22 Commits

Author SHA1 Message Date
3546dbd75b some broken dialogs fixed 2017-05-08 23:58:23 +03:00
b081bff2ce some mainscreen widgets fixes 2017-04-16 22:56:31 +03:00
e257d8f96f signals && imports fixes 2017-04-13 19:22:46 +03:00
972a073cb9 missed translations fix, travis fix, updates 2017-04-11 21:38:00 +03:00
e4998cd5b5 pyqt5 initial commit 2017-04-11 21:10:03 +03:00
19fb905554 some fixes 2017-04-06 21:28:34 +03:00
3ef581bc5d some messages improvements 2017-04-05 23:46:32 +03:00
f897c7ce8d unlock screen crash fixed 2017-03-27 00:04:32 +03:00
ba390eda91 message splitting bug fix 2017-03-26 18:28:30 +03:00
5fea3e918d plugin reloading refactoring 2017-03-25 18:21:25 +03:00
7cc404ce52 plugins improvements 2017-03-15 23:17:38 +03:00
8a502b4082 block user option in friend menu and translations update 2017-03-08 13:37:19 +03:00
b83ea6be18 reconnection bug fix 2017-03-08 13:19:41 +03:00
85554eacd1 docs updates 2017-03-04 23:35:46 +03:00
8bbefff6c7 history - travis tests fix 2017-03-04 23:18:26 +03:00
019165aeac unsent files fix 2017-03-04 22:15:42 +03:00
0cfb8efefa reconnection fixes 2017-03-03 22:09:45 +03:00
b227ed627a more tests 2017-02-27 21:44:35 +03:00
f41b5e5c97 history test 2017-02-25 23:53:33 +03:00
bc9ec04171 version number fix 2017-02-20 23:47:55 +03:00
05e4184c5d travis fix 2017-02-20 22:03:35 +03:00
3194099f59 default config file moved to app dir 2017-02-20 21:33:04 +03:00
40 changed files with 1146 additions and 1139 deletions

View File

@ -1,13 +1,14 @@
language: python
python:
- "3.4"
- "3.5"
- "3.6"
before_install:
- sudo apt-get update
- sudo apt-get install -y checkinstall build-essential
- sudo apt-get install portaudio19-dev
- sudo apt-get install libconfig-dev libvpx-dev check -qq
- sudo apt-get install -y python3-pyqt5
install:
- pip install PySide --no-index --find-links https://parkin.github.io/python-wheelhouse/;
- python ~/virtualenv/python${TRAVIS_PYTHON_VERSION}/bin/pyside_postinstall.py -install
- pip install pyaudio
before_script:
# OPUS

View File

@ -2,13 +2,13 @@
Toxygen is powerful cross-platform [Tox](https://tox.chat/) client written in pure Python3.
[![Release](https://img.shields.io/github/release/xveduk/toxygen.svg?style=flat)](https://github.com/toxygen-project/toxygen/releases/latest)
[![Stars](https://img.shields.io/github/stars/xveduk/toxygen.svg?style=flat)](https://github.com/toxygen-project/toxygen/stargazers)
[![Open issues](https://img.shields.io/github/issues/xveduk/toxygen.svg?style=flat)](https://github.com/toxygen-project/toxygen/issues)
[![Release](https://img.shields.io/github/release/toxygen-project/toxygen.svg?style=flat)](https://github.com/toxygen-project/toxygen/releases/latest)
[![Stars](https://img.shields.io/github/stars/toxygen-project/toxygen.svg?style=flat)](https://github.com/toxygen-project/toxygen/stargazers)
[![Open issues](https://img.shields.io/github/issues/toxygen-project/toxygen.svg?style=flat)](https://github.com/toxygen-project/toxygen/issues)
[![License](https://img.shields.io/badge/license-GPLv3-blue.svg?style=flat)](https://raw.githubusercontent.com/toxygen-project/toxygen/master/LICENSE.md)
[![Build Status](https://travis-ci.org/toxygen-project/toxygen.svg?branch=master)](https://travis-ci.org/toxygen-project/toxygen)
### [Install](/docs/install.md) - [Contribute](/docs/contributing.md) - [Plugins](/docs/plugins.md) - [Compile](/docs/compile.md) - [Contact](/docs/contact.md)
### [Install](/docs/install.md) - [Contribute](/docs/contributing.md) - [Plugins](/docs/plugins.md) - [Compile](/docs/compile.md) - [Contact](/docs/contact.md) - [Updater](https://github.com/toxygen-project/toxygen_updater)
### Supported OS:
@ -18,7 +18,7 @@ Toxygen is powerful cross-platform [Tox](https://tox.chat/) client written in pu
- [x] 1v1 messages
- [x] File transfers
- [x] Audio
- [x] Audio calls
- [x] Plugins support
- [x] Chat history
- [x] Emoticons
@ -42,7 +42,7 @@ Toxygen is powerful cross-platform [Tox](https://tox.chat/) client written in pu
- [x] Changing nospam
- [x] File resuming
- [x] Read receipts
- [ ] Video
- [ ] Video calls
- [ ] Desktop sharing
- [ ] Group chats

View File

@ -5,6 +5,7 @@ You can compile Toxygen using [PyInstaller](http://www.pyinstaller.org/)
Install PyInstaller:
``pip3 install pyinstaller``
Compile Toxygen:
``pyinstaller --windowed --icon images/icon.ico main.py``
Don't forget to copy /images/, /sounds/, /translations/, /styles/, /smileys/, /stickers/, /plugins/ (and /libs/libtox.dll, /libs/libsodium.a on Windows) to /dist/main/

View File

@ -4,15 +4,15 @@ Help us find all bugs in Toxygen! Please provide following info:
- OS
- Toxygen version
- Toxygen executable info - .py or precompiled binary
- Toxygen executable info - .py or precompiled binary, how was it installed in system
- Steps to reproduce the bug
Want to see new feature in Toxygen? [Ask for it!](https://github.com/xveduk/toxygen/issues)
Want to see new feature in Toxygen? [Ask for it!](https://github.com/toxygen-project/toxygen/issues)
#Pull requests
Developer? Feel free to open pull request. Our dev team is small so we glad to get help.
Don't know what to do? Improve UI, fix [issues](https://github.com/xveduk/toxygen/issues) or implement features from our TODO list.
Developer? Feel free to open pull request. Our dev team is small so we glad to get help.
Don't know what to do? Improve UI, fix [issues](https://github.com/toxygen-project/toxygen/issues) or implement features from our TODO list.
You can find our TODO's in code, issues list and [here](/README.md). Also you can implement [plugins](/docs/plugins.md) for Toxygen.
#Translations

View File

@ -1,7 +1,7 @@
# How to install Toxygen
## Use precompiled binary:
[Check our releases page](https://github.com/xveduk/toxygen/releases)
[Check our releases page](https://github.com/toxygen-project/toxygen/releases)
## Using pip3

View File

@ -1,4 +1,4 @@
#Plugins API
# Plugins API
In Toxygen plugin is single python (supported Python 3.0 - 3.4) module (.py file) and directory with data associated with it.
Every module must contain one class derived from PluginSuperClass defined in [plugin_super_class.py](/src/plugins/plugin_super_class.py). Instance of this class will be created by PluginLoader class (defined in [plugin_support.py](/src/plugin_support.py) ). This class can enable/disable plugins and send data to it.
@ -18,7 +18,7 @@ All plugin's data should be stored in following structure:
```
Plugin MUST override:
- __init__ with params: tox (Tox instance), profile (Profile instance), settings (Settings instance), encrypt_save (ToxEncryptSave instance). Call super().__init__ with params plugin_full_name, plugin_short_name, tox, profile, settings, encrypt_save.
- __init__ with params: tox (Tox instance), profile (Profile instance), settings (Settings instance), encrypt_save (ToxES instance). Call super().__init__ with params plugin_full_name, plugin_short_name, tox, profile, settings, encrypt_save.
Plugin can override following methods:
- get_description - this method should return plugin description.
@ -51,7 +51,7 @@ Exceptions:
Plugin's methods MUST NOT raise exceptions.
#Examples
# Examples
You can find examples in [official repo](https://github.com/ingvar1995/toxygen_plugins)
You can find examples in [official repo](https://github.com/toxygen-project/toxygen_plugins)

View File

@ -1,22 +1,22 @@
#Plugins
# Plugins
Toxygen is the first [Tox](https://tox.chat/) client with plugins support. Plugin is Python 3.4 module (.py file) and directory with plugin's data which provide some additional functionality.
#How to write plugin
# How to write plugin
Check [Plugin API](/docs/plugin_api.md) for more info
#How to install plugin
# How to install plugin
Toxygen comes without preinstalled plugins.
1. Put plugin and directory with its data into /src/plugins/ or import it via GUI (In menu: Plugins -> Import plugin)
2. Restart Toxygen
1. Put plugin and directory with its data into /src/plugins/ or import it via GUI (In menu: Plugins => Import plugin)
2. Restart Toxygen or choose Plugins => Reload plugins in menu.
##Note: /src/plugins/ should contain plugin_super_class.py and __init__.py
## Note: /src/plugins/ should contain plugin_super_class.py and __init__.py
#Plugins list
# Plugins list
WARNING: It is unsecure to install plugin not from this list!
[Main repo](https://github.com/ingvar1995/toxygen_plugins)
[Main repo](https://github.com/toxygen-project/toxygen_plugins)

View File

@ -10,4 +10,4 @@ Animated smileys (.gif) are supported too.
Sticker is inline image. If you want to create your own smiley pack, create directory in src/stickers/ and place your stickers there.
Users can import plugins and stickers packs using menu: Settings -> Interface
Users can import smileys and stickers using menu: Settings -> Interface

View File

@ -11,7 +11,7 @@ version = program_version + '.0'
MODULES = []
if system() in ('Windows', 'Darwin'):
MODULES = ['PyAudio', 'PySide']
MODULES = ['PyAudio', 'PyQt5']
else:
try:
import pyaudio
@ -58,7 +58,8 @@ setup(name='Toxygen',
include_package_data=True,
classifiers=[
'Programming Language :: Python :: 3 :: Only',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
],
entry_points={
'console_scripts': ['toxygen=toxygen.main:main'],

View File

@ -1,7 +1,10 @@
from toxygen.profile import *
from toxygen.tox_dns import tox_dns
from toxygen.history import History
from toxygen.smileys import SmileyLoader
from toxygen.messages import *
import toxygen.toxes as encr
import toxygen.messages as m
import toxygen.util as util
import time
@ -58,56 +61,117 @@ class TestEncryption:
lib.set_password(password)
copy_data = data[:]
new_data = lib.pass_encrypt(data)
assert lib.is_data_encrypted(new_data)
new_data = lib.pass_decrypt(new_data)
assert copy_data == new_data
class TestSmileys:
def test_loading(self):
settings = {'smiley_pack': 'default', 'smileys': True}
sm = SmileyLoader(settings)
assert sm.get_smileys_path() is not None
l = sm.get_packs_list()
assert len(l) == 4
def create_singletons():
folder = util.curr_directory() + '/abc'
Settings._instance = Settings.get_default_settings()
if not os.path.exists(folder):
os.makedirs(folder)
ProfileHelper(folder, 'test')
def create_friend(name, status_message, number, tox_id):
friend = Friend(None, number, name, status_message, None, tox_id)
return friend
def create_random_friend():
name, status_message, number = 'Friend', 'I am friend!', 0
tox_id = '76518406F6A9F2217E8DC487CC783C25CC16A15EB36FF32E335A235342C48A39218F515C39A6'
friend = create_friend(name, status_message, number, tox_id)
return friend
class TestFriend:
def create_singletons(self):
Settings._instance = Settings.get_default_settings()
ProfileHelper('abc', 'test')
def create_friend(self, name, status_message, number, tox_id):
friend = Friend(None, number, name, status_message, None, tox_id)
return friend
def test_friend_creation(self):
self.create_singletons()
create_singletons()
name, status_message, number = 'Friend', 'I am friend!', 0
tox_id = '76518406F6A9F2217E8DC487CC783C25CC16A15EB36FF32E335A235342C48A39218F515C39A6'
friend = self.create_friend(name, status_message, number, tox_id)
friend = create_friend(name, status_message, number, tox_id)
assert friend.name == name
assert friend.tox_id == tox_id
assert friend.status_message == status_message
assert friend.number == number
def test_friend_corr(self):
self.create_singletons()
name, status_message, number = 'Friend', 'I am friend!', 0
tox_id = '76518406F6A9F2217E8DC487CC783C25CC16A15EB36FF32E335A235342C48A39218F515C39A6'
friend = self.create_friend(name, status_message, number, tox_id)
create_singletons()
friend = create_random_friend()
t = time.time()
friend.append_message(m.InfoMessage('Info message', t))
friend.append_message(m.TextMessage('Hello! It is test!', MESSAGE_OWNER['ME'], t + 0.001, 0))
friend.append_message(m.TextMessage('Hello!', MESSAGE_OWNER['FRIEND'], t + 0.002, 0))
friend.append_message(InfoMessage('Info message', t))
friend.append_message(TextMessage('Hello! It is test!', MESSAGE_OWNER['ME'], t + 0.001, 0))
friend.append_message(TextMessage('Hello!', MESSAGE_OWNER['FRIEND'], t + 0.002, 0))
assert friend.get_last_message_text() == 'Hello! It is test!'
assert len(friend.get_corr()) == 3
assert len(friend.get_corr_for_saving()) == 2
friend.append_message(m.TextMessage('Not sent', MESSAGE_OWNER['NOT_SENT'], t + 0.002, 0))
friend.append_message(TextMessage('Not sent', MESSAGE_OWNER['NOT_SENT'], t + 0.002, 0))
arr = friend.get_unsent_messages_for_saving()
assert len(arr) == 1
assert arr[0][0] == 'Not sent'
tm = m.TransferMessage(MESSAGE_OWNER['FRIEND'],
time.time(),
TOX_FILE_TRANSFER_STATE['RUNNING'],
100, 'file_name', friend.number, 0)
tm = TransferMessage(MESSAGE_OWNER['FRIEND'],
time.time(),
TOX_FILE_TRANSFER_STATE['RUNNING'],
100, 'file_name', friend.number, 0)
friend.append_message(tm)
friend.clear_corr()
assert len(friend.get_corr()) == 1
assert len(friend.get_corr_for_saving()) == 0
friend.append_message(m.TextMessage('Hello! It is test!', MESSAGE_OWNER['ME'], t, 0))
friend.append_message(TextMessage('Hello! It is test!', MESSAGE_OWNER['ME'], t, 0))
assert len(friend.get_corr()) == 2
assert len(friend.get_corr_for_saving()) == 1
# TODO: more friend tests and history test
def test_history_search(self):
create_singletons()
friend = create_random_friend()
message = 'Hello! It is test!'
friend.append_message(TextMessage(message, MESSAGE_OWNER['ME'], time.time(), 0))
last_message = friend.get_last_message_text()
assert last_message == message
result = friend.search_string('e[m|s]')
assert result is not None
result = friend.search_string('tox')
assert result is None
class TestHistory:
def test_history(self):
create_singletons()
db_name = 'my_name'
name, status_message, number = 'Friend', 'I am friend!', 0
tox_id = '76518406F6A9F2217E8DC487CC783C25CC16A15EB36FF32E335A235342C48A39218F515C39A6'
friend = create_friend(name, status_message, number, tox_id)
history = History(db_name)
history.add_friend_to_db(friend.tox_id)
assert history.friend_exists_in_db(friend.tox_id)
text_message = 'Test!'
t = time.time()
friend.append_message(TextMessage(text_message, MESSAGE_OWNER['ME'], t, 0))
messages = friend.get_corr_for_saving()
history.save_messages_to_db(friend.tox_id, messages)
getter = history.messages_getter(friend.tox_id)
messages = getter.get_all()
assert len(messages) == 1
assert messages[0][0] == text_message
assert messages[0][1] == MESSAGE_OWNER['ME']
assert messages[0][-1] == 0
history.delete_message(friend.tox_id, t)
getter = history.messages_getter(friend.tox_id)
messages = getter.get_all()
assert len(messages) == 0
history.delete_friend_from_db(friend.tox_id)
assert not history.friend_exists_in_db(friend.tox_id)

View File

@ -1,7 +1,4 @@
try:
from PySide import QtCore, QtGui
except ImportError:
from PyQt4 import QtCore, QtGui
from PyQt5 import QtCore, QtGui, QtWidgets
import widgets
import profile
import util
@ -17,7 +14,7 @@ class IncomingCallWidget(widgets.CenteredWidget):
super(IncomingCallWidget, self).__init__()
self.setWindowFlags(QtCore.Qt.CustomizeWindowHint | QtCore.Qt.WindowTitleHint | QtCore.Qt.WindowStaysOnTopHint)
self.resize(QtCore.QSize(500, 270))
self.avatar_label = QtGui.QLabel(self)
self.avatar_label = QtWidgets.QLabel(self)
self.avatar_label.setGeometry(QtCore.QRect(10, 20, 64, 64))
self.avatar_label.setScaledContents(False)
self.name = widgets.DataLabel(self)
@ -30,11 +27,11 @@ class IncomingCallWidget(widgets.CenteredWidget):
self.call_type = widgets.DataLabel(self)
self.call_type.setGeometry(QtCore.QRect(90, 55, 300, 25))
self.call_type.setFont(font)
self.accept_audio = QtGui.QPushButton(self)
self.accept_audio = QtWidgets.QPushButton(self)
self.accept_audio.setGeometry(QtCore.QRect(20, 100, 150, 150))
self.accept_video = QtGui.QPushButton(self)
self.accept_video = QtWidgets.QPushButton(self)
self.accept_video.setGeometry(QtCore.QRect(170, 100, 150, 150))
self.decline = QtGui.QPushButton(self)
self.decline = QtWidgets.QPushButton(self)
self.decline.setGeometry(QtCore.QRect(320, 100, 150, 150))
pixmap = QtGui.QPixmap(util.curr_directory() + '/images/accept_audio.png')
icon = QtGui.QIcon(pixmap)
@ -63,6 +60,7 @@ class IncomingCallWidget(widgets.CenteredWidget):
def __init__(self):
QtCore.QThread.__init__(self)
self.a = None
def run(self):
class AudioFile:
@ -115,15 +113,14 @@ class AudioMessageRecorder(widgets.CenteredWidget):
def __init__(self, friend_number, name):
super(AudioMessageRecorder, self).__init__()
self.label = QtGui.QLabel(self)
self.label = QtWidgets.QLabel(self)
self.label.setGeometry(QtCore.QRect(10, 20, 250, 20))
text = QtGui.QApplication.translate("MenuWindow", "Send audio message to friend {}", None, QtGui.QApplication.UnicodeUTF8)
text = QtWidgets.QApplication.translate("MenuWindow", "Send audio message to friend {}")
self.label.setText(text.format(name))
self.record = QtGui.QPushButton(self)
self.record = QtWidgets.QPushButton(self)
self.record.setGeometry(QtCore.QRect(20, 100, 150, 150))
self.record.setText(QtGui.QApplication.translate("MenuWindow", "Start recording", None,
QtGui.QApplication.UnicodeUTF8))
self.record.setText(QtWidgets.QApplication.translate("MenuWindow", "Start recording"))
self.record.clicked.connect(self.start_or_stop_recording)
self.recording = False
self.friend_num = friend_number
@ -131,8 +128,7 @@ class AudioMessageRecorder(widgets.CenteredWidget):
def start_or_stop_recording(self):
if not self.recording:
self.recording = True
self.record.setText(QtGui.QApplication.translate("MenuWindow", "Stop recording", None,
QtGui.QApplication.UnicodeUTF8))
self.record.setText(QtWidgets.QApplication.translate("MenuWindow", "Stop recording"))
else:
self.close()

View File

@ -1,8 +1,5 @@
from settings import *
try:
from PySide import QtCore, QtGui
except ImportError:
from PyQt4 import QtCore, QtGui
from PyQt5 import QtCore, QtGui
from toxcore_enums_and_consts import TOX_PUBLIC_KEY_SIZE
@ -109,6 +106,10 @@ class BaseContact:
def get_pixmap(self):
return self._widget.avatar_label.pixmap()
# -----------------------------------------------------------------------------------------------------------------
# Widgets
# -----------------------------------------------------------------------------------------------------------------
def init_widget(self):
if self._widget is not None:
self._widget.name.setText(self._name)

View File

@ -1,7 +1,4 @@
try:
from PySide import QtCore
except ImportError:
from PyQt4 import QtCore
from PyQt5 import QtCore, QtGui, QtWidgets
from notifications import *
from settings import Settings
from profile import Profile
@ -225,7 +222,7 @@ def tox_file_recv(window, tray):
if not window.isActiveWindow():
friend = profile.get_friend_by_number(friend_number)
if settings['notifications'] and profile.status != TOX_USER_STATUS['BUSY'] and not settings.locked:
file_from = QtGui.QApplication.translate("Callback", "File from", None, QtGui.QApplication.UnicodeUTF8)
file_from = QtWidgets.QApplication.translate("Callback", "File from")
invoke_in_main_thread(tray_notification, file_from + ' ' + friend.name, file_name, tray, window)
if settings['sound_notifications'] and profile.status != TOX_USER_STATUS['BUSY']:
sound_notification(SOUND_NOTIFICATION['FILE_TRANSFER'])

View File

@ -1,7 +1,4 @@
try:
from PySide import QtCore, QtGui
except ImportError:
from PyQt4 import QtCore, QtGui
from PyQt5 import QtCore, QtGui
from history import *
import basecontact
import util
@ -30,7 +27,6 @@ class Contact(basecontact.BaseContact):
self._corr = []
self._unsaved_messages = 0
self._history_loaded = self._new_actions = False
self._receipts = 0
self._curr_text = self._search_string = ''
self._search_index = 0
@ -50,6 +46,8 @@ class Contact(basecontact.BaseContact):
"""
if (first_time and self._history_loaded) or (not hasattr(self, '_message_getter')):
return
if self._message_getter is None:
return
data = list(self._message_getter.get(PAGE_SIZE))
if data is not None and len(data):
data.reverse()
@ -138,12 +136,15 @@ class Contact(basecontact.BaseContact):
"""
Delete old messages (reduces RAM usage if messages saving is not enabled)
"""
old = filter(lambda x: x.get_type() == 2 and (x.get_status() >= 2 or x.get_status() is None),
self._corr[:-SAVE_MESSAGES])
old = list(old)
l = max(len(self._corr) - SAVE_MESSAGES, 0) - len(old)
self._unsaved_messages -= l
self._corr = old + self._corr[-SAVE_MESSAGES:]
def save_message(x):
if x.get_type() == 2 and (x.get_status() >= 2 or x.get_status() is None):
return True
return x.get_owner() == MESSAGE_OWNER['NOT_SENT']
old = filter(save_message, self._corr[:-SAVE_MESSAGES])
self._corr = list(old) + self._corr[-SAVE_MESSAGES:]
text_messages = filter(lambda x: x.get_type() <= 1, self._corr)
self._unsaved_messages = min(self._unsaved_messages, len(list(text_messages)))
self._search_index = 0
def clear_corr(self, save_unsent=False):
@ -176,7 +177,7 @@ class Contact(basecontact.BaseContact):
while True:
l = len(self._corr)
for i in range(self._search_index - 1, -l - 1, -1):
if type(self._corr[i]) is not TextMessage:
if self._corr[i].get_type() > 1:
continue
message = self._corr[i].get_data()[0]
if re.search(self._search_string, message, re.IGNORECASE) is not None:
@ -191,7 +192,7 @@ class Contact(basecontact.BaseContact):
if not self._search_index:
return None
for i in range(self._search_index + 1, 0):
if type(self._corr[i]) is not TextMessage:
if self._corr[i].get_type() > 1:
continue
message = self._corr[i].get_data()[0]
if re.search(self._search_string, message, re.IGNORECASE) is not None:

View File

@ -4,11 +4,7 @@ from os import remove, rename, chdir
from time import time, sleep
from tox import Tox
import settings
try:
from PySide import QtCore
except ImportError:
from PyQt4 import QtCore
QtCore.Signal = QtCore.pyqtSignal
from PyQt5 import QtCore
TOX_FILE_TRANSFER_STATE = {
@ -38,12 +34,12 @@ def is_inline(file_name):
class StateSignal(QtCore.QObject):
signal = QtCore.Signal(int, float, int) # state, progress, time in sec
signal = QtCore.pyqtSignal(int, float, int) # state, progress, time in sec
class TransferFinishedSignal(QtCore.QObject):
signal = QtCore.Signal(int, int) # friend number, file number
signal = QtCore.pyqtSignal(int, int) # friend number, file number
class FileTransfer(QtCore.QObject):

View File

@ -1,5 +1,6 @@
import contact
from messages import *
import os
class Friend(contact.Contact):
@ -37,6 +38,15 @@ class Friend(contact.Contact):
def clear_unsent_files(self):
self._corr = list(filter(lambda x: type(x) is not UnsentFile, self._corr))
def remove_invalid_unsent_files(self):
def is_valid(message):
if type(message) is not UnsentFile:
return True
if message.get_data()[1] is not None:
return True
return os.path.exists(message.get_data()[0])
self._corr = list(filter(is_valid, self._corr))
def delete_one_unsent_file(self, time):
self._corr = list(filter(lambda x: not (type(x) is UnsentFile and x.get_data()[2] == time), self._corr))

View File

@ -9,7 +9,7 @@ PAGE_SIZE = 42
TIMEOUT = 11
SAVE_MESSAGES = 150
SAVE_MESSAGES = 250
MESSAGE_OWNER = {
'ME': 0,
@ -133,14 +133,15 @@ class History:
db.rollback()
finally:
db.close()
pass
def delete_message(self, tox_id, time):
start, end = str(time - 0.01), str(time + 0.01)
chdir(settings.ProfileHelper.get_path())
db = connect(self._name + '.hstr', timeout=TIMEOUT)
try:
cursor = db.cursor()
cursor.execute('DELETE FROM id' + tox_id + ' WHERE unix_time = ' + str(time) + ';')
cursor.execute('DELETE FROM id' + tox_id + ' WHERE unix_time < ' + end + ' AND unix_time > ' +
start + ';')
db.commit()
except:
print('Database is locked!')

View File

@ -1,7 +1,4 @@
try:
from PySide import QtCore, QtGui
except ImportError:
from PyQt4 import QtCore, QtGui
from PyQt5 import QtWidgets, QtCore
from list_items import *
@ -13,7 +10,7 @@ class ItemsFactory:
def friend_item(self):
item = ContactItem()
elem = QtGui.QListWidgetItem(self._friends)
elem = QtWidgets.QListWidgetItem(self._friends)
elem.setSizeHint(QtCore.QSize(250, item.height()))
self._friends.addItem(elem)
self._friends.setItemWidget(elem, item)
@ -23,7 +20,7 @@ class ItemsFactory:
item = MessageItem(text, time, name, sent, message_type, self._messages)
if pixmap is not None:
item.set_avatar(pixmap)
elem = QtGui.QListWidgetItem()
elem = QtWidgets.QListWidgetItem()
elem.setSizeHint(QtCore.QSize(self._messages.width(), item.height()))
if append:
self._messages.addItem(elem)
@ -33,7 +30,7 @@ class ItemsFactory:
return item
def inline_item(self, data, append):
elem = QtGui.QListWidgetItem()
elem = QtWidgets.QListWidgetItem()
item = InlineImageItem(data, self._messages.width(), elem)
elem.setSizeHint(QtCore.QSize(self._messages.width(), item.height()))
if append:
@ -49,7 +46,7 @@ class ItemsFactory:
name,
time,
self._messages.width())
elem = QtGui.QListWidgetItem()
elem = QtWidgets.QListWidgetItem()
elem.setSizeHint(QtCore.QSize(self._messages.width() - 30, 34))
if append:
self._messages.addItem(elem)
@ -61,7 +58,7 @@ class ItemsFactory:
def file_transfer_item(self, data, append):
data.append(self._messages.width())
item = FileTransferItem(*data)
elem = QtGui.QListWidgetItem()
elem = QtWidgets.QListWidgetItem()
elem.setSizeHint(QtCore.QSize(self._messages.width() - 30, 34))
if append:
self._messages.addItem(elem)

View File

@ -1,9 +1,5 @@
from toxcore_enums_and_consts import *
try:
from PySide import QtCore, QtGui
except ImportError:
from PyQt4 import QtCore, QtGui
QtCore.Slot = QtCore.pyqtSlot
from PyQt5 import QtCore, QtGui, QtWidgets
import profile
from file_transfers import TOX_FILE_TRANSFER_STATE, PAUSED_FILE_TRANSFERS, DO_NOT_SHOW_ACCEPT_BUTTON, ACTIVE_FILE_TRANSFERS, SHOW_PROGRESS_BAR
from util import curr_directory, convert_time, curr_time
@ -14,7 +10,7 @@ import settings
import re
class MessageEdit(QtGui.QTextBrowser):
class MessageEdit(QtWidgets.QTextBrowser):
def __init__(self, text, width, message_type, parent=None):
super(MessageEdit, self).__init__(parent)
@ -46,7 +42,7 @@ class MessageEdit(QtGui.QTextBrowser):
def contextMenuEvent(self, event):
menu = create_menu(self.createStandardContextMenu(event.pos()))
quote = menu.addAction(QtGui.QApplication.translate("MainWindow", 'Quote selected text', None, QtGui.QApplication.UnicodeUTF8))
quote = menu.addAction(QtWidgets.QApplication.translate("MainWindow", 'Quote selected text'))
quote.triggered.connect(self.quote_text)
text = self.textCursor().selection().toPlainText()
if not text:
@ -55,7 +51,7 @@ class MessageEdit(QtGui.QTextBrowser):
import plugin_support
submenu = plugin_support.PluginLoader.get_instance().get_message_menu(menu, text)
if len(submenu):
plug = menu.addMenu(QtGui.QApplication.translate("MainWindow", 'Plugins', None, QtGui.QApplication.UnicodeUTF8))
plug = menu.addMenu(QtWidgets.QApplication.translate("MainWindow", 'Plugins'))
plug.addActions(submenu)
menu.popup(event.globalPos())
menu.exec_(event.globalPos())
@ -123,12 +119,12 @@ class MessageEdit(QtGui.QTextBrowser):
return text
class MessageItem(QtGui.QWidget):
class MessageItem(QtWidgets.QWidget):
"""
Message in messages list
"""
def __init__(self, text, time, user='', sent=True, message_type=TOX_MESSAGE_TYPE['NORMAL'], parent=None):
QtGui.QWidget.__init__(self, parent)
QtWidgets.QWidget.__init__(self, parent)
self.name = DataLabel(self)
self.name.setGeometry(QtCore.QRect(2, 2, 95, 23))
self.name.setTextFormat(QtCore.Qt.PlainText)
@ -139,7 +135,7 @@ class MessageItem(QtGui.QWidget):
self.name.setFont(font)
self.name.setText(user)
self.time = QtGui.QLabel(self)
self.time = QtWidgets.QLabel(self)
self.time.setGeometry(QtCore.QRect(parent.width() - 60, 0, 50, 25))
font.setPointSize(10)
font.setBold(False)
@ -164,9 +160,9 @@ class MessageItem(QtGui.QWidget):
def mouseReleaseEvent(self, event):
if event.button() == QtCore.Qt.RightButton and event.x() > self.time.x():
self.listMenu = QtGui.QMenu()
delete_item = self.listMenu.addAction(QtGui.QApplication.translate("MainWindow", 'Delete message', None, QtGui.QApplication.UnicodeUTF8))
self.connect(delete_item, QtCore.SIGNAL("triggered()"), self.delete)
self.listMenu = QtWidgets.QMenu()
delete_item = self.listMenu.addAction(QtWidgets.QApplication.translate("MainWindow", 'Delete message'))
delete_item.triggered.connect(self.delete)
parent_position = self.time.mapToGlobal(QtCore.QPoint(0, 0))
self.listMenu.move(parent_position)
self.listMenu.show()
@ -216,16 +212,16 @@ class MessageItem(QtGui.QWidget):
return text
class ContactItem(QtGui.QWidget):
class ContactItem(QtWidgets.QWidget):
"""
Contact in friends list
"""
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
QtWidgets.QWidget.__init__(self, parent)
mode = settings.Settings.get_instance()['compact_mode']
self.setBaseSize(QtCore.QSize(250, 40 if mode else 70))
self.avatar_label = QtGui.QLabel(self)
self.avatar_label = QtWidgets.QLabel(self)
size = 32 if mode else 64
self.avatar_label.setGeometry(QtCore.QRect(3, 4, size, size))
self.avatar_label.setScaledContents(False)
@ -248,14 +244,14 @@ class ContactItem(QtGui.QWidget):
self.messages.setGeometry(QtCore.QRect(20 if mode else 52, 20 if mode else 50, 30, 20))
class StatusCircle(QtGui.QWidget):
class StatusCircle(QtWidgets.QWidget):
"""
Connection status
"""
def __init__(self, parent):
QtGui.QWidget.__init__(self, parent)
QtWidgets.QWidget.__init__(self, parent)
self.setGeometry(0, 0, 32, 32)
self.label = QtGui.QLabel(self)
self.label = QtWidgets.QLabel(self)
self.label.setGeometry(QtCore.QRect(0, 0, 32, 32))
self.unread = False
@ -281,12 +277,12 @@ class StatusCircle(QtGui.QWidget):
self.label.setPixmap(pixmap)
class UnreadMessagesCount(QtGui.QWidget):
class UnreadMessagesCount(QtWidgets.QWidget):
def __init__(self, parent=None):
super(UnreadMessagesCount, self).__init__(parent)
self.resize(30, 20)
self.label = QtGui.QLabel(self)
self.label = QtWidgets.QLabel(self)
self.label.setGeometry(QtCore.QRect(0, 0, 30, 20))
self.label.setVisible(False)
font = QtGui.QFont()
@ -308,11 +304,11 @@ class UnreadMessagesCount(QtGui.QWidget):
self.label.setVisible(False)
class FileTransferItem(QtGui.QListWidget):
class FileTransferItem(QtWidgets.QListWidget):
def __init__(self, file_name, size, time, user, friend_number, file_number, state, width, parent=None):
QtGui.QListWidget.__init__(self, parent)
QtWidgets.QListWidget.__init__(self, parent)
self.resize(QtCore.QSize(width, 34))
if state == TOX_FILE_TRANSFER_STATE['CANCELLED']:
self.setStyleSheet('QListWidget { border: 1px solid #B40404; }')
@ -332,14 +328,14 @@ class FileTransferItem(QtGui.QListWidget):
self.name.setFont(font)
self.name.setText(user)
self.time = QtGui.QLabel(self)
self.time = QtWidgets.QLabel(self)
self.time.setGeometry(QtCore.QRect(width - 60, 7, 50, 25))
font.setPointSize(10)
font.setBold(False)
self.time.setFont(font)
self.time.setText(convert_time(time))
self.cancel = QtGui.QPushButton(self)
self.cancel = QtWidgets.QPushButton(self)
self.cancel.setGeometry(QtCore.QRect(width - 125, 2, 30, 30))
pixmap = QtGui.QPixmap(curr_directory() + '/images/decline.png')
icon = QtGui.QIcon(pixmap)
@ -349,7 +345,7 @@ class FileTransferItem(QtGui.QListWidget):
self.cancel.clicked.connect(lambda: self.cancel_transfer(friend_number, file_number))
self.cancel.setStyleSheet('QPushButton:hover { border: 1px solid #3A3939; background-color: none;}')
self.accept_or_pause = QtGui.QPushButton(self)
self.accept_or_pause = QtWidgets.QPushButton(self)
self.accept_or_pause.setGeometry(QtCore.QRect(width - 170, 2, 30, 30))
if state == TOX_FILE_TRANSFER_STATE['INCOMING_NOT_STARTED']:
self.accept_or_pause.setVisible(True)
@ -366,7 +362,7 @@ class FileTransferItem(QtGui.QListWidget):
self.accept_or_pause.setStyleSheet('QPushButton:hover { border: 1px solid #3A3939; background-color: none}')
self.pb = QtGui.QProgressBar(self)
self.pb = QtWidgets.QProgressBar(self)
self.pb.setGeometry(QtCore.QRect(100, 7, 100, 20))
self.pb.setValue(0)
self.pb.setStyleSheet('QProgressBar { background-color: #302F2F; }')
@ -387,7 +383,7 @@ class FileTransferItem(QtGui.QListWidget):
self.file_name.setText(file_data)
self.file_name.setToolTip(file_name)
self.saved_name = file_name
self.time_left = QtGui.QLabel(self)
self.time_left = QtWidgets.QLabel(self)
self.time_left.setGeometry(QtCore.QRect(width - 92, 7, 30, 20))
font.setPointSize(10)
self.time_left.setFont(font)
@ -405,10 +401,10 @@ class FileTransferItem(QtGui.QListWidget):
def accept_or_pause_transfer(self, friend_number, file_number, size):
if self.state == TOX_FILE_TRANSFER_STATE['INCOMING_NOT_STARTED']:
directory = QtGui.QFileDialog.getExistingDirectory(self,
QtGui.QApplication.translate("MainWindow", 'Choose folder', None, QtGui.QApplication.UnicodeUTF8),
directory = QtWidgets.QFileDialog.getExistingDirectory(self,
QtWidgets.QApplication.translate("MainWindow", 'Choose folder'),
curr_directory(),
QtGui.QFileDialog.ShowDirsOnly | QtGui.QFileDialog.DontUseNativeDialog)
QtWidgets.QFileDialog.ShowDirsOnly | QtWidgets.QFileDialog.DontUseNativeDialog)
self.pb.setVisible(True)
if directory:
pr = profile.Profile.get_instance()
@ -432,8 +428,7 @@ class FileTransferItem(QtGui.QListWidget):
self.accept_or_pause.setIcon(icon)
self.accept_or_pause.setIconSize(QtCore.QSize(30, 30))
@QtCore.Slot(int, float, int)
def update(self, state, progress, time):
def update_transfer_state(self, state, progress, time):
self.pb.setValue(int(progress * 100))
if time + 1:
m, s = divmod(time, 60)
@ -496,14 +491,14 @@ class UnsentFileItem(FileTransferItem):
pr.cancel_not_started_transfer(self._time)
class InlineImageItem(QtGui.QScrollArea):
class InlineImageItem(QtWidgets.QScrollArea):
def __init__(self, data, width, elem):
QtGui.QScrollArea.__init__(self)
QtWidgets.QScrollArea.__init__(self)
self.setFocusPolicy(QtCore.Qt.NoFocus)
self._elem = elem
self._image_label = QtGui.QLabel(self)
self._image_label = QtWidgets.QLabel(self)
self._image_label.raise_()
self.setWidget(self._image_label)
self._image_label.setScaledContents(False)
@ -537,12 +532,11 @@ class InlineImageItem(QtGui.QScrollArea):
self._full_size = not self._full_size
self._elem.setSizeHint(QtCore.QSize(self.width(), self.height()))
elif event.button() == QtCore.Qt.RightButton: # save inline
directory = QtGui.QFileDialog.getExistingDirectory(self,
QtGui.QApplication.translate("MainWindow",
'Choose folder', None,
QtGui.QApplication.UnicodeUTF8),
directory = QtWidgets.QFileDialog.getExistingDirectory(self,
QtWidgets.QApplication.translate("MainWindow",
'Choose folder'),
curr_directory(),
QtGui.QFileDialog.ShowDirsOnly | QtGui.QFileDialog.DontUseNativeDialog)
QtWidgets.QFileDialog.ShowDirsOnly | QtWidgets.QFileDialog.DontUseNativeDialog)
if directory:
fl = QtCore.QFile(directory + '/toxygen_inline_' + curr_time().replace(':', '_') + '.png')
self._pixmap.save(fl, 'PNG')

View File

@ -1,9 +1,4 @@
# -*- coding: utf-8 -*-
try:
from PySide import QtCore, QtGui
except ImportError:
from PyQt4 import QtCore, QtGui
from PyQt5 import QtWidgets, QtCore
from widgets import *
@ -31,25 +26,25 @@ class LoginScreen(CenteredWidget):
self.resize(400, 200)
self.setMinimumSize(QtCore.QSize(400, 200))
self.setMaximumSize(QtCore.QSize(400, 200))
self.new_profile = QtGui.QPushButton(self)
self.new_profile = QtWidgets.QPushButton(self)
self.new_profile.setGeometry(QtCore.QRect(20, 150, 171, 27))
self.new_profile.clicked.connect(self.create_profile)
self.label = QtGui.QLabel(self)
self.label = QtWidgets.QLabel(self)
self.label.setGeometry(QtCore.QRect(20, 70, 101, 17))
self.new_name = NickEdit(self)
self.new_name.setGeometry(QtCore.QRect(20, 100, 171, 31))
self.load_profile = QtGui.QPushButton(self)
self.load_profile = QtWidgets.QPushButton(self)
self.load_profile.setGeometry(QtCore.QRect(220, 150, 161, 27))
self.load_profile.clicked.connect(self.load_ex_profile)
self.default = QtGui.QCheckBox(self)
self.default = QtWidgets.QCheckBox(self)
self.default.setGeometry(QtCore.QRect(220, 110, 131, 22))
self.groupBox = QtGui.QGroupBox(self)
self.groupBox = QtWidgets.QGroupBox(self)
self.groupBox.setGeometry(QtCore.QRect(210, 40, 181, 151))
self.comboBox = QtGui.QComboBox(self.groupBox)
self.comboBox = QtWidgets.QComboBox(self.groupBox)
self.comboBox.setGeometry(QtCore.QRect(10, 30, 161, 27))
self.groupBox_2 = QtGui.QGroupBox(self)
self.groupBox_2 = QtWidgets.QGroupBox(self)
self.groupBox_2.setGeometry(QtCore.QRect(10, 40, 191, 151))
self.toxygen = QtGui.QLabel(self)
self.toxygen = QtWidgets.QLabel(self)
self.groupBox.raise_()
self.groupBox_2.raise_()
self.comboBox.raise_()
@ -71,15 +66,15 @@ class LoginScreen(CenteredWidget):
QtCore.QMetaObject.connectSlotsByName(self)
def retranslateUi(self):
self.new_name.setPlaceholderText(QtGui.QApplication.translate("login", "Profile name", None, QtGui.QApplication.UnicodeUTF8))
self.setWindowTitle(QtGui.QApplication.translate("login", "Log in", None, QtGui.QApplication.UnicodeUTF8))
self.new_profile.setText(QtGui.QApplication.translate("login", "Create", None, QtGui.QApplication.UnicodeUTF8))
self.label.setText(QtGui.QApplication.translate("login", "Profile name:", None, QtGui.QApplication.UnicodeUTF8))
self.load_profile.setText(QtGui.QApplication.translate("login", "Load profile", None, QtGui.QApplication.UnicodeUTF8))
self.default.setText(QtGui.QApplication.translate("login", "Use as default", None, QtGui.QApplication.UnicodeUTF8))
self.groupBox.setTitle(QtGui.QApplication.translate("login", "Load existing profile", None, QtGui.QApplication.UnicodeUTF8))
self.groupBox_2.setTitle(QtGui.QApplication.translate("login", "Create new profile", None, QtGui.QApplication.UnicodeUTF8))
self.toxygen.setText(QtGui.QApplication.translate("login", "toxygen", None, QtGui.QApplication.UnicodeUTF8))
self.new_name.setPlaceholderText(QtWidgets.QApplication.translate("login", "Profile name"))
self.setWindowTitle(QtWidgets.QApplication.translate("login", "Log in"))
self.new_profile.setText(QtWidgets.QApplication.translate("login", "Create"))
self.label.setText(QtWidgets.QApplication.translate("login", "Profile name:"))
self.load_profile.setText(QtWidgets.QApplication.translate("login", "Load profile"))
self.default.setText(QtWidgets.QApplication.translate("login", "Use as default"))
self.groupBox.setTitle(QtWidgets.QApplication.translate("login", "Load existing profile"))
self.groupBox_2.setTitle(QtWidgets.QApplication.translate("login", "Create new profile"))
self.toxygen.setText(QtWidgets.QApplication.translate("login", "toxygen"))
def create_profile(self):
self.type = 1

View File

@ -2,10 +2,7 @@ import sys
from loginscreen import LoginScreen
import profile
from settings import *
try:
from PySide import QtCore, QtGui
except ImportError:
from PyQt4 import QtCore, QtGui
from PyQt5 import QtCore, QtGui, QtWidgets
from bootstrap import node_generator
from mainscreen import MainWindow
from callbacks import init_callbacks, stop, start
@ -39,7 +36,7 @@ class Toxygen:
tmp = [data]
p = PasswordScreen(toxes.ToxES.get_instance(), tmp)
p.show()
self.app.connect(self.app, QtCore.SIGNAL("lastWindowClosed()"), self.app, QtCore.SLOT("quit()"))
self.app.lastWindowClosed.connect(self.app.quit)
self.app.exec_()
if tmp[0] == data:
raise SystemExit()
@ -50,7 +47,7 @@ class Toxygen:
"""
Main function of app. loads login screen if needed and starts main screen
"""
app = QtGui.QApplication(sys.argv)
app = QtWidgets.QApplication(sys.argv)
app.setWindowIcon(QtGui.QIcon(curr_directory() + '/images/icon.png'))
self.app = app
@ -92,7 +89,6 @@ class Toxygen:
_login = self.Login(profiles)
ls.update_on_close(_login.login_screen_close)
ls.show()
app.connect(app, QtCore.SIGNAL("lastWindowClosed()"), app, QtCore.SLOT("quit()"))
app.exec_()
if not _login.t:
return
@ -101,40 +97,35 @@ class Toxygen:
name = _login.name if _login.name else 'toxygen_user'
pr = map(lambda x: x[1], ProfileHelper.find_profiles())
if name in list(pr):
msgBox = QtGui.QMessageBox()
msgBox = QtWidgets.QMessageBox()
msgBox.setWindowTitle(
QtGui.QApplication.translate("MainWindow", "Error", None, QtGui.QApplication.UnicodeUTF8))
text = (QtGui.QApplication.translate("MainWindow",
'Profile with this name already exists',
None, QtGui.QApplication.UnicodeUTF8))
QtWidgets.QApplication.translate("MainWindow", "Error"))
text = (QtWidgets.QApplication.translate("MainWindow",
'Profile with this name already exists'))
msgBox.setText(text)
msgBox.exec_()
return
self.tox = profile.tox_factory()
self.tox.self_set_name(bytes(_login.name, 'utf-8') if _login.name else b'Toxygen User')
self.tox.self_set_status_message(b'Toxing on Toxygen')
reply = QtGui.QMessageBox.question(None,
reply = QtWidgets.QMessageBox.question(None,
'Profile {}'.format(name),
QtGui.QApplication.translate("login",
'Do you want to set profile password?',
None,
QtGui.QApplication.UnicodeUTF8),
QtGui.QMessageBox.Yes,
QtGui.QMessageBox.No)
if reply == QtGui.QMessageBox.Yes:
QtWidgets.QApplication.translate("login",
'Do you want to set profile password?'),
QtWidgets.QMessageBox.Yes,
QtWidgets.QMessageBox.No)
if reply == QtWidgets.QMessageBox.Yes:
set_pass = SetProfilePasswordScreen(encrypt_save)
set_pass.show()
self.app.connect(self.app, QtCore.SIGNAL("lastWindowClosed()"), self.app, QtCore.SLOT("quit()"))
self.app.lastWindowClosed.connect(self.app.quit)
self.app.exec_()
reply = QtGui.QMessageBox.question(None,
reply = QtWidgets.QMessageBox.question(None,
'Profile {}'.format(name),
QtGui.QApplication.translate("login",
'Do you want to save profile in default folder? If no, profile will be saved in program folder',
None,
QtGui.QApplication.UnicodeUTF8),
QtGui.QMessageBox.Yes,
QtGui.QMessageBox.No)
if reply == QtGui.QMessageBox.Yes:
QtWidgets.QApplication.translate("login",
'Do you want to save profile in default folder? If no, profile will be saved in program folder'),
QtWidgets.QMessageBox.Yes,
QtWidgets.QMessageBox.No)
if reply == QtWidgets.QMessageBox.Yes:
path = Settings.get_default_path()
else:
path = curr_directory() + '/'
@ -143,11 +134,9 @@ class Toxygen:
except Exception as ex:
print(str(ex))
log('Profile creation exception: ' + str(ex))
msgBox = QtGui.QMessageBox()
msgBox.setText(QtGui.QApplication.translate("login",
'Profile saving error! Does Toxygen have permission to write to this directory?',
None,
QtGui.QApplication.UnicodeUTF8))
msgBox = QtWidgets.QMessageBox()
msgBox.setText(QtWidgets.QApplication.translate("login",
'Profile saving error! Does Toxygen have permission to write to this directory?'))
msgBox.exec_()
return
path = Settings.get_default_path()
@ -173,12 +162,12 @@ class Toxygen:
self.tox = profile.tox_factory(data, settings)
if Settings.is_active_profile(path, name): # profile is in use
reply = QtGui.QMessageBox.question(None,
reply = QtWidgets.QMessageBox.question(None,
'Profile {}'.format(name),
QtGui.QApplication.translate("login", 'Other instance of Toxygen uses this profile or profile was not properly closed. Continue?', None, QtGui.QApplication.UnicodeUTF8),
QtGui.QMessageBox.Yes,
QtGui.QMessageBox.No)
if reply != QtGui.QMessageBox.Yes:
QtWidgets.QApplication.translate("login", 'Other instance of Toxygen uses this profile or profile was not properly closed. Continue?'),
QtWidgets.QMessageBox.Yes,
QtWidgets.QMessageBox.No)
if reply != QtWidgets.QMessageBox.Yes:
return
else:
settings.set_active_profile()
@ -190,21 +179,21 @@ class Toxygen:
app.translator = translator
# tray icon
self.tray = QtGui.QSystemTrayIcon(QtGui.QIcon(curr_directory() + '/images/icon.png'))
self.tray = QtWidgets.QSystemTrayIcon(QtGui.QIcon(curr_directory() + '/images/icon.png'))
self.tray.setObjectName('tray')
self.ms = MainWindow(self.tox, self.reset, self.tray)
app.aboutToQuit.connect(self.ms.close_window)
class Menu(QtGui.QMenu):
class Menu(QtWidgets.QMenu):
def newStatus(self, status):
if not Settings.get_instance().locked:
profile.Profile.get_instance().set_status(status)
self.aboutToShow()
self.aboutToShowHandler()
self.hide()
def aboutToShow(self):
def aboutToShowHandler(self):
status = profile.Profile.get_instance().status
act = self.act
if status is None or Settings.get_instance().locked:
@ -218,42 +207,47 @@ class Toxygen:
self.actions()[2].setVisible(not Settings.get_instance().locked)
def languageChange(self, *args, **kwargs):
self.actions()[0].setText(QtGui.QApplication.translate('tray', 'Open Toxygen', None, QtGui.QApplication.UnicodeUTF8))
self.actions()[1].setText(QtGui.QApplication.translate('tray', 'Set status', None, QtGui.QApplication.UnicodeUTF8))
self.actions()[2].setText(QtGui.QApplication.translate('tray', 'Exit', None, QtGui.QApplication.UnicodeUTF8))
self.act.actions()[0].setText(QtGui.QApplication.translate('tray', 'Online', None, QtGui.QApplication.UnicodeUTF8))
self.act.actions()[1].setText(QtGui.QApplication.translate('tray', 'Away', None, QtGui.QApplication.UnicodeUTF8))
self.act.actions()[2].setText(QtGui.QApplication.translate('tray', 'Busy', None, QtGui.QApplication.UnicodeUTF8))
self.actions()[0].setText(QtWidgets.QApplication.translate('tray', 'Open Toxygen'))
self.actions()[1].setText(QtWidgets.QApplication.translate('tray', 'Set status'))
self.actions()[2].setText(QtWidgets.QApplication.translate('tray', 'Exit'))
self.act.actions()[0].setText(QtWidgets.QApplication.translate('tray', 'Online'))
self.act.actions()[1].setText(QtWidgets.QApplication.translate('tray', 'Away'))
self.act.actions()[2].setText(QtWidgets.QApplication.translate('tray', 'Busy'))
m = Menu()
show = m.addAction(QtGui.QApplication.translate('tray', 'Open Toxygen', None, QtGui.QApplication.UnicodeUTF8))
sub = m.addMenu(QtGui.QApplication.translate('tray', 'Set status', None, QtGui.QApplication.UnicodeUTF8))
onl = sub.addAction(QtGui.QApplication.translate('tray', 'Online', None, QtGui.QApplication.UnicodeUTF8))
away = sub.addAction(QtGui.QApplication.translate('tray', 'Away', None, QtGui.QApplication.UnicodeUTF8))
busy = sub.addAction(QtGui.QApplication.translate('tray', 'Busy', None, QtGui.QApplication.UnicodeUTF8))
show = m.addAction(QtWidgets.QApplication.translate('tray', 'Open Toxygen'))
sub = m.addMenu(QtWidgets.QApplication.translate('tray', 'Set status'))
onl = sub.addAction(QtWidgets.QApplication.translate('tray', 'Online'))
away = sub.addAction(QtWidgets.QApplication.translate('tray', 'Away'))
busy = sub.addAction(QtWidgets.QApplication.translate('tray', 'Busy'))
onl.setCheckable(True)
away.setCheckable(True)
busy.setCheckable(True)
m.act = sub
exit = m.addAction(QtGui.QApplication.translate('tray', 'Exit', None, QtGui.QApplication.UnicodeUTF8))
exit = m.addAction(QtWidgets.QApplication.translate('tray', 'Exit'))
def show_window():
s = Settings.get_instance()
def show():
if not self.ms.isActiveWindow():
self.ms.setWindowState(self.ms.windowState() & ~QtCore.Qt.WindowMinimized | QtCore.Qt.WindowActive)
self.ms.activateWindow()
self.ms.show()
if not Settings.get_instance().locked:
if not s.locked:
show()
else:
def correct_pass():
show()
Settings.get_instance().locked = False
self.p = UnlockAppScreen(toxes.ToxES.get_instance(), correct_pass)
self.p.show()
s.locked = False
s.unlockScreen = False
if not s.unlockScreen:
s.unlockScreen = True
self.p = UnlockAppScreen(toxes.ToxES.get_instance(), correct_pass)
self.p.show()
def tray_activated(reason):
if reason == QtGui.QSystemTrayIcon.DoubleClick:
if reason == QtWidgets.QSystemTrayIcon.DoubleClick:
show_window()
def close_app():
@ -261,12 +255,12 @@ class Toxygen:
settings.closing = True
self.ms.close()
m.connect(show, QtCore.SIGNAL("triggered()"), show_window)
m.connect(exit, QtCore.SIGNAL("triggered()"), close_app)
m.connect(m, QtCore.SIGNAL("aboutToShow()"), lambda: m.aboutToShow())
sub.connect(onl, QtCore.SIGNAL("triggered()"), lambda: m.newStatus(0))
sub.connect(away, QtCore.SIGNAL("triggered()"), lambda: m.newStatus(1))
sub.connect(busy, QtCore.SIGNAL("triggered()"), lambda: m.newStatus(2))
show.triggered.connect(show_window)
exit.triggered.connect(close_app)
m.aboutToShow.connect(lambda: m.aboutToShowHandler())
onl.triggered.connect(lambda: m.newStatus(0))
away.triggered.connect(lambda: m.newStatus(1))
busy.triggered.connect(lambda: m.newStatus(2))
self.tray.setContextMenu(m)
self.tray.show()
@ -282,15 +276,13 @@ class Toxygen:
updater.download(version)
updating = True
else:
reply = QtGui.QMessageBox.question(None,
reply = QtWidgets.QMessageBox.question(None,
'Toxygen',
QtGui.QApplication.translate("login",
'Update for Toxygen was found. Download and install it?',
None,
QtGui.QApplication.UnicodeUTF8),
QtGui.QMessageBox.Yes,
QtGui.QMessageBox.No)
if reply == QtGui.QMessageBox.Yes:
QtWidgets.QApplication.translate("login",
'Update for Toxygen was found. Download and install it?'),
QtWidgets.QMessageBox.Yes,
QtWidgets.QMessageBox.No)
if reply == QtWidgets.QMessageBox.Yes:
updater.download(version)
updating = True
@ -318,7 +310,7 @@ class Toxygen:
if self.uri is not None:
self.ms.add_contact(self.uri)
app.connect(app, QtCore.SIGNAL("lastWindowClosed()"), app, QtCore.SLOT("quit()"))
app.lastWindowClosed.connect(app.quit)
app.exec_()
self.init.stop = True

View File

@ -1,7 +1,7 @@
from menu import *
from profile import *
from list_items import *
from widgets import MultilineEdit, LineEdit, ComboBox
from widgets import MultilineEdit, ComboBox
import plugin_support
from mainscreen_widgets import *
import settings
@ -9,7 +9,7 @@ import platform
import toxes
class MainWindow(QtGui.QMainWindow, Singleton):
class MainWindow(QtWidgets.QMainWindow, Singleton):
def __init__(self, tox, reset, tray):
super().__init__()
@ -23,7 +23,7 @@ class MainWindow(QtGui.QMainWindow, Singleton):
self.ws = WelcomeScreen()
def setup_menu(self, Form):
box = QtGui.QHBoxLayout()
box = QtWidgets.QHBoxLayout()
box.setContentsMargins(0, 0, 0, 0)
box.setAlignment(QtCore.Qt.AlignLeft)
self.profile_button = MainMenuButton(Form)
@ -36,36 +36,37 @@ class MainWindow(QtGui.QMainWindow, Singleton):
box.addWidget(self.about_button)
box.setSpacing(0)
self.menuProfile = QtGui.QMenu()
self.menuProfile = QtWidgets.QMenu()
self.menuProfile.setObjectName("menuProfile")
self.menuSettings = QtGui.QMenu()
self.menuSettings = QtWidgets.QMenu()
self.menuSettings.setObjectName("menuSettings")
self.menuPlugins = QtGui.QMenu()
self.menuPlugins = QtWidgets.QMenu()
self.menuPlugins.setObjectName("menuPlugins")
self.menuAbout = QtGui.QMenu()
self.menuAbout = QtWidgets.QMenu()
self.menuAbout.setObjectName("menuAbout")
self.actionAdd_friend = QtGui.QAction(Form)
self.actionAdd_friend = QtWidgets.QAction(Form)
self.actionAdd_friend.setObjectName("actionAdd_friend")
self.actionprofilesettings = QtGui.QAction(Form)
self.actionprofilesettings = QtWidgets.QAction(Form)
self.actionprofilesettings.setObjectName("actionprofilesettings")
self.actionPrivacy_settings = QtGui.QAction(Form)
self.actionPrivacy_settings = QtWidgets.QAction(Form)
self.actionPrivacy_settings.setObjectName("actionPrivacy_settings")
self.actionInterface_settings = QtGui.QAction(Form)
self.actionInterface_settings = QtWidgets.QAction(Form)
self.actionInterface_settings.setObjectName("actionInterface_settings")
self.actionNotifications = QtGui.QAction(Form)
self.actionNotifications = QtWidgets.QAction(Form)
self.actionNotifications.setObjectName("actionNotifications")
self.actionNetwork = QtGui.QAction(Form)
self.actionNetwork = QtWidgets.QAction(Form)
self.actionNetwork.setObjectName("actionNetwork")
self.actionAbout_program = QtGui.QAction(Form)
self.actionAbout_program = QtWidgets.QAction(Form)
self.actionAbout_program.setObjectName("actionAbout_program")
self.updateSettings = QtGui.QAction(Form)
self.actionSettings = QtGui.QAction(Form)
self.updateSettings = QtWidgets.QAction(Form)
self.actionSettings = QtWidgets.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.audioSettings = QtWidgets.QAction(Form)
self.pluginData = QtWidgets.QAction(Form)
self.importPlugin = QtWidgets.QAction(Form)
self.reloadPlugins = QtWidgets.QAction(Form)
self.lockApp = QtWidgets.QAction(Form)
self.menuProfile.addAction(self.actionAdd_friend)
self.menuProfile.addAction(self.actionSettings)
self.menuProfile.addAction(self.lockApp)
@ -77,6 +78,7 @@ class MainWindow(QtGui.QMainWindow, Singleton):
self.menuSettings.addAction(self.updateSettings)
self.menuPlugins.addAction(self.pluginData)
self.menuPlugins.addAction(self.importPlugin)
self.menuPlugins.addAction(self.reloadPlugins)
self.menuAbout.addAction(self.actionAbout_program)
self.profile_button.setMenu(self.menuProfile)
@ -96,6 +98,7 @@ class MainWindow(QtGui.QMainWindow, Singleton):
self.pluginData.triggered.connect(self.plugins_menu)
self.lockApp.triggered.connect(self.lock_app)
self.importPlugin.triggered.connect(self.import_plugin)
self.reloadPlugins.triggered.connect(self.reload_plugins)
Form.setLayout(box)
QtCore.QMetaObject.connectSlotsByName(Form)
@ -110,36 +113,37 @@ class MainWindow(QtGui.QMainWindow, Singleton):
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.lockApp.setText(QtWidgets.QApplication.translate("MainWindow", "Lock"))
self.plugins_button.setText(QtWidgets.QApplication.translate("MainWindow", "Plugins"))
self.pluginData.setText(QtWidgets.QApplication.translate("MainWindow", "List of plugins"))
self.profile_button.setText(QtWidgets.QApplication.translate("MainWindow", "Profile"))
self.settings_button.setText(QtWidgets.QApplication.translate("MainWindow", "Settings"))
self.about_button.setText(QtWidgets.QApplication.translate("MainWindow", "About"))
self.actionAdd_friend.setText(QtWidgets.QApplication.translate("MainWindow", "Add contact"))
self.actionprofilesettings.setText(QtWidgets.QApplication.translate("MainWindow", "Profile"))
self.actionPrivacy_settings.setText(QtWidgets.QApplication.translate("MainWindow", "Privacy"))
self.actionInterface_settings.setText(QtWidgets.QApplication.translate("MainWindow", "Interface"))
self.actionNotifications.setText(QtWidgets.QApplication.translate("MainWindow", "Notifications"))
self.actionNetwork.setText(QtWidgets.QApplication.translate("MainWindow", "Network"))
self.actionAbout_program.setText(QtWidgets.QApplication.translate("MainWindow", "About program"))
self.actionSettings.setText(QtWidgets.QApplication.translate("MainWindow", "Settings"))
self.audioSettings.setText(QtWidgets.QApplication.translate("MainWindow", "Audio"))
self.updateSettings.setText(QtWidgets.QApplication.translate("MainWindow", "Updates"))
self.contact_name.setPlaceholderText(QtWidgets.QApplication.translate("MainWindow", "Search"))
self.sendMessageButton.setToolTip(QtWidgets.QApplication.translate("MainWindow", "Send message"))
self.callButton.setToolTip(QtWidgets.QApplication.translate("MainWindow", "Start audio call with friend"))
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))
self.online_contacts.addItem(QtWidgets.QApplication.translate("MainWindow", "All"))
self.online_contacts.addItem(QtWidgets.QApplication.translate("MainWindow", "Online"))
self.online_contacts.addItem(QtWidgets.QApplication.translate("MainWindow", "Online first"))
self.online_contacts.addItem(QtWidgets.QApplication.translate("MainWindow", "Name"))
self.online_contacts.addItem(QtWidgets.QApplication.translate("MainWindow", "Online and by name"))
self.online_contacts.addItem(QtWidgets.QApplication.translate("MainWindow", "Online first and by name"))
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))
self.importPlugin.setText(QtWidgets.QApplication.translate("MainWindow", "Import plugin"))
self.reloadPlugins.setText(QtWidgets.QApplication.translate("MainWindow", "Reload plugins"))
def setup_right_bottom(self, Form):
Form.resize(650, 60)
@ -151,7 +155,7 @@ class MainWindow(QtGui.QMainWindow, Singleton):
font.setFamily(settings.Settings.get_instance()['font'])
self.messageEdit.setFont(font)
self.sendMessageButton = QtGui.QPushButton(Form)
self.sendMessageButton = QtWidgets.QPushButton(Form)
self.sendMessageButton.setGeometry(QtCore.QRect(565, 3, 60, 55))
self.sendMessageButton.setObjectName("sendMessageButton")
@ -174,7 +178,7 @@ class MainWindow(QtGui.QMainWindow, Singleton):
def setup_left_center_menu(self, Form):
Form.resize(270, 25)
self.search_label = QtGui.QLabel(Form)
self.search_label = QtWidgets.QLabel(Form)
self.search_label.setGeometry(QtCore.QRect(3, 2, 20, 20))
pixmap = QtGui.QPixmap()
pixmap.load(curr_directory() + '/images/search.png')
@ -198,7 +202,7 @@ class MainWindow(QtGui.QMainWindow, Singleton):
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 = Form.avatar_label = QtWidgets.QLabel(Form)
self.avatar_label.setGeometry(QtCore.QRect(5, 5, 64, 64))
self.avatar_label.setScaledContents(False)
self.avatar_label.setAlignment(QtCore.Qt.AlignCenter)
@ -226,7 +230,7 @@ class MainWindow(QtGui.QMainWindow, Singleton):
def setup_right_top(self, Form):
Form.resize(650, 75)
self.account_avatar = QtGui.QLabel(Form)
self.account_avatar = QtWidgets.QLabel(Form)
self.account_avatar.setGeometry(QtCore.QRect(10, 5, 64, 64))
self.account_avatar.setScaledContents(False)
self.account_name = DataLabel(Form)
@ -245,16 +249,16 @@ class MainWindow(QtGui.QMainWindow, Singleton):
font.setBold(False)
self.account_status.setFont(font)
self.account_status.setObjectName("account_status")
self.callButton = QtGui.QPushButton(Form)
self.callButton = QtWidgets.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 = QtWidgets.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 = QtWidgets.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')
@ -264,20 +268,19 @@ class MainWindow(QtGui.QMainWindow, Singleton):
QtCore.QMetaObject.connectSlotsByName(Form)
def setup_left_center(self, widget):
self.friends_list = QtGui.QListWidget(widget)
self.friends_list = QtWidgets.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.customContextMenuRequested.connect(self.friend_right_click)
self.friends_list.setVerticalScrollMode(QtWidgets.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 = QtWidgets.QListWidget(widget)
self.messages.setGeometry(0, 0, 620, 310)
self.messages.setObjectName("messages")
self.messages.setSpacing(1)
@ -291,8 +294,8 @@ class MainWindow(QtGui.QMainWindow, Singleton):
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)
self.messages.setVerticalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
self.messages.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
def initUI(self, tox):
self.setMinimumSize(920, 500)
@ -300,15 +303,15 @@ class MainWindow(QtGui.QMainWindow, Singleton):
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()
menu = QtWidgets.QWidget()
main = QtWidgets.QWidget()
grid = QtWidgets.QGridLayout()
search = QtWidgets.QWidget()
name = QtWidgets.QWidget()
info = QtWidgets.QWidget()
main_list = QtWidgets.QWidget()
messages = QtWidgets.QWidget()
message_buttons = QtWidgets.QWidget()
self.setup_left_center_menu(search)
self.setup_left_top(name)
self.setup_right_center(messages)
@ -365,9 +368,9 @@ class MainWindow(QtGui.QMainWindow, Singleton):
s['width'] = self.width()
s['height'] = self.height()
s.save()
QtGui.QApplication.closeAllWindows()
QtWidgets.QApplication.closeAllWindows()
event.accept()
elif QtGui.QSystemTrayIcon.isSystemTrayAvailable():
elif QtWidgets.QSystemTrayIcon.isSystemTrayAvailable():
event.ignore()
self.hide()
@ -397,13 +400,13 @@ class MainWindow(QtGui.QMainWindow, Singleton):
self.profile.update()
def keyPressEvent(self, event):
if event.key() == QtCore.Qt.Key_Escape and QtGui.QSystemTrayIcon.isSystemTrayAvailable():
if event.key() == QtCore.Qt.Key_Escape and QtWidgets.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 = QtWidgets.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()
@ -418,9 +421,9 @@ class MainWindow(QtGui.QMainWindow, Singleton):
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 = QtWidgets.QMessageBox()
msgBox.setWindowTitle(QtWidgets.QApplication.translate("MainWindow", "About"))
text = (QtWidgets.QApplication.translate("MainWindow", 'Toxygen is Tox client written on Python.\nVersion: '))
msgBox.setText(text + util.program_version + '\nGitHub: https://github.com/toxygen-project/toxygen/')
msgBox.exec_()
@ -460,24 +463,26 @@ class MainWindow(QtGui.QMainWindow, Singleton):
self.update_s = UpdateSettings()
self.update_s.show()
def reload_plugins(self):
plugin_loader = plugin_support.PluginLoader.get_instance()
if plugin_loader is not None:
plugin_loader.reload()
def import_plugin(self):
import util
directory = QtGui.QFileDialog.getExistingDirectory(self,
QtGui.QApplication.translate("MainWindow", 'Choose folder with plugin',
None,
QtGui.QApplication.UnicodeUTF8),
directory = QtWidgets.QFileDialog.getExistingDirectory(self,
QtWidgets.QApplication.translate("MainWindow", 'Choose folder with plugin'),
util.curr_directory(),
QtGui.QFileDialog.ShowDirsOnly | QtGui.QFileDialog.DontUseNativeDialog)
QtWidgets.QFileDialog.ShowDirsOnly | QtWidgets.QFileDialog.DontUseNativeDialog)
if directory:
src = directory + '/'
dest = curr_directory() + '/plugins/'
util.copy(src, dest)
msgBox = QtGui.QMessageBox()
msgBox = QtWidgets.QMessageBox()
msgBox.setWindowTitle(
QtGui.QApplication.translate("MainWindow", "Restart Toxygen", None, QtGui.QApplication.UnicodeUTF8))
QtWidgets.QApplication.translate("MainWindow", "Restart Toxygen"))
msgBox.setText(
QtGui.QApplication.translate("MainWindow", 'Plugin will be loaded after restart', None,
QtGui.QApplication.UnicodeUTF8))
QtWidgets.QApplication.translate("MainWindow", 'Plugin will be loaded after restart'))
msgBox.exec_()
def lock_app(self):
@ -485,12 +490,11 @@ class MainWindow(QtGui.QMainWindow, Singleton):
Settings.get_instance().locked = True
self.hide()
else:
msgBox = QtGui.QMessageBox()
msgBox = QtWidgets.QMessageBox()
msgBox.setWindowTitle(
QtGui.QApplication.translate("MainWindow", "Cannot lock app", None, QtGui.QApplication.UnicodeUTF8))
QtWidgets.QApplication.translate("MainWindow", "Cannot lock app"))
msgBox.setText(
QtGui.QApplication.translate("MainWindow", 'Error. Profile password is not set.', None,
QtGui.QApplication.UnicodeUTF8))
QtWidgets.QApplication.translate("MainWindow", 'Error. Profile password is not set.'))
msgBox.exec_()
def show_menu(self):
@ -513,8 +517,8 @@ class MainWindow(QtGui.QMainWindow, Singleton):
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)
choose = QtWidgets.QApplication.translate("MainWindow", 'Choose file')
name = QtWidgets.QFileDialog.getOpenFileName(self, choose, options=QtWidgets.QFileDialog.DontUseNativeDialog)
if name[0]:
self.profile.send_file(name[0])
@ -579,40 +583,43 @@ class MainWindow(QtGui.QMainWindow, Singleton):
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)
auto = QtWidgets.QApplication.translate("MainWindow", 'Disallow auto accept') if allowed else QtWidgets.QApplication.translate("MainWindow", 'Allow auto accept')
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))
self.listMenu = QtWidgets.QMenu()
set_alias_item = self.listMenu.addAction(QtWidgets.QApplication.translate("MainWindow", 'Set alias'))
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))
history_menu = self.listMenu.addMenu(QtWidgets.QApplication.translate("MainWindow", 'Chat history'))
clear_history_item = history_menu.addAction(QtWidgets.QApplication.translate("MainWindow", 'Clear history'))
export_to_text_item = history_menu.addAction(QtWidgets.QApplication.translate("MainWindow", 'Export as text'))
export_to_html_item = history_menu.addAction(QtWidgets.QApplication.translate("MainWindow", 'Export as HTML'))
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))
copy_menu = self.listMenu.addMenu(QtWidgets.QApplication.translate("MainWindow", 'Copy'))
copy_name_item = copy_menu.addAction(QtWidgets.QApplication.translate("MainWindow", 'Name'))
copy_status_item = copy_menu.addAction(QtWidgets.QApplication.translate("MainWindow", 'Status message'))
copy_key_item = copy_menu.addAction(QtWidgets.QApplication.translate("MainWindow", 'Public key'))
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))
remove_item = self.listMenu.addAction(QtWidgets.QApplication.translate("MainWindow", 'Remove friend'))
block_item = self.listMenu.addAction(QtWidgets.QApplication.translate("MainWindow", 'Block friend'))
notes_item = self.listMenu.addAction(QtWidgets.QApplication.translate("MainWindow", 'Notes'))
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))
plugins_loader = plugin_support.PluginLoader.get_instance()
if plugins_loader is not None:
submenu = plugins_loader.get_menu(self.listMenu, num)
if len(submenu):
plug = self.listMenu.addMenu(QtWidgets.QApplication.translate("MainWindow", 'Plugins'))
plug.addActions(submenu)
set_alias_item.triggered.connect(lambda: self.set_alias(num))
remove_item.triggered.connect(lambda: self.remove_friend(num))
block_item.triggered.connect(lambda: self.block_friend(num))
copy_key_item.triggered.connect(lambda: self.copy_friend_key(num))
clear_history_item.triggered.connect(lambda: self.clear_history(num))
auto_accept_item.triggered.connect(lambda: self.auto_accept(num, not allowed))
notes_item.triggered.connect(lambda: self.show_note(friend))
copy_name_item.triggered.connect(lambda: self.copy_name(friend))
copy_status_item.triggered.connect(lambda: self.copy_status(friend))
export_to_text_item.triggered.connect(lambda: self.export_history(num))
export_to_html_item.triggered.connect(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()
@ -620,7 +627,7 @@ class MainWindow(QtGui.QMainWindow, Singleton):
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 = QtWidgets.QApplication.translate("MainWindow", 'Notes about user')
user = '{} {}'.format(user, friend.name)
def save_note(text):
@ -634,12 +641,11 @@ class MainWindow(QtGui.QMainWindow, Singleton):
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),
directory = QtWidgets.QFileDialog.getExistingDirectory(None,
QtWidgets.QApplication.translate("MainWindow",
'Choose folder'),
curr_directory(),
QtGui.QFileDialog.ShowDirsOnly | QtGui.QFileDialog.DontUseNativeDialog)
QtWidgets.QFileDialog.ShowDirsOnly | QtWidgets.QFileDialog.DontUseNativeDialog)
if directory:
name = 'exported_history_{}.{}'.format(convert_time(time.time()), 'txt' if as_text else 'html')
@ -652,17 +658,21 @@ class MainWindow(QtGui.QMainWindow, Singleton):
def remove_friend(self, num):
self.profile.delete_friend(num)
def block_friend(self, num):
friend = self.profile.get_friend(num)
self.profile.block_user(friend.tox_id)
def copy_friend_key(self, num):
tox_id = self.profile.friend_public_key(num)
clipboard = QtGui.QApplication.clipboard()
clipboard = QtWidgets.QApplication.clipboard()
clipboard.setText(tox_id)
def copy_name(self, friend):
clipboard = QtGui.QApplication.clipboard()
clipboard = QtWidgets.QApplication.clipboard()
clipboard.setText(friend.name)
def copy_status(self, friend):
clipboard = QtGui.QApplication.clipboard()
clipboard = QtWidgets.QApplication.clipboard()
clipboard.setText(friend.status_message)
def clear_history(self, num):

View File

@ -1,14 +1,11 @@
try:
from PySide import QtCore, QtGui
except ImportError:
from PyQt4 import QtCore, QtGui
from PyQt5 import QtCore, QtGui, QtWidgets
from widgets import RubberBand, create_menu, QRightClickButton, CenteredWidget, LineEdit
from profile import Profile
import smileys
import util
class MessageArea(QtGui.QPlainTextEdit):
class MessageArea(QtWidgets.QPlainTextEdit):
"""User types messages here"""
def __init__(self, parent, form):
@ -20,7 +17,7 @@ class MessageArea(QtGui.QPlainTextEdit):
def keyPressEvent(self, event):
if event.matches(QtGui.QKeySequence.Paste):
mimeData = QtGui.QApplication.clipboard().mimeData()
mimeData = QtWidgets.QApplication.clipboard().mimeData()
if mimeData.hasUrls():
for url in mimeData.urls():
self.pasteEvent(url.toString())
@ -67,14 +64,14 @@ class MessageArea(QtGui.QPlainTextEdit):
e.ignore()
def pasteEvent(self, text=None):
text = text or QtGui.QApplication.clipboard().text()
text = text or QtWidgets.QApplication.clipboard().text()
if text.startswith('file://'):
self.parent.profile.send_file(text[7:])
else:
self.insertPlainText(text)
class ScreenShotWindow(QtGui.QWidget):
class ScreenShotWindow(QtWidgets.QWidget):
def __init__(self, parent):
super(ScreenShotWindow, self).__init__()
@ -84,6 +81,8 @@ class ScreenShotWindow(QtGui.QWidget):
self.showFullScreen()
self.setWindowOpacity(0.5)
self.rubberband = RubberBand()
self.rubberband.setWindowFlags(self.rubberband.windowFlags() | QtCore.Qt.FramelessWindowHint)
self.rubberband.setAttribute(QtCore.Qt.WA_TranslucentBackground)
def closeEvent(self, *args):
if self.parent.isHidden():
@ -93,7 +92,7 @@ class ScreenShotWindow(QtGui.QWidget):
self.origin = event.pos()
self.rubberband.setGeometry(QtCore.QRect(self.origin, QtCore.QSize()))
self.rubberband.show()
QtGui.QWidget.mousePressEvent(self, event)
QtWidgets.QWidget.mousePressEvent(self, event)
def mouseMoveEvent(self, event):
if self.rubberband.isVisible():
@ -109,11 +108,12 @@ class ScreenShotWindow(QtGui.QWidget):
self.rubberband.hide()
rect = self.rubberband.geometry()
if rect.width() and rect.height():
p = QtGui.QPixmap.grabWindow(QtGui.QApplication.desktop().winId(),
rect.x() + 4,
rect.y() + 4,
rect.width() - 8,
rect.height() - 8)
screen = QtWidgets.QApplication.primaryScreen()
p = screen.grabWindow(0,
rect.x() + 4,
rect.y() + 4,
rect.width() - 8,
rect.height() - 8)
byte_array = QtCore.QByteArray()
buffer = QtCore.QBuffer(byte_array)
buffer.open(QtCore.QIODevice.WriteOnly)
@ -129,7 +129,7 @@ class ScreenShotWindow(QtGui.QWidget):
super(ScreenShotWindow, self).keyPressEvent(event)
class SmileyWindow(QtGui.QWidget):
class SmileyWindow(QtWidgets.QWidget):
"""
Smiley selection window
"""
@ -151,7 +151,7 @@ class SmileyWindow(QtGui.QWidget):
self.radio = []
self.parent = parent
for i in range(self.page_count): # buttons with smileys
elem = QtGui.QRadioButton(self)
elem = QtWidgets.QRadioButton(self)
elem.setGeometry(QtCore.QRect(i * 20 + 5, 180, 20, 20))
elem.clicked.connect(lambda i=i: self.checked(i))
self.radio.append(elem)
@ -160,7 +160,7 @@ class SmileyWindow(QtGui.QWidget):
self.setMinimumSize(width, 200)
self.buttons = []
for i in range(self.page_size): # pages - radio buttons
b = QtGui.QPushButton(self)
b = QtWidgets.QPushButton(self)
b.setGeometry(QtCore.QRect((i // 8) * 20 + 5, (i % 8) * 20, 20, 20))
b.clicked.connect(lambda i=i: self.clicked(i))
self.buttons.append(b)
@ -190,7 +190,7 @@ class SmileyWindow(QtGui.QWidget):
self.close()
class MenuButton(QtGui.QPushButton):
class MenuButton(QtWidgets.QPushButton):
def __init__(self, parent, enter):
super(MenuButton, self).__init__(parent)
@ -201,7 +201,7 @@ class MenuButton(QtGui.QPushButton):
super(MenuButton, self).enterEvent(event)
class DropdownMenu(QtGui.QWidget):
class DropdownMenu(QtWidgets.QWidget):
def __init__(self, parent):
super(DropdownMenu, self).__init__(parent)
@ -213,20 +213,20 @@ class DropdownMenu(QtGui.QWidget):
self.screenshotButton.setGeometry(QtCore.QRect(0, 60, 60, 60))
self.screenshotButton.setObjectName("screenshotButton")
self.fileTransferButton = QtGui.QPushButton(self)
self.fileTransferButton = QtWidgets.QPushButton(self)
self.fileTransferButton.setGeometry(QtCore.QRect(60, 60, 60, 60))
self.fileTransferButton.setObjectName("fileTransferButton")
self.audioMessageButton = QtGui.QPushButton(self)
self.audioMessageButton = QtWidgets.QPushButton(self)
self.audioMessageButton.setGeometry(QtCore.QRect(120, 60, 60, 60))
self.smileyButton = QtGui.QPushButton(self)
self.smileyButton = QtWidgets.QPushButton(self)
self.smileyButton.setGeometry(QtCore.QRect(0, 0, 60, 60))
self.videoMessageButton = QtGui.QPushButton(self)
self.videoMessageButton = QtWidgets.QPushButton(self)
self.videoMessageButton.setGeometry(QtCore.QRect(120, 0, 60, 60))
self.stickerButton = QtGui.QPushButton(self)
self.stickerButton = QtWidgets.QPushButton(self)
self.stickerButton.setGeometry(QtCore.QRect(60, 0, 60, 60))
pixmap = QtGui.QPixmap(util.curr_directory() + '/images/file.png')
@ -254,16 +254,16 @@ class DropdownMenu(QtGui.QWidget):
self.stickerButton.setIcon(icon)
self.stickerButton.setIconSize(QtCore.QSize(55, 55))
self.screenshotButton.setToolTip(QtGui.QApplication.translate("MenuWindow", "Send screenshot", None, QtGui.QApplication.UnicodeUTF8))
self.fileTransferButton.setToolTip(QtGui.QApplication.translate("MenuWindow", "Send file", None, QtGui.QApplication.UnicodeUTF8))
self.audioMessageButton.setToolTip(QtGui.QApplication.translate("MenuWindow", "Send audio message", None, QtGui.QApplication.UnicodeUTF8))
self.videoMessageButton.setToolTip(QtGui.QApplication.translate("MenuWindow", "Send video message", None, QtGui.QApplication.UnicodeUTF8))
self.smileyButton.setToolTip(QtGui.QApplication.translate("MenuWindow", "Add smiley", None, QtGui.QApplication.UnicodeUTF8))
self.stickerButton.setToolTip(QtGui.QApplication.translate("MenuWindow", "Send sticker", None, QtGui.QApplication.UnicodeUTF8))
self.screenshotButton.setToolTip(QtWidgets.QApplication.translate("MenuWindow", "Send screenshot"))
self.fileTransferButton.setToolTip(QtWidgets.QApplication.translate("MenuWindow", "Send file"))
self.audioMessageButton.setToolTip(QtWidgets.QApplication.translate("MenuWindow", "Send audio message"))
self.videoMessageButton.setToolTip(QtWidgets.QApplication.translate("MenuWindow", "Send video message"))
self.smileyButton.setToolTip(QtWidgets.QApplication.translate("MenuWindow", "Add smiley"))
self.stickerButton.setToolTip(QtWidgets.QApplication.translate("MenuWindow", "Send sticker"))
self.fileTransferButton.clicked.connect(parent.send_file)
self.screenshotButton.clicked.connect(parent.send_screenshot)
self.connect(self.screenshotButton, QtCore.SIGNAL("rightClicked()"), lambda: parent.send_screenshot(True))
self.screenshotButton.rightClicked.connect(lambda: parent.send_screenshot(True))
self.smileyButton.clicked.connect(parent.send_smiley)
self.stickerButton.clicked.connect(parent.send_sticker)
@ -276,11 +276,11 @@ class DropdownMenu(QtGui.QWidget):
return False
class StickerItem(QtGui.QWidget):
class StickerItem(QtWidgets.QWidget):
def __init__(self, fl):
super(StickerItem, self).__init__()
self._image_label = QtGui.QLabel(self)
self._image_label = QtWidgets.QLabel(self)
self.path = fl
self.pixmap = QtGui.QPixmap()
self.pixmap.load(fl)
@ -290,7 +290,7 @@ class StickerItem(QtGui.QWidget):
self._image_label.setPixmap(self.pixmap)
class StickerWindow(QtGui.QWidget):
class StickerWindow(QtWidgets.QWidget):
"""Sticker selection window"""
def __init__(self, parent):
@ -298,16 +298,16 @@ class StickerWindow(QtGui.QWidget):
self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
self.setMaximumSize(250, 200)
self.setMinimumSize(250, 200)
self.list = QtGui.QListWidget(self)
self.list = QtWidgets.QListWidget(self)
self.list.setGeometry(QtCore.QRect(0, 0, 250, 200))
self.arr = smileys.sticker_loader()
for sticker in self.arr:
item = StickerItem(sticker)
elem = QtGui.QListWidgetItem()
elem = QtWidgets.QListWidgetItem()
elem.setSizeHint(QtCore.QSize(250, item.height()))
self.list.addItem(elem)
self.list.setItemWidget(elem, item)
self.list.setVerticalScrollMode(QtGui.QAbstractItemView.ScrollPerPixel)
self.list.setVerticalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
self.list.setSpacing(3)
self.list.clicked.connect(self.click)
self.parent = parent
@ -329,60 +329,44 @@ class WelcomeScreen(CenteredWidget):
self.setMinimumSize(250, 200)
self.center()
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
self.text = QtGui.QTextBrowser(self)
self.text = QtWidgets.QTextBrowser(self)
self.text.setGeometry(QtCore.QRect(0, 0, 250, 170))
self.text.setOpenExternalLinks(True)
self.checkbox = QtGui.QCheckBox(self)
self.checkbox = QtWidgets.QCheckBox(self)
self.checkbox.setGeometry(QtCore.QRect(5, 170, 240, 30))
self.checkbox.setText(QtGui.QApplication.translate('WelcomeScreen', "Don't show again",
None, QtGui.QApplication.UnicodeUTF8))
self.setWindowTitle(QtGui.QApplication.translate('WelcomeScreen', 'Tip of the day',
None, QtGui.QApplication.UnicodeUTF8))
self.checkbox.setText(QtWidgets.QApplication.translate('WelcomeScreen', "Don't show again"))
self.setWindowTitle(QtWidgets.QApplication.translate('WelcomeScreen', 'Tip of the day'))
import random
num = random.randint(0, 10)
if num == 0:
text = QtGui.QApplication.translate('WelcomeScreen', 'Press Esc if you want hide app to tray.',
None, QtGui.QApplication.UnicodeUTF8)
text = QtWidgets.QApplication.translate('WelcomeScreen', 'Press Esc if you want hide app to tray.')
elif num == 1:
text = QtGui.QApplication.translate('WelcomeScreen',
'Right click on screenshot button hides app to tray during screenshot.',
None, QtGui.QApplication.UnicodeUTF8)
text = QtWidgets.QApplication.translate('WelcomeScreen',
'Right click on screenshot button hides app to tray during screenshot.')
elif num == 2:
text = QtGui.QApplication.translate('WelcomeScreen',
'You can use Tox over Tor. For more info read <a href="https://wiki.tox.chat/users/tox_over_tor_tot">this post</a>',
None, QtGui.QApplication.UnicodeUTF8)
text = QtWidgets.QApplication.translate('WelcomeScreen',
'You can use Tox over Tor. For more info read <a href="https://wiki.tox.chat/users/tox_over_tor_tot">this post</a>')
elif num == 3:
text = QtGui.QApplication.translate('WelcomeScreen',
'Use Settings -> Interface to customize interface.',
None, QtGui.QApplication.UnicodeUTF8)
text = QtWidgets.QApplication.translate('WelcomeScreen',
'Use Settings -> Interface to customize interface.')
elif num == 4:
text = QtGui.QApplication.translate('WelcomeScreen',
'Set profile password via Profile -> Settings. Password allows Toxygen encrypt your history and settings.',
None, QtGui.QApplication.UnicodeUTF8)
text = QtWidgets.QApplication.translate('WelcomeScreen',
'Set profile password via Profile -> Settings. Password allows Toxygen encrypt your history and settings.')
elif num == 5:
text = QtGui.QApplication.translate('WelcomeScreen',
'Since v0.1.3 Toxygen supports plugins. <a href="https://github.com/xveduk/toxygen/blob/master/docs/plugins.md">Read more</a>',
None, QtGui.QApplication.UnicodeUTF8)
elif num == 6:
text = QtGui.QApplication.translate('WelcomeScreen',
'New in Toxygen v0.2.6:<br>Updater<br>Better contact sorting<br>Plugins improvements',
None, QtGui.QApplication.UnicodeUTF8)
elif num == 7:
text = QtGui.QApplication.translate('WelcomeScreen',
'Toxygen supports faux offline messages and file transfers. Send message or file to offline friend and he will get it later.',
None, QtGui.QApplication.UnicodeUTF8)
text = QtWidgets.QApplication.translate('WelcomeScreen',
'Since v0.1.3 Toxygen supports plugins. <a href="https://github.com/xveduk/toxygen/blob/master/docs/plugins.md">Read more</a>')
elif num in (6, 7):
text = QtWidgets.QApplication.translate('WelcomeScreen',
'Toxygen supports faux offline messages and file transfers. Send message or file to offline friend and he will get it later.')
elif num == 8:
text = QtGui.QApplication.translate('WelcomeScreen',
'Delete single message in chat: make right click on spinner or message time and choose "Delete" in menu',
None, QtGui.QApplication.UnicodeUTF8)
text = QtWidgets.QApplication.translate('WelcomeScreen',
'Delete single message in chat: make right click on spinner or message time and choose "Delete" in menu')
elif num == 9:
text = QtGui.QApplication.translate('WelcomeScreen',
'Use right click on inline image to save it',
None, QtGui.QApplication.UnicodeUTF8)
text = QtWidgets.QApplication.translate('WelcomeScreen',
'Use right click on inline image to save it')
else:
text = QtGui.QApplication.translate('WelcomeScreen',
'Set new NoSpam to avoid spam friend requests: Profile -> Settings -> Set new NoSpam.',
None, QtGui.QApplication.UnicodeUTF8)
text = QtWidgets.QApplication.translate('WelcomeScreen',
'Set new NoSpam to avoid spam friend requests: Profile -> Settings -> Set new NoSpam.')
self.text.setHtml(text)
self.checkbox.stateChanged.connect(self.not_show)
QtCore.QTimer.singleShot(1000, self.show)
@ -394,7 +378,7 @@ class WelcomeScreen(CenteredWidget):
s.save()
class MainMenuButton(QtGui.QPushButton):
class MainMenuButton(QtWidgets.QPushButton):
def __init__(self, *args):
super().__init__(*args)
@ -406,16 +390,18 @@ class MainMenuButton(QtGui.QPushButton):
super().setText(text)
class ClickableLabel(QtGui.QLabel):
class ClickableLabel(QtWidgets.QLabel):
clicked = QtCore.pyqtSignal()
def __init__(self, *args):
super().__init__(*args)
def mouseReleaseEvent(self, ev):
self.emit(QtCore.SIGNAL('clicked()'))
self.clicked.emit()
class SearchScreen(QtGui.QWidget):
class SearchScreen(QtWidgets.QWidget):
def __init__(self, messages, width, *args):
super().__init__(*args)
@ -433,23 +419,23 @@ class SearchScreen(QtGui.QWidget):
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)
self.search_button.clicked.connect(self.search)
font = QtGui.QFont()
font.setPointSize(32)
font.setBold(True)
self.prev_button = QtGui.QPushButton(self)
self.prev_button = QtWidgets.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 = QtWidgets.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 = QtWidgets.QPushButton(self)
self.close_button.setGeometry(width - 40, 0, 40, 40)
self.close_button.clicked.connect(self.close)
self.close_button.setText('×')
@ -462,8 +448,7 @@ class SearchScreen(QtGui.QWidget):
self.retranslateUi()
def retranslateUi(self):
self.search_text.setPlaceholderText(QtGui.QApplication.translate("MainWindow", "Search", None,
QtGui.QApplication.UnicodeUTF8))
self.search_text.setPlaceholderText(QtWidgets.QApplication.translate("MainWindow", "Search"))
def show(self):
super().show()
@ -519,13 +504,11 @@ class SearchScreen(QtGui.QWidget):
@staticmethod
def not_found(text):
mbox = QtGui.QMessageBox()
mbox.setText(QtGui.QApplication.translate("MainWindow",
'Text "{}" was not found'.format(text),
None,
QtGui.QApplication.UnicodeUTF8))
mbox.setWindowTitle(QtGui.QApplication.translate("MainWindow",
'Not found',
None,
QtGui.QApplication.UnicodeUTF8))
mbox = QtWidgets.QMessageBox()
mbox_text = QtWidgets.QApplication.translate("MainWindow",
'Text "{}" was not found')
mbox.setText(mbox_text.format(text))
mbox.setWindowTitle(QtWidgets.QApplication.translate("MainWindow",
'Not found'))
mbox.exec_()

View File

@ -1,7 +1,4 @@
try:
from PySide import QtCore, QtGui
except ImportError:
from PyQt4 import QtCore, QtGui
from PyQt5 import QtCore, QtGui, QtWidgets
from settings import *
from profile import Profile
from util import curr_directory, copy
@ -23,7 +20,7 @@ class AddContact(CenteredWidget):
def initUI(self, tox_id):
self.setObjectName('AddContact')
self.resize(568, 306)
self.sendRequestButton = QtGui.QPushButton(self)
self.sendRequestButton = QtWidgets.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))
@ -33,7 +30,7 @@ class AddContact(CenteredWidget):
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 = QtWidgets.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))
@ -44,10 +41,10 @@ class AddContact(CenteredWidget):
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 = QtWidgets.QTextEdit(self)
self.message_edit.setGeometry(QtCore.QRect(50, 110, 471, 151))
self.message_edit.setObjectName("textEdit")
self.message = QtGui.QLabel(self)
self.message = QtWidgets.QLabel(self)
self.message.setGeometry(QtCore.QRect(50, 70, 101, 31))
self.message.setFont(font)
self.message.setObjectName("label_2")
@ -73,11 +70,11 @@ class AddContact(CenteredWidget):
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))
self.setWindowTitle(QtWidgets.QApplication.translate('AddContact', "Add contact"))
self.sendRequestButton.setText(QtWidgets.QApplication.translate("Form", "Send request"))
self.label.setText(QtWidgets.QApplication.translate('AddContact', "TOX ID:"))
self.message.setText(QtWidgets.QApplication.translate('AddContact', "Message:"))
self.tox_id.setPlaceholderText(QtWidgets.QApplication.translate('AddContact', "TOX ID or public key of contact"))
class ProfileSettings(CenteredWidget):
@ -95,12 +92,12 @@ class ProfileSettings(CenteredWidget):
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 = QtWidgets.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 = QtWidgets.QLabel(self)
self.label.setGeometry(QtCore.QRect(40, 30, 91, 25))
font = QtGui.QFont()
font.setFamily(Settings.get_instance()['font'])
@ -108,59 +105,59 @@ class ProfileSettings(CenteredWidget):
font.setWeight(75)
font.setBold(True)
self.label.setFont(font)
self.label_2 = QtGui.QLabel(self)
self.label_2 = QtWidgets.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 = QtWidgets.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 = QtWidgets.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 = QtWidgets.QPushButton(self)
self.copyId.setGeometry(QtCore.QRect(40, 250, 180, 30))
self.copyId.clicked.connect(self.copy)
self.export = QtGui.QPushButton(self)
self.export = QtWidgets.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 = QtWidgets.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 = QtWidgets.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 = QtWidgets.QPushButton(self)
self.new_avatar.setGeometry(QtCore.QRect(230, 300, 180, 30))
self.delete_avatar = QtGui.QPushButton(self)
self.delete_avatar = QtWidgets.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 = QtWidgets.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.password.setEchoMode(QtWidgets.QLineEdit.Password)
self.leave_blank = QtWidgets.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.confirm_password.setEchoMode(QtWidgets.QLineEdit.Password)
self.set_password = QtWidgets.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 = QtWidgets.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 = QtWidgets.QLabel(self)
self.warning.setGeometry(QtCore.QRect(40, 510, 500, 30))
self.warning.setStyleSheet('QLabel { color: #BC1C1C; }')
self.default = QtGui.QPushButton(self)
self.default = QtWidgets.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
@ -173,30 +170,30 @@ class ProfileSettings(CenteredWidget):
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))
self.export.setText(QtWidgets.QApplication.translate("ProfileSettingsForm", "Export profile"))
self.setWindowTitle(QtWidgets.QApplication.translate("ProfileSettingsForm", "Profile settings"))
self.label.setText(QtWidgets.QApplication.translate("ProfileSettingsForm", "Name:"))
self.label_2.setText(QtWidgets.QApplication.translate("ProfileSettingsForm", "Status:"))
self.label_3.setText(QtWidgets.QApplication.translate("ProfileSettingsForm", "TOX ID:"))
self.copyId.setText(QtWidgets.QApplication.translate("ProfileSettingsForm", "Copy TOX ID"))
self.new_avatar.setText(QtWidgets.QApplication.translate("ProfileSettingsForm", "New avatar"))
self.delete_avatar.setText(QtWidgets.QApplication.translate("ProfileSettingsForm", "Reset avatar"))
self.new_nospam.setText(QtWidgets.QApplication.translate("ProfileSettingsForm", "New NoSpam"))
self.profilepass.setText(QtWidgets.QApplication.translate("ProfileSettingsForm", "Profile password"))
self.password.setPlaceholderText(QtWidgets.QApplication.translate("ProfileSettingsForm", "Password (at least 8 symbols)"))
self.confirm_password.setPlaceholderText(QtWidgets.QApplication.translate("ProfileSettingsForm", "Confirm password"))
self.set_password.setText(QtWidgets.QApplication.translate("ProfileSettingsForm", "Set password"))
self.not_match.setText(QtWidgets.QApplication.translate("ProfileSettingsForm", "Passwords do not match"))
self.leave_blank.setText(QtWidgets.QApplication.translate("ProfileSettingsForm", "Leaving blank will reset current password"))
self.warning.setText(QtWidgets.QApplication.translate("ProfileSettingsForm", "There is no way to recover lost passwords"))
self.status.addItem(QtWidgets.QApplication.translate("ProfileSettingsForm", "Online"))
self.status.addItem(QtWidgets.QApplication.translate("ProfileSettingsForm", "Away"))
self.status.addItem(QtWidgets.QApplication.translate("ProfileSettingsForm", "Busy"))
self.copy_pk.setText(QtWidgets.QApplication.translate("ProfileSettingsForm", "Copy public key"))
if self.auto:
self.default.setText(QtGui.QApplication.translate("ProfileSettingsForm", "Mark as not default profile", None, QtGui.QApplication.UnicodeUTF8))
self.default.setText(QtWidgets.QApplication.translate("ProfileSettingsForm", "Mark as not default profile"))
else:
self.default.setText(QtGui.QApplication.translate("ProfileSettingsForm", "Mark as default profile", None, QtGui.QApplication.UnicodeUTF8))
self.default.setText(QtWidgets.QApplication.translate("ProfileSettingsForm", "Mark as default profile"))
def auto_profile(self):
if self.auto:
@ -205,12 +202,10 @@ class ProfileSettings(CenteredWidget):
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))
self.default.setText(QtWidgets.QApplication.translate("ProfileSettingsForm", "Mark as not default profile"))
else:
self.default.setText(
QtGui.QApplication.translate("ProfileSettingsForm", "Mark as default profile", None,
QtGui.QApplication.UnicodeUTF8))
QtWidgets.QApplication.translate("ProfileSettingsForm", "Mark as default profile"))
def new_password(self):
if self.password.text() == self.confirm_password.text():
@ -220,16 +215,14 @@ class ProfileSettings(CenteredWidget):
self.close()
else:
self.not_match.setText(
QtGui.QApplication.translate("ProfileSettingsForm", "Password must be at least 8 symbols", None,
QtGui.QApplication.UnicodeUTF8))
QtWidgets.QApplication.translate("ProfileSettingsForm", "Password must be at least 8 symbols"))
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.setText(QtWidgets.QApplication.translate("ProfileSettingsForm", "Passwords do not match"))
self.not_match.setVisible(True)
def copy(self):
clipboard = QtGui.QApplication.clipboard()
clipboard = QtWidgets.QApplication.clipboard()
profile = Profile.get_instance()
clipboard.setText(profile.tox_id)
pixmap = QtGui.QPixmap(curr_directory() + '/images/accept.png')
@ -238,7 +231,7 @@ class ProfileSettings(CenteredWidget):
self.copyId.setIconSize(QtCore.QSize(10, 10))
def copy_public_key(self):
clipboard = QtGui.QApplication.clipboard()
clipboard = QtWidgets.QApplication.clipboard()
profile = Profile.get_instance()
clipboard.setText(profile.tox_id[:64])
pixmap = QtGui.QPixmap(curr_directory() + '/images/accept.png')
@ -253,13 +246,13 @@ class ProfileSettings(CenteredWidget):
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)
choose = QtWidgets.QApplication.translate("ProfileSettingsForm", "Choose avatar")
name = QtWidgets.QFileDialog.getOpenFileName(self, choose, None, None, 'Images (*.png)',
QtWidgets.QFileDialog.DontUseNativeDialog)
if name[0]:
bitmap = QtGui.QPixmap(name[0])
bitmap.scaled(QtCore.QSize(128, 128), aspectMode=QtCore.Qt.KeepAspectRatio,
mode=QtCore.Qt.SmoothTransformation)
bitmap.scaled(128, 128, QtCore.Qt.KeepAspectRatio,
QtCore.Qt.SmoothTransformation)
byte_array = QtCore.QByteArray()
buffer = QtCore.QBuffer(byte_array)
@ -268,25 +261,22 @@ class ProfileSettings(CenteredWidget):
Profile.get_instance().set_avatar(bytes(byte_array.data()))
def export_profile(self):
directory = QtGui.QFileDialog.getExistingDirectory(options=QtGui.QFileDialog.DontUseNativeDialog,
dir=curr_directory()) + '/'
directory = QtWidgets.QFileDialog.getExistingDirectory(self, '', curr_directory() + '/',
QtWidgets.QFileDialog.ShowDirsOnly | QtWidgets.QFileDialog.DontUseNativeDialog)
if directory != '/':
reply = QtGui.QMessageBox.question(None,
QtGui.QApplication.translate("ProfileSettingsForm",
'Use new path',
None,
QtGui.QApplication.UnicodeUTF8),
QtGui.QApplication.translate("ProfileSettingsForm",
'Do you want to move your profile to this location?',
None,
QtGui.QApplication.UnicodeUTF8),
QtGui.QMessageBox.Yes,
QtGui.QMessageBox.No)
reply = QtWidgets.QMessageBox.question(None,
QtWidgets.QApplication.translate("ProfileSettingsForm",
'Use new path'),
QtWidgets.QApplication.translate("ProfileSettingsForm",
'Do you want to move your profile to this location?'),
QtWidgets.QMessageBox.Yes,
QtWidgets.QMessageBox.No)
settings = Settings.get_instance()
settings.export(directory)
profile = Profile.get_instance()
profile.export_db(directory)
ProfileHelper.get_instance().export_profile(directory, reply == QtGui.QMessageBox.Yes)
ProfileHelper.get_instance().export_profile(directory, reply == QtWidgets.QMessageBox.Yes)
def closeEvent(self, event):
profile = Profile.get_instance()
@ -309,15 +299,15 @@ class NetworkSettings(CenteredWidget):
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 = QtWidgets.QCheckBox(self)
self.ipv.setGeometry(QtCore.QRect(20, 10, 97, 22))
self.ipv.setObjectName("ipv")
self.udp = QtGui.QCheckBox(self)
self.udp = QtWidgets.QCheckBox(self)
self.udp.setGeometry(QtCore.QRect(150, 10, 97, 22))
self.udp.setObjectName("udp")
self.proxy = QtGui.QCheckBox(self)
self.proxy = QtWidgets.QCheckBox(self)
self.proxy.setGeometry(QtCore.QRect(20, 40, 97, 22))
self.http = QtGui.QCheckBox(self)
self.http = QtWidgets.QCheckBox(self)
self.http.setGeometry(QtCore.QRect(20, 70, 97, 22))
self.proxy.setObjectName("proxy")
self.proxyip = LineEdit(self)
@ -326,11 +316,11 @@ class NetworkSettings(CenteredWidget):
self.proxyport = LineEdit(self)
self.proxyport.setGeometry(QtCore.QRect(40, 190, 231, 27))
self.proxyport.setObjectName("proxyport")
self.label = QtGui.QLabel(self)
self.label = QtWidgets.QLabel(self)
self.label.setGeometry(QtCore.QRect(40, 100, 66, 17))
self.label_2 = QtGui.QLabel(self)
self.label_2 = QtWidgets.QLabel(self)
self.label_2.setGeometry(QtCore.QRect(40, 165, 66, 17))
self.reconnect = QtGui.QPushButton(self)
self.reconnect = QtWidgets.QPushButton(self)
self.reconnect.setGeometry(QtCore.QRect(40, 230, 231, 30))
self.reconnect.clicked.connect(self.restart_core)
settings = Settings.get_instance()
@ -340,7 +330,7 @@ class NetworkSettings(CenteredWidget):
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 = QtWidgets.QLabel(self)
self.warning.setGeometry(QtCore.QRect(5, 270, 290, 60))
self.warning.setStyleSheet('QLabel { color: #BC1C1C; }')
self.retranslateUi()
@ -349,16 +339,15 @@ class NetworkSettings(CenteredWidget):
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))
self.setWindowTitle(QtWidgets.QApplication.translate("NetworkSettings", "Network settings"))
self.ipv.setText(QtWidgets.QApplication.translate("Form", "IPv6"))
self.udp.setText(QtWidgets.QApplication.translate("Form", "UDP"))
self.proxy.setText(QtWidgets.QApplication.translate("Form", "Proxy"))
self.label.setText(QtWidgets.QApplication.translate("Form", "IP:"))
self.label_2.setText(QtWidgets.QApplication.translate("Form", "Port:"))
self.reconnect.setText(QtWidgets.QApplication.translate("NetworkSettings", "Restart TOX core"))
self.http.setText(QtWidgets.QApplication.translate("Form", "HTTP"))
self.warning.setText(QtWidgets.QApplication.translate("Form", "WARNING:\nusing proxy with enabled UDP\ncan produce IP leak"))
def activate(self):
bl = self.proxy.isChecked()
@ -395,23 +384,23 @@ class PrivacySettings(CenteredWidget):
self.resize(370, 600)
self.setMinimumSize(QtCore.QSize(370, 600))
self.setMaximumSize(QtCore.QSize(370, 600))
self.saveHistory = QtGui.QCheckBox(self)
self.saveHistory = QtWidgets.QCheckBox(self)
self.saveHistory.setGeometry(QtCore.QRect(10, 20, 350, 22))
self.saveUnsentOnly = QtGui.QCheckBox(self)
self.saveUnsentOnly = QtWidgets.QCheckBox(self)
self.saveUnsentOnly.setGeometry(QtCore.QRect(10, 60, 350, 22))
self.fileautoaccept = QtGui.QCheckBox(self)
self.fileautoaccept = QtWidgets.QCheckBox(self)
self.fileautoaccept.setGeometry(QtCore.QRect(10, 100, 350, 22))
self.typingNotifications = QtGui.QCheckBox(self)
self.typingNotifications = QtWidgets.QCheckBox(self)
self.typingNotifications.setGeometry(QtCore.QRect(10, 140, 350, 30))
self.inlines = QtGui.QCheckBox(self)
self.inlines = QtWidgets.QCheckBox(self)
self.inlines.setGeometry(QtCore.QRect(10, 180, 350, 30))
self.auto_path = QtGui.QLabel(self)
self.auto_path = QtWidgets.QLabel(self)
self.auto_path.setGeometry(QtCore.QRect(10, 230, 350, 30))
self.path = QtGui.QPlainTextEdit(self)
self.path = QtWidgets.QPlainTextEdit(self)
self.path.setGeometry(QtCore.QRect(10, 265, 350, 45))
self.change_path = QtGui.QPushButton(self)
self.change_path = QtWidgets.QPushButton(self)
self.change_path.setGeometry(QtCore.QRect(10, 320, 350, 30))
settings = Settings.get_instance()
self.typingNotifications.setChecked(settings['typing_notifications'])
@ -423,37 +412,37 @@ class PrivacySettings(CenteredWidget):
self.saveHistory.stateChanged.connect(self.update)
self.path.setPlainText(settings['auto_accept_path'] or curr_directory())
self.change_path.clicked.connect(self.new_path)
self.block_user_label = QtGui.QLabel(self)
self.block_user_label = QtWidgets.QLabel(self)
self.block_user_label.setGeometry(QtCore.QRect(10, 360, 350, 30))
self.block_id = QtGui.QPlainTextEdit(self)
self.block_id = QtWidgets.QPlainTextEdit(self)
self.block_id.setGeometry(QtCore.QRect(10, 390, 350, 30))
self.block = QtGui.QPushButton(self)
self.block = QtWidgets.QPushButton(self)
self.block.setGeometry(QtCore.QRect(10, 430, 350, 30))
self.block.clicked.connect(lambda: Profile.get_instance().block_user(self.block_id.toPlainText()) or self.close())
self.blocked_users_label = QtGui.QLabel(self)
self.blocked_users_label = QtWidgets.QLabel(self)
self.blocked_users_label.setGeometry(QtCore.QRect(10, 470, 350, 30))
self.comboBox = QtGui.QComboBox(self)
self.comboBox = QtWidgets.QComboBox(self)
self.comboBox.setGeometry(QtCore.QRect(10, 500, 350, 30))
self.comboBox.addItems(settings['blocked'])
self.unblock = QtGui.QPushButton(self)
self.unblock = QtWidgets.QPushButton(self)
self.unblock.setGeometry(QtCore.QRect(10, 540, 350, 30))
self.unblock.clicked.connect(lambda: self.unblock_user())
self.retranslateUi()
QtCore.QMetaObject.connectSlotsByName(self)
def retranslateUi(self):
self.setWindowTitle(QtGui.QApplication.translate("privacySettings", "Privacy settings", None, QtGui.QApplication.UnicodeUTF8))
self.saveHistory.setText(QtGui.QApplication.translate("privacySettings", "Save chat history", None, QtGui.QApplication.UnicodeUTF8))
self.fileautoaccept.setText(QtGui.QApplication.translate("privacySettings", "Allow file auto accept", None, QtGui.QApplication.UnicodeUTF8))
self.typingNotifications.setText(QtGui.QApplication.translate("privacySettings", "Send typing notifications", None, QtGui.QApplication.UnicodeUTF8))
self.auto_path.setText(QtGui.QApplication.translate("privacySettings", "Auto accept default path:", None, QtGui.QApplication.UnicodeUTF8))
self.change_path.setText(QtGui.QApplication.translate("privacySettings", "Change", None, QtGui.QApplication.UnicodeUTF8))
self.inlines.setText(QtGui.QApplication.translate("privacySettings", "Allow inlines", None, QtGui.QApplication.UnicodeUTF8))
self.block_user_label.setText(QtGui.QApplication.translate("privacySettings", "Block by public key:", None, QtGui.QApplication.UnicodeUTF8))
self.blocked_users_label.setText(QtGui.QApplication.translate("privacySettings", "Blocked users:", None, QtGui.QApplication.UnicodeUTF8))
self.unblock.setText(QtGui.QApplication.translate("privacySettings", "Unblock", None, QtGui.QApplication.UnicodeUTF8))
self.block.setText(QtGui.QApplication.translate("privacySettings", "Block user", None, QtGui.QApplication.UnicodeUTF8))
self.saveUnsentOnly.setText(QtGui.QApplication.translate("privacySettings", "Save unsent messages only", None, QtGui.QApplication.UnicodeUTF8))
self.setWindowTitle(QtWidgets.QApplication.translate("privacySettings", "Privacy settings"))
self.saveHistory.setText(QtWidgets.QApplication.translate("privacySettings", "Save chat history"))
self.fileautoaccept.setText(QtWidgets.QApplication.translate("privacySettings", "Allow file auto accept"))
self.typingNotifications.setText(QtWidgets.QApplication.translate("privacySettings", "Send typing notifications"))
self.auto_path.setText(QtWidgets.QApplication.translate("privacySettings", "Auto accept default path:"))
self.change_path.setText(QtWidgets.QApplication.translate("privacySettings", "Change"))
self.inlines.setText(QtWidgets.QApplication.translate("privacySettings", "Allow inlines"))
self.block_user_label.setText(QtWidgets.QApplication.translate("privacySettings", "Block by public key:"))
self.blocked_users_label.setText(QtWidgets.QApplication.translate("privacySettings", "Blocked users:"))
self.unblock.setText(QtWidgets.QApplication.translate("privacySettings", "Unblock"))
self.block.setText(QtWidgets.QApplication.translate("privacySettings", "Block user"))
self.saveUnsentOnly.setText(QtWidgets.QApplication.translate("privacySettings", "Save unsent messages only"))
def update(self, new_state):
self.saveUnsentOnly.setEnabled(new_state)
@ -463,10 +452,10 @@ class PrivacySettings(CenteredWidget):
def unblock_user(self):
if not self.comboBox.count():
return
title = QtGui.QApplication.translate("privacySettings", "Add to friend list", None, QtGui.QApplication.UnicodeUTF8)
info = QtGui.QApplication.translate("privacySettings", "Do you want to add this user to friend list?", None, QtGui.QApplication.UnicodeUTF8)
reply = QtGui.QMessageBox.question(None, title, info, QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)
Profile.get_instance().unblock_user(self.comboBox.currentText(), reply == QtGui.QMessageBox.Yes)
title = QtWidgets.QApplication.translate("privacySettings", "Add to friend list")
info = QtWidgets.QApplication.translate("privacySettings", "Do you want to add this user to friend list?")
reply = QtWidgets.QMessageBox.question(None, title, info, QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.No)
Profile.get_instance().unblock_user(self.comboBox.currentText(), reply == QtWidgets.QMessageBox.Yes)
self.close()
def closeEvent(self, event):
@ -475,31 +464,27 @@ class PrivacySettings(CenteredWidget):
settings['allow_auto_accept'] = self.fileautoaccept.isChecked()
if settings['save_history'] and not self.saveHistory.isChecked(): # clear history
reply = QtGui.QMessageBox.question(None,
QtGui.QApplication.translate("privacySettings",
'Chat history',
None, QtGui.QApplication.UnicodeUTF8),
QtGui.QApplication.translate("privacySettings",
'History will be cleaned! Continue?',
None, QtGui.QApplication.UnicodeUTF8),
QtGui.QMessageBox.Yes,
QtGui.QMessageBox.No)
if reply == QtGui.QMessageBox.Yes:
reply = QtWidgets.QMessageBox.question(None,
QtWidgets.QApplication.translate("privacySettings",
'Chat history'),
QtWidgets.QApplication.translate("privacySettings",
'History will be cleaned! Continue?'),
QtWidgets.QMessageBox.Yes,
QtWidgets.QMessageBox.No)
if reply == QtWidgets.QMessageBox.Yes:
Profile.get_instance().clear_history()
settings['save_history'] = self.saveHistory.isChecked()
else:
settings['save_history'] = self.saveHistory.isChecked()
if self.saveUnsentOnly.isChecked() and not settings['save_unsent_only']:
reply = QtGui.QMessageBox.question(None,
QtGui.QApplication.translate("privacySettings",
'Chat history',
None, QtGui.QApplication.UnicodeUTF8),
QtGui.QApplication.translate("privacySettings",
'History will be cleaned! Continue?',
None, QtGui.QApplication.UnicodeUTF8),
QtGui.QMessageBox.Yes,
QtGui.QMessageBox.No)
if reply == QtGui.QMessageBox.Yes:
reply = QtWidgets.QMessageBox.question(None,
QtWidgets.QApplication.translate("privacySettings",
'Chat history'),
QtWidgets.QApplication.translate("privacySettings",
'History will be cleaned! Continue?'),
QtWidgets.QMessageBox.Yes,
QtWidgets.QMessageBox.No)
if reply == QtWidgets.QMessageBox.Yes:
Profile.get_instance().clear_history(None, True)
settings['save_unsent_only'] = self.saveUnsentOnly.isChecked()
else:
@ -509,7 +494,8 @@ class PrivacySettings(CenteredWidget):
settings.save()
def new_path(self):
directory = QtGui.QFileDialog.getExistingDirectory(options=QtGui.QFileDialog.DontUseNativeDialog) + '/'
directory = QtWidgets.QFileDialog.getExistingDirectory(self, '', curr_directory() + '/',
QtWidgets.QFileDialog.ShowDirsOnly | QtWidgets.QFileDialog.DontUseNativeDialog) + '/'
if directory != '/':
self.path.setPlainText(directory)
@ -527,11 +513,11 @@ class NotificationsSettings(CenteredWidget):
self.resize(350, 180)
self.setMinimumSize(QtCore.QSize(350, 180))
self.setMaximumSize(QtCore.QSize(350, 180))
self.enableNotifications = QtGui.QCheckBox(self)
self.enableNotifications = QtWidgets.QCheckBox(self)
self.enableNotifications.setGeometry(QtCore.QRect(10, 20, 340, 18))
self.callsSound = QtGui.QCheckBox(self)
self.callsSound = QtWidgets.QCheckBox(self)
self.callsSound.setGeometry(QtCore.QRect(10, 120, 340, 18))
self.soundNotifications = QtGui.QCheckBox(self)
self.soundNotifications = QtWidgets.QCheckBox(self)
self.soundNotifications.setGeometry(QtCore.QRect(10, 70, 340, 18))
font = QtGui.QFont()
s = Settings.get_instance()
@ -547,10 +533,10 @@ class NotificationsSettings(CenteredWidget):
QtCore.QMetaObject.connectSlotsByName(self)
def retranslateUi(self):
self.setWindowTitle(QtGui.QApplication.translate("notificationsForm", "Notification settings", None, QtGui.QApplication.UnicodeUTF8))
self.enableNotifications.setText(QtGui.QApplication.translate("notificationsForm", "Enable notifications", None, QtGui.QApplication.UnicodeUTF8))
self.callsSound.setText(QtGui.QApplication.translate("notificationsForm", "Enable call\'s sound", None, QtGui.QApplication.UnicodeUTF8))
self.soundNotifications.setText(QtGui.QApplication.translate("notificationsForm", "Enable sound notifications", None, QtGui.QApplication.UnicodeUTF8))
self.setWindowTitle(QtWidgets.QApplication.translate("notificationsForm", "Notification settings"))
self.enableNotifications.setText(QtWidgets.QApplication.translate("notificationsForm", "Enable notifications"))
self.callsSound.setText(QtWidgets.QApplication.translate("notificationsForm", "Enable call\'s sound"))
self.soundNotifications.setText(QtWidgets.QApplication.translate("notificationsForm", "Enable sound notifications"))
def closeEvent(self, *args, **kwargs):
settings = Settings.get_instance()
@ -571,7 +557,7 @@ class InterfaceSettings(CenteredWidget):
self.setObjectName("interfaceForm")
self.setMinimumSize(QtCore.QSize(400, 650))
self.setMaximumSize(QtCore.QSize(400, 650))
self.label = QtGui.QLabel(self)
self.label = QtWidgets.QLabel(self)
self.label.setGeometry(QtCore.QRect(30, 10, 370, 20))
settings = Settings.get_instance()
font = QtGui.QFont()
@ -579,7 +565,7 @@ class InterfaceSettings(CenteredWidget):
font.setBold(True)
font.setFamily(settings['font'])
self.label.setFont(font)
self.themeSelect = QtGui.QComboBox(self)
self.themeSelect = QtWidgets.QComboBox(self)
self.themeSelect.setGeometry(QtCore.QRect(30, 40, 120, 30))
list_of_themes = ['dark']
self.themeSelect.addItems(list_of_themes)
@ -589,26 +575,26 @@ class InterfaceSettings(CenteredWidget):
else:
index = 0
self.themeSelect.setCurrentIndex(index)
self.lang_choose = QtGui.QComboBox(self)
self.lang_choose = QtWidgets.QComboBox(self)
self.lang_choose.setGeometry(QtCore.QRect(30, 110, 120, 30))
supported = sorted(Settings.supported_languages().keys(), reverse=True)
for key in supported:
self.lang_choose.insertItem(0, key)
if settings['language'] == key:
self.lang_choose.setCurrentIndex(0)
self.lang = QtGui.QLabel(self)
self.lang = QtWidgets.QLabel(self)
self.lang.setGeometry(QtCore.QRect(30, 80, 370, 20))
self.lang.setFont(font)
self.mirror_mode = QtGui.QCheckBox(self)
self.mirror_mode = QtWidgets.QCheckBox(self)
self.mirror_mode.setGeometry(QtCore.QRect(30, 160, 370, 20))
self.mirror_mode.setChecked(settings['mirror_mode'])
self.smileys = QtGui.QCheckBox(self)
self.smileys = QtWidgets.QCheckBox(self)
self.smileys.setGeometry(QtCore.QRect(30, 190, 120, 20))
self.smileys.setChecked(settings['smileys'])
self.smiley_pack_label = QtGui.QLabel(self)
self.smiley_pack_label = QtWidgets.QLabel(self)
self.smiley_pack_label.setGeometry(QtCore.QRect(30, 230, 370, 20))
self.smiley_pack_label.setFont(font)
self.smiley_pack = QtGui.QComboBox(self)
self.smiley_pack = QtWidgets.QComboBox(self)
self.smiley_pack.setGeometry(QtCore.QRect(30, 260, 160, 30))
sm = smileys.SmileyLoader.get_instance()
self.smiley_pack.addItems(sm.get_packs_list())
@ -617,39 +603,39 @@ class InterfaceSettings(CenteredWidget):
except:
ind = sm.get_packs_list().index('default')
self.smiley_pack.setCurrentIndex(ind)
self.messages_font_size_label = QtGui.QLabel(self)
self.messages_font_size_label = QtWidgets.QLabel(self)
self.messages_font_size_label.setGeometry(QtCore.QRect(30, 300, 370, 20))
self.messages_font_size_label.setFont(font)
self.messages_font_size = QtGui.QComboBox(self)
self.messages_font_size = QtWidgets.QComboBox(self)
self.messages_font_size.setGeometry(QtCore.QRect(30, 330, 160, 30))
self.messages_font_size.addItems([str(x) for x in range(10, 19)])
self.messages_font_size.setCurrentIndex(settings['message_font_size'] - 10)
self.unread = QtGui.QPushButton(self)
self.unread = QtWidgets.QPushButton(self)
self.unread.setGeometry(QtCore.QRect(30, 470, 340, 30))
self.unread.clicked.connect(self.select_color)
self.compact_mode = QtGui.QCheckBox(self)
self.compact_mode = QtWidgets.QCheckBox(self)
self.compact_mode.setGeometry(QtCore.QRect(30, 380, 370, 20))
self.compact_mode.setChecked(settings['compact_mode'])
self.close_to_tray = QtGui.QCheckBox(self)
self.close_to_tray = QtWidgets.QCheckBox(self)
self.close_to_tray.setGeometry(QtCore.QRect(30, 410, 370, 20))
self.close_to_tray.setChecked(settings['close_to_tray'])
self.show_avatars = QtGui.QCheckBox(self)
self.show_avatars = QtWidgets.QCheckBox(self)
self.show_avatars.setGeometry(QtCore.QRect(30, 440, 370, 20))
self.show_avatars.setChecked(settings['show_avatars'])
self.choose_font = QtGui.QPushButton(self)
self.choose_font = QtWidgets.QPushButton(self)
self.choose_font.setGeometry(QtCore.QRect(30, 510, 340, 30))
self.choose_font.clicked.connect(self.new_font)
self.import_smileys = QtGui.QPushButton(self)
self.import_smileys = QtWidgets.QPushButton(self)
self.import_smileys.setGeometry(QtCore.QRect(30, 550, 340, 30))
self.import_smileys.clicked.connect(self.import_sm)
self.import_stickers = QtGui.QPushButton(self)
self.import_stickers = QtWidgets.QPushButton(self)
self.import_stickers.setGeometry(QtCore.QRect(30, 590, 340, 30))
self.import_stickers.clicked.connect(self.import_st)
@ -657,29 +643,27 @@ class InterfaceSettings(CenteredWidget):
QtCore.QMetaObject.connectSlotsByName(self)
def retranslateUi(self):
self.show_avatars.setText(QtGui.QApplication.translate("interfaceForm", "Show avatars in chat", None, QtGui.QApplication.UnicodeUTF8))
self.setWindowTitle(QtGui.QApplication.translate("interfaceForm", "Interface settings", None, QtGui.QApplication.UnicodeUTF8))
self.label.setText(QtGui.QApplication.translate("interfaceForm", "Theme:", None, QtGui.QApplication.UnicodeUTF8))
self.lang.setText(QtGui.QApplication.translate("interfaceForm", "Language:", None, QtGui.QApplication.UnicodeUTF8))
self.smileys.setText(QtGui.QApplication.translate("interfaceForm", "Smileys", None, QtGui.QApplication.UnicodeUTF8))
self.smiley_pack_label.setText(QtGui.QApplication.translate("interfaceForm", "Smiley pack:", None, QtGui.QApplication.UnicodeUTF8))
self.mirror_mode.setText(QtGui.QApplication.translate("interfaceForm", "Mirror mode", None, QtGui.QApplication.UnicodeUTF8))
self.messages_font_size_label.setText(QtGui.QApplication.translate("interfaceForm", "Messages font size:", None, QtGui.QApplication.UnicodeUTF8))
self.unread.setText(QtGui.QApplication.translate("interfaceForm", "Select unread messages notification color", None, QtGui.QApplication.UnicodeUTF8))
self.compact_mode.setText(QtGui.QApplication.translate("interfaceForm", "Compact contact list", None, QtGui.QApplication.UnicodeUTF8))
self.import_smileys.setText(QtGui.QApplication.translate("interfaceForm", "Import smiley pack", None, QtGui.QApplication.UnicodeUTF8))
self.import_stickers.setText(QtGui.QApplication.translate("interfaceForm", "Import sticker pack", None, QtGui.QApplication.UnicodeUTF8))
self.close_to_tray.setText(QtGui.QApplication.translate("interfaceForm", "Close to tray", None, QtGui.QApplication.UnicodeUTF8))
self.choose_font.setText(QtGui.QApplication.translate("interfaceForm", "Select font", None, QtGui.QApplication.UnicodeUTF8))
self.show_avatars.setText(QtWidgets.QApplication.translate("interfaceForm", "Show avatars in chat"))
self.setWindowTitle(QtWidgets.QApplication.translate("interfaceForm", "Interface settings"))
self.label.setText(QtWidgets.QApplication.translate("interfaceForm", "Theme:"))
self.lang.setText(QtWidgets.QApplication.translate("interfaceForm", "Language:"))
self.smileys.setText(QtWidgets.QApplication.translate("interfaceForm", "Smileys"))
self.smiley_pack_label.setText(QtWidgets.QApplication.translate("interfaceForm", "Smiley pack:"))
self.mirror_mode.setText(QtWidgets.QApplication.translate("interfaceForm", "Mirror mode"))
self.messages_font_size_label.setText(QtWidgets.QApplication.translate("interfaceForm", "Messages font size:"))
self.unread.setText(QtWidgets.QApplication.translate("interfaceForm", "Select unread messages notification color"))
self.compact_mode.setText(QtWidgets.QApplication.translate("interfaceForm", "Compact contact list"))
self.import_smileys.setText(QtWidgets.QApplication.translate("interfaceForm", "Import smiley pack"))
self.import_stickers.setText(QtWidgets.QApplication.translate("interfaceForm", "Import sticker pack"))
self.close_to_tray.setText(QtWidgets.QApplication.translate("interfaceForm", "Close to tray"))
self.choose_font.setText(QtWidgets.QApplication.translate("interfaceForm", "Select font"))
def import_st(self):
directory = QtGui.QFileDialog.getExistingDirectory(self,
QtGui.QApplication.translate("MainWindow",
'Choose folder with sticker pack',
None,
QtGui.QApplication.UnicodeUTF8),
curr_directory(),
QtGui.QFileDialog.ShowDirsOnly | QtGui.QFileDialog.DontUseNativeDialog)
directory = QtWidgets.QFileDialog.getExistingDirectory(self,
QtWidgets.QApplication.translate("MainWindow",
'Choose folder with sticker pack'),
curr_directory(),
QtWidgets.QFileDialog.ShowDirsOnly | QtWidgets.QFileDialog.DontUseNativeDialog)
if directory:
src = directory + '/'
@ -687,13 +671,11 @@ class InterfaceSettings(CenteredWidget):
copy(src, dest)
def import_sm(self):
directory = QtGui.QFileDialog.getExistingDirectory(self,
QtGui.QApplication.translate("MainWindow",
'Choose folder with smiley pack',
None,
QtGui.QApplication.UnicodeUTF8),
directory = QtWidgets.QFileDialog.getExistingDirectory(self,
QtWidgets.QApplication.translate("MainWindow",
'Choose folder with smiley pack'),
curr_directory(),
QtGui.QFileDialog.ShowDirsOnly | QtGui.QFileDialog.DontUseNativeDialog)
QtWidgets.QFileDialog.ShowDirsOnly | QtWidgets.QFileDialog.DontUseNativeDialog)
if directory:
src = directory + '/'
@ -702,21 +684,19 @@ class InterfaceSettings(CenteredWidget):
def new_font(self):
settings = Settings.get_instance()
font, ok = QtGui.QFontDialog.getFont(QtGui.QFont(settings['font'], 10), self)
font, ok = QtWidgets.QFontDialog.getFont(QtGui.QFont(settings['font'], 10), self)
if ok:
settings['font'] = font.family()
settings.save()
msgBox = QtGui.QMessageBox()
text = QtGui.QApplication.translate("interfaceForm", 'Restart app to apply settings', None,
QtGui.QApplication.UnicodeUTF8)
msgBox.setWindowTitle(QtGui.QApplication.translate("interfaceForm", 'Restart required', None,
QtGui.QApplication.UnicodeUTF8))
msgBox = QtWidgets.QMessageBox()
text = QtWidgets.QApplication.translate("interfaceForm", 'Restart app to apply settings')
msgBox.setWindowTitle(QtWidgets.QApplication.translate("interfaceForm", 'Restart required'))
msgBox.setText(text)
msgBox.exec_()
def select_color(self):
settings = Settings.get_instance()
col = QtGui.QColorDialog.getColor(settings['unread_color'])
col = QtWidgets.QColorDialog.getColor(QtGui.QColor(settings['unread_color']))
if col.isValid():
name = col.name()
@ -745,7 +725,7 @@ class InterfaceSettings(CenteredWidget):
settings['language'] = language
text = self.lang_choose.currentText()
path = Settings.supported_languages()[text]
app = QtGui.QApplication.instance()
app = QtWidgets.QApplication.instance()
app.removeTranslator(app.translator)
app.translator.load(curr_directory() + '/translations/' + path)
app.installTranslator(app.translator)
@ -753,11 +733,9 @@ class InterfaceSettings(CenteredWidget):
Profile.get_instance().update()
settings.save()
if restart:
msgBox = QtGui.QMessageBox()
text = QtGui.QApplication.translate("interfaceForm", 'Restart app to apply settings', None,
QtGui.QApplication.UnicodeUTF8)
msgBox.setWindowTitle(QtGui.QApplication.translate("interfaceForm", 'Restart required', None,
QtGui.QApplication.UnicodeUTF8))
msgBox = QtWidgets.QMessageBox()
text = QtWidgets.QApplication.translate("interfaceForm", 'Restart app to apply settings')
msgBox.setWindowTitle(QtWidgets.QApplication.translate("interfaceForm", 'Restart required'))
msgBox.setText(text)
msgBox.exec_()
@ -778,9 +756,9 @@ class AudioSettings(CenteredWidget):
self.resize(400, 150)
self.setMinimumSize(QtCore.QSize(400, 150))
self.setMaximumSize(QtCore.QSize(400, 150))
self.in_label = QtGui.QLabel(self)
self.in_label = QtWidgets.QLabel(self)
self.in_label.setGeometry(QtCore.QRect(25, 5, 350, 20))
self.out_label = QtGui.QLabel(self)
self.out_label = QtWidgets.QLabel(self)
self.out_label.setGeometry(QtCore.QRect(25, 65, 350, 20))
settings = Settings.get_instance()
font = QtGui.QFont()
@ -789,9 +767,9 @@ class AudioSettings(CenteredWidget):
font.setFamily(settings['font'])
self.in_label.setFont(font)
self.out_label.setFont(font)
self.input = QtGui.QComboBox(self)
self.input = QtWidgets.QComboBox(self)
self.input.setGeometry(QtCore.QRect(25, 30, 350, 30))
self.output = QtGui.QComboBox(self)
self.output = QtWidgets.QComboBox(self)
self.output.setGeometry(QtCore.QRect(25, 90, 350, 30))
p = pyaudio.PyAudio()
self.in_indexes, self.out_indexes = [], []
@ -808,9 +786,9 @@ class AudioSettings(CenteredWidget):
QtCore.QMetaObject.connectSlotsByName(self)
def retranslateUi(self):
self.setWindowTitle(QtGui.QApplication.translate("audioSettingsForm", "Audio settings", None, QtGui.QApplication.UnicodeUTF8))
self.in_label.setText(QtGui.QApplication.translate("audioSettingsForm", "Input device:", None, QtGui.QApplication.UnicodeUTF8))
self.out_label.setText(QtGui.QApplication.translate("audioSettingsForm", "Output device:", None, QtGui.QApplication.UnicodeUTF8))
self.setWindowTitle(QtWidgets.QApplication.translate("audioSettingsForm", "Audio settings"))
self.in_label.setText(QtWidgets.QApplication.translate("audioSettingsForm", "Input device:"))
self.out_label.setText(QtWidgets.QApplication.translate("audioSettingsForm", "Output device:"))
def closeEvent(self, event):
settings = Settings.get_instance()
@ -834,15 +812,15 @@ class PluginsSettings(CenteredWidget):
self.resize(400, 210)
self.setMinimumSize(QtCore.QSize(400, 210))
self.setMaximumSize(QtCore.QSize(400, 210))
self.comboBox = QtGui.QComboBox(self)
self.comboBox = QtWidgets.QComboBox(self)
self.comboBox.setGeometry(QtCore.QRect(30, 10, 340, 30))
self.label = QtGui.QLabel(self)
self.label = QtWidgets.QLabel(self)
self.label.setGeometry(QtCore.QRect(30, 40, 340, 90))
self.label.setWordWrap(True)
self.button = QtGui.QPushButton(self)
self.button = QtWidgets.QPushButton(self)
self.button.setGeometry(QtCore.QRect(30, 130, 340, 30))
self.button.clicked.connect(self.button_click)
self.open = QtGui.QPushButton(self)
self.open = QtWidgets.QPushButton(self)
self.open.setGeometry(QtCore.QRect(30, 170, 340, 30))
self.open.clicked.connect(self.open_plugin)
self.pl_loader = plugin_support.PluginLoader.get_instance()
@ -851,8 +829,8 @@ class PluginsSettings(CenteredWidget):
self.show_data()
def retranslateUi(self):
self.setWindowTitle(QtGui.QApplication.translate('PluginsForm', "Plugins", None, QtGui.QApplication.UnicodeUTF8))
self.open.setText(QtGui.QApplication.translate('PluginsForm', "Open selected plugin", None, QtGui.QApplication.UnicodeUTF8))
self.setWindowTitle(QtWidgets.QApplication.translate('PluginsForm', "Plugins"))
self.open.setText(QtWidgets.QApplication.translate('PluginsForm', "Open selected plugin"))
def open_plugin(self):
ind = self.comboBox.currentIndex()
@ -862,11 +840,9 @@ class PluginsSettings(CenteredWidget):
self.window = window
self.window.show()
else:
msgBox = QtGui.QMessageBox()
text = QtGui.QApplication.translate("PluginsForm", 'No GUI found for this plugin', None,
QtGui.QApplication.UnicodeUTF8)
msgBox.setWindowTitle(QtGui.QApplication.translate("PluginsForm", 'Error', None,
QtGui.QApplication.UnicodeUTF8))
msgBox = QtWidgets.QMessageBox()
text = QtWidgets.QApplication.translate("PluginsForm", 'No GUI found for this plugin')
msgBox.setWindowTitle(QtWidgets.QApplication.translate("PluginsForm", 'Error'))
msgBox.setText(text)
msgBox.exec_()
@ -880,16 +856,16 @@ class PluginsSettings(CenteredWidget):
ind = self.comboBox.currentIndex()
if len(self.data):
plugin = self.data[ind]
descr = plugin[2] or QtGui.QApplication.translate("PluginsForm", "No description available", None, QtGui.QApplication.UnicodeUTF8)
descr = plugin[2] or QtWidgets.QApplication.translate("PluginsForm", "No description available")
self.label.setText(descr)
if plugin[1]:
self.button.setText(QtGui.QApplication.translate("PluginsForm", "Disable plugin", None, QtGui.QApplication.UnicodeUTF8))
self.button.setText(QtWidgets.QApplication.translate("PluginsForm", "Disable plugin"))
else:
self.button.setText(QtGui.QApplication.translate("PluginsForm", "Enable plugin", None, QtGui.QApplication.UnicodeUTF8))
self.button.setText(QtWidgets.QApplication.translate("PluginsForm", "Enable plugin"))
else:
self.open.setVisible(False)
self.button.setVisible(False)
self.label.setText(QtGui.QApplication.translate("PluginsForm", "No plugins found", None, QtGui.QApplication.UnicodeUTF8))
self.label.setText(QtWidgets.QApplication.translate("PluginsForm", "No plugins found"))
def button_click(self):
ind = self.comboBox.currentIndex()
@ -897,9 +873,9 @@ class PluginsSettings(CenteredWidget):
self.pl_loader.toggle_plugin(plugin[-1])
plugin[1] = not plugin[1]
if plugin[1]:
self.button.setText(QtGui.QApplication.translate("PluginsForm", "Disable plugin", None, QtGui.QApplication.UnicodeUTF8))
self.button.setText(QtWidgets.QApplication.translate("PluginsForm", "Disable plugin"))
else:
self.button.setText(QtGui.QApplication.translate("PluginsForm", "Enable plugin", None, QtGui.QApplication.UnicodeUTF8))
self.button.setText(QtWidgets.QApplication.translate("PluginsForm", "Enable plugin"))
class UpdateSettings(CenteredWidget):
@ -917,7 +893,7 @@ class UpdateSettings(CenteredWidget):
self.resize(400, 150)
self.setMinimumSize(QtCore.QSize(400, 120))
self.setMaximumSize(QtCore.QSize(400, 120))
self.in_label = QtGui.QLabel(self)
self.in_label = QtWidgets.QLabel(self)
self.in_label.setGeometry(QtCore.QRect(25, 5, 350, 20))
settings = Settings.get_instance()
font = QtGui.QFont()
@ -925,9 +901,9 @@ class UpdateSettings(CenteredWidget):
font.setBold(True)
font.setFamily(settings['font'])
self.in_label.setFont(font)
self.autoupdate = QtGui.QComboBox(self)
self.autoupdate = QtWidgets.QComboBox(self)
self.autoupdate.setGeometry(QtCore.QRect(25, 30, 350, 30))
self.button = QtGui.QPushButton(self)
self.button = QtWidgets.QPushButton(self)
self.button.setGeometry(QtCore.QRect(25, 70, 350, 30))
self.button.setEnabled(settings['update'])
self.button.clicked.connect(self.update_client)
@ -937,12 +913,12 @@ class UpdateSettings(CenteredWidget):
QtCore.QMetaObject.connectSlotsByName(self)
def retranslateUi(self):
self.setWindowTitle(QtGui.QApplication.translate("updateSettingsForm", "Update settings", None, QtGui.QApplication.UnicodeUTF8))
self.in_label.setText(QtGui.QApplication.translate("updateSettingsForm", "Select update mode:", None, QtGui.QApplication.UnicodeUTF8))
self.button.setText(QtGui.QApplication.translate("updateSettingsForm", "Update Toxygen", None, QtGui.QApplication.UnicodeUTF8))
self.autoupdate.addItem(QtGui.QApplication.translate("updateSettingsForm", "Disabled", None, QtGui.QApplication.UnicodeUTF8))
self.autoupdate.addItem(QtGui.QApplication.translate("updateSettingsForm", "Manual", None, QtGui.QApplication.UnicodeUTF8))
self.autoupdate.addItem(QtGui.QApplication.translate("updateSettingsForm", "Auto", None, QtGui.QApplication.UnicodeUTF8))
self.setWindowTitle(QtWidgets.QApplication.translate("updateSettingsForm", "Update settings"))
self.in_label.setText(QtWidgets.QApplication.translate("updateSettingsForm", "Select update mode:"))
self.button.setText(QtWidgets.QApplication.translate("updateSettingsForm", "Update Toxygen"))
self.autoupdate.addItem(QtWidgets.QApplication.translate("updateSettingsForm", "Disabled"))
self.autoupdate.addItem(QtWidgets.QApplication.translate("updateSettingsForm", "Manual"))
self.autoupdate.addItem(QtWidgets.QApplication.translate("updateSettingsForm", "Auto"))
def closeEvent(self, event):
settings = Settings.get_instance()
@ -951,34 +927,29 @@ class UpdateSettings(CenteredWidget):
def update_client(self):
if not updater.connection_available():
msgBox = QtGui.QMessageBox()
msgBox = QtWidgets.QMessageBox()
msgBox.setWindowTitle(
QtGui.QApplication.translate("updateSettingsForm", "Error", None,
QtGui.QApplication.UnicodeUTF8))
text = (QtGui.QApplication.translate("updateSettingsForm", 'Problems with internet connection', None,
QtGui.QApplication.UnicodeUTF8))
QtWidgets.QApplication.translate("updateSettingsForm", "Error"))
text = (QtWidgets.QApplication.translate("updateSettingsForm", 'Problems with internet connection'))
msgBox.setText(text)
msgBox.exec_()
return
if not updater.updater_available():
msgBox = QtGui.QMessageBox()
msgBox = QtWidgets.QMessageBox()
msgBox.setWindowTitle(
QtGui.QApplication.translate("updateSettingsForm", "Error", None,
QtGui.QApplication.UnicodeUTF8))
text = (QtGui.QApplication.translate("updateSettingsForm", 'Updater not found', None,
QtGui.QApplication.UnicodeUTF8))
QtWidgets.QApplication.translate("updateSettingsForm", "Error"))
text = (QtWidgets.QApplication.translate("updateSettingsForm", 'Updater not found'))
msgBox.setText(text)
msgBox.exec_()
return
version = updater.check_for_updates()
if version is not None:
updater.download(version)
QtGui.QApplication.closeAllWindows()
QtWidgets.QApplication.closeAllWindows()
else:
msgBox = QtGui.QMessageBox()
msgBox = QtWidgets.QMessageBox()
msgBox.setWindowTitle(
QtGui.QApplication.translate("updateSettingsForm", "No updates found", None, QtGui.QApplication.UnicodeUTF8))
text = (QtGui.QApplication.translate("updateSettingsForm", 'Toxygen is up to date', None,
QtGui.QApplication.UnicodeUTF8))
QtWidgets.QApplication.translate("updateSettingsForm", "No updates found"))
text = (QtWidgets.QApplication.translate("updateSettingsForm", 'Toxygen is up to date'))
msgBox.setText(text)
msgBox.exec_()

View File

@ -1,7 +1,4 @@
try:
from PySide import QtCore, QtGui
except ImportError:
from PyQt4 import QtCore, QtGui
from PyQt5 import QtCore, QtWidgets
from util import curr_directory
import wave
import pyaudio
@ -23,16 +20,16 @@ def tray_notification(title, text, tray, window):
:param tray: ref to tray icon
:param window: main window
"""
if QtGui.QSystemTrayIcon.isSystemTrayAvailable():
if QtWidgets.QSystemTrayIcon.isSystemTrayAvailable():
if len(text) > 30:
text = text[:27] + '...'
tray.showMessage(title, text, QtGui.QSystemTrayIcon.NoIcon, 3000)
QtGui.QApplication.alert(window, 0)
tray.showMessage(title, text, QtWidgets.QSystemTrayIcon.NoIcon, 3000)
QtWidgets.QApplication.alert(window, 0)
def message_clicked():
window.setWindowState(window.windowState() & ~QtCore.Qt.WindowMinimized | QtCore.Qt.WindowActive)
window.activateWindow()
tray.connect(tray, QtCore.SIGNAL("messageClicked()"), message_clicked)
tray.messageClicked.connect(message_clicked)
class AudioFile:

View File

@ -1,8 +1,5 @@
from widgets import CenteredWidget, LineEdit
try:
from PySide import QtCore, QtGui
except ImportError:
from PyQt4 import QtCore, QtGui
from PyQt5 import QtCore, QtWidgets
class PasswordArea(LineEdit):
@ -10,7 +7,7 @@ class PasswordArea(LineEdit):
def __init__(self, parent):
super(PasswordArea, self).__init__(parent)
self.parent = parent
self.setEchoMode(QtGui.QLineEdit.EchoMode.Password)
self.setEchoMode(QtWidgets.QLineEdit.Password)
def keyPressEvent(self, event):
if event.key() == QtCore.Qt.Key_Return:
@ -31,18 +28,18 @@ class PasswordScreenBase(CenteredWidget):
self.setMinimumSize(QtCore.QSize(360, 170))
self.setMaximumSize(QtCore.QSize(360, 170))
self.enter_pass = QtGui.QLabel(self)
self.enter_pass = QtWidgets.QLabel(self)
self.enter_pass.setGeometry(QtCore.QRect(30, 10, 300, 30))
self.password = PasswordArea(self)
self.password.setGeometry(QtCore.QRect(30, 50, 300, 30))
self.button = QtGui.QPushButton(self)
self.button = QtWidgets.QPushButton(self)
self.button.setGeometry(QtCore.QRect(30, 90, 300, 30))
self.button.setText('OK')
self.button.clicked.connect(self.button_click)
self.warning = QtGui.QLabel(self)
self.warning = QtWidgets.QLabel(self)
self.warning.setGeometry(QtCore.QRect(30, 130, 300, 30))
self.warning.setStyleSheet('QLabel { color: #F70D1A; }')
self.warning.setVisible(False)
@ -61,9 +58,9 @@ class PasswordScreenBase(CenteredWidget):
super(PasswordScreenBase, self).keyPressEvent(event)
def retranslateUi(self):
self.setWindowTitle(QtGui.QApplication.translate("pass", "Enter password", None, QtGui.QApplication.UnicodeUTF8))
self.enter_pass.setText(QtGui.QApplication.translate("pass", "Password:", None, QtGui.QApplication.UnicodeUTF8))
self.warning.setText(QtGui.QApplication.translate("pass", "Incorrect password", None, QtGui.QApplication.UnicodeUTF8))
self.setWindowTitle(QtWidgets.QApplication.translate("pass", "Enter password"))
self.enter_pass.setText(QtWidgets.QApplication.translate("pass", "Password:"))
self.warning.setText(QtWidgets.QApplication.translate("pass", "Incorrect password"))
class PasswordScreen(PasswordScreenBase):
@ -116,37 +113,32 @@ class SetProfilePasswordScreen(CenteredWidget):
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.password.setEchoMode(QtWidgets.QLineEdit.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.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 = QtGui.QLabel(self)
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 = QtGui.QLabel(self)
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(QtGui.QApplication.translate("PasswordScreen", "Profile password", None,
QtGui.QApplication.UnicodeUTF8))
self.setWindowTitle(QtWidgets.QApplication.translate("PasswordScreen", "Profile password"))
self.password.setPlaceholderText(
QtGui.QApplication.translate("PasswordScreen", "Password (at least 8 symbols)", None,
QtGui.QApplication.UnicodeUTF8))
QtWidgets.QApplication.translate("PasswordScreen", "Password (at least 8 symbols)"))
self.confirm_password.setPlaceholderText(
QtGui.QApplication.translate("PasswordScreen", "Confirm password", None,
QtGui.QApplication.UnicodeUTF8))
QtWidgets.QApplication.translate("PasswordScreen", "Confirm password"))
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))
QtWidgets.QApplication.translate("PasswordScreen", "Set password"))
self.not_match.setText(QtWidgets.QApplication.translate("PasswordScreen", "Passwords do not match"))
self.warning.setText(
QtGui.QApplication.translate("PasswordScreen", "There is no way to recover lost passwords", None,
QtGui.QApplication.UnicodeUTF8))
QtWidgets.QApplication.translate("PasswordScreen", "There is no way to recover lost passwords"))
def new_password(self):
if self.password.text() == self.confirm_password.text():
@ -155,10 +147,8 @@ class SetProfilePasswordScreen(CenteredWidget):
self.close()
else:
self.not_match.setText(
QtGui.QApplication.translate("PasswordScreen", "Password must be at least 8 symbols", None,
QtGui.QApplication.UnicodeUTF8))
QtWidgets.QApplication.translate("PasswordScreen", "Password must be at least 8 symbols"))
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.setText(QtWidgets.QApplication.translate("PasswordScreen", "Passwords do not match"))
self.not_match.setVisible(True)

View File

@ -51,7 +51,8 @@ class PluginLoader(util.Singleton):
continue
for elem in dir(module):
obj = getattr(module, elem)
if inspect.isclass(obj) and hasattr(obj, 'is_plugin') and obj.is_plugin: # looking for plugin class in module
# looking for plugin class in module
if inspect.isclass(obj) and hasattr(obj, 'is_plugin') and obj.is_plugin:
print('Plugin', elem)
try: # create instance of plugin class
inst = obj(self._tox, self._profile, self._settings, self._encr)
@ -165,3 +166,8 @@ class PluginLoader(util.Singleton):
if self._plugins[key][1]:
self._plugins[key][0].close()
del self._plugins[key]
def reload(self):
print('Reloading plugins')
self.stop()
self.load()

View File

@ -1,8 +1,5 @@
import os
try:
from PySide import QtCore, QtGui
except ImportError:
from PyQt4 import QtCore, QtGui
from PyQt5 import QtCore, QtWidgets
MAX_SHORT_NAME_LENGTH = 5
@ -137,10 +134,10 @@ class PluginSuperClass:
:param command: string with command
"""
if command == 'help':
msgbox = QtGui.QMessageBox()
title = QtGui.QApplication.translate("PluginWindow", "List of commands for plugin {}", None, QtGui.QApplication.UnicodeUTF8)
msgbox = QtWidgets.QMessageBox()
title = QtWidgets.QApplication.translate("PluginWindow", "List of commands for plugin {}")
msgbox.setWindowTitle(title.format(self._name))
msgbox.setText(QtGui.QApplication.translate("PluginWindow", "No commands available", None, QtGui.QApplication.UnicodeUTF8))
msgbox.setText(QtWidgets.QApplication.translate("PluginWindow", "No commands available"))
msgbox.exec_()
# -----------------------------------------------------------------------------------------------------------------
@ -151,7 +148,7 @@ class PluginSuperClass:
"""
This method loads translations for GUI
"""
app = QtGui.QApplication.instance()
app = QtWidgets.QApplication.instance()
langs = self._settings.supported_languages()
curr_lang = self._settings['language']
if curr_lang in langs:

View File

@ -1,8 +1,5 @@
from list_items import *
try:
from PySide import QtCore, QtGui
except ImportError:
from PyQt4 import QtCore, QtGui
from PyQt5 import QtGui, QtWidgets
from friend import *
from settings import *
from toxcore_enums_and_consts import *
@ -41,6 +38,7 @@ class Profile(basecontact.BaseContact, Singleton):
self._call = calls.AV(tox.AV) # object with data about calls
self._incoming_calls = set()
self._load_history = True
self._waiting_for_reconnection = False
self._factory = items_factory.ItemsFactory(self._screen.friends_list, self._messages)
settings = Settings.get_instance()
self._sorting = settings['sorting']
@ -86,8 +84,8 @@ class Profile(basecontact.BaseContact, Singleton):
super(Profile, self).set_status(status)
if status is not None:
self._tox.self_set_status(status)
else:
QtCore.QTimer.singleShot(45000, self.reconnect)
elif not self._waiting_for_reconnection:
QtCore.QTimer.singleShot(50000, self.reconnect)
def set_name(self, value):
if self.name == value:
@ -95,8 +93,7 @@ class Profile(basecontact.BaseContact, Singleton):
tmp = self.name
super(Profile, self).set_name(value.encode('utf-8'))
self._tox.self_set_name(self._name.encode('utf-8'))
message = QtGui.QApplication.translate("MainWindow", 'User {} is now known as {}', None,
QtGui.QApplication.UnicodeUTF8)
message = QtWidgets.QApplication.translate("MainWindow", 'User {} is now known as {}')
message = message.format(tmp, value)
for friend in self._contacts:
friend.append_message(InfoMessage(message, time.time()))
@ -218,6 +215,7 @@ class Profile(basecontact.BaseContact, Singleton):
except:
pass
friend = self._contacts[value]
friend.remove_invalid_unsent_files()
if self._active_friend != value:
self._screen.messageEdit.setPlainText(friend.curr_text)
self._active_friend = value
@ -243,7 +241,7 @@ class Profile(basecontact.BaseContact, Singleton):
if message.get_status() in ACTIVE_FILE_TRANSFERS: # active file transfer
try:
ft = self._file_transfers[(message.get_friend_number(), message.get_file_number())]
ft.set_state_changed_handler(item.update)
ft.set_state_changed_handler(item.update_transfer_state)
ft.signal()
except:
print('Incoming not started transfer - no info found')
@ -309,7 +307,7 @@ class Profile(basecontact.BaseContact, Singleton):
friend.set_name(name)
name = str(name, 'utf-8')
if friend.name == name and tmp != name:
message = QtGui.QApplication.translate("MainWindow", 'User {} is now known as {}', None, QtGui.QApplication.UnicodeUTF8)
message = QtWidgets.QApplication.translate("MainWindow", 'User {} is now known as {}')
message = message.format(tmp, name)
friend.append_message(InfoMessage(message, time.time()))
friend.actions = True
@ -328,6 +326,7 @@ class Profile(basecontact.BaseContact, Singleton):
def send_files(self, friend_number):
friend = self.get_friend_by_number(friend_number)
friend.remove_invalid_unsent_files()
files = friend.get_unsent_files()
try:
for fl in files:
@ -409,25 +408,25 @@ class Profile(basecontact.BaseContact, Singleton):
for message in messages:
self.split_and_send(friend_number, message.get_data()[-1], message.get_data()[0].encode('utf-8'))
friend.inc_receipts()
except:
pass
except Exception as ex:
log('Sending pending messages failed with ' + str(ex))
def split_and_send(self, number, message_type, message):
"""
Message splitting
Message splitting. Message length cannot be > TOX_MAX_MESSAGE_LENGTH
:param number: friend's number
:param message_type: type of message
:param message: message text
"""
while len(message) > TOX_MAX_MESSAGE_LENGTH:
size = TOX_MAX_MESSAGE_LENGTH * 4 / 5
size = TOX_MAX_MESSAGE_LENGTH * 4 // 5
last_part = message[size:TOX_MAX_MESSAGE_LENGTH]
if ' ' in last_part:
index = last_part.index(' ')
elif ',' in last_part:
index = last_part.index(',')
elif '.' in last_part:
index = last_part.index('.')
if b' ' in last_part:
index = last_part.index(b' ')
elif b',' in last_part:
index = last_part.index(b',')
elif b'.' in last_part:
index = last_part.index(b'.')
else:
index = TOX_MAX_MESSAGE_LENGTH - size - 1
index += size + 1
@ -562,7 +561,7 @@ class Profile(basecontact.BaseContact, Singleton):
if message.get_status() in ACTIVE_FILE_TRANSFERS: # active file transfer
try:
ft = self._file_transfers[(message.get_friend_number(), message.get_file_number())]
ft.set_state_changed_handler(item.update)
ft.set_state_changed_handler(item.update_transfer_state)
ft.signal()
except:
print('Incoming not started transfer - no info found')
@ -659,17 +658,15 @@ class Profile(basecontact.BaseContact, Singleton):
"""
friend = self._contacts[num]
name = friend.name
dialog = QtGui.QApplication.translate('MainWindow',
"Enter new alias for friend {} or leave empty to use friend's name:",
None, QtGui.QApplication.UnicodeUTF8)
dialog = QtWidgets.QApplication.translate('MainWindow',
"Enter new alias for friend {} or leave empty to use friend's name:")
dialog = dialog.format(name)
title = QtGui.QApplication.translate('MainWindow',
'Set alias',
None, QtGui.QApplication.UnicodeUTF8)
title = QtWidgets.QApplication.translate('MainWindow',
'Set alias')
text, ok = QtGui.QInputDialog.getText(None,
title,
dialog,
QtGui.QLineEdit.Normal,
QtWidgets.QLineEdit.Normal,
name)
if ok:
settings = Settings.get_instance()
@ -794,9 +791,9 @@ class Profile(basecontact.BaseContact, Singleton):
raise Exception('TOX DNS lookup failed')
if len(tox_id) == TOX_PUBLIC_KEY_SIZE * 2: # public key
self.add_friend(tox_id)
msgBox = QtGui.QMessageBox()
msgBox.setWindowTitle(QtGui.QApplication.translate("MainWindow", "Friend added", None, QtGui.QApplication.UnicodeUTF8))
text = (QtGui.QApplication.translate("MainWindow", 'Friend added without sending friend request', None, QtGui.QApplication.UnicodeUTF8))
msgBox = QtWidgets.QMessageBox()
msgBox.setWindowTitle(QtWidgets.QApplication.translate("MainWindow", "Friend added"))
text = (QtWidgets.QApplication.translate("MainWindow", 'Friend added without sending friend request'))
msgBox.setText(text)
msgBox.exec_()
else:
@ -822,11 +819,11 @@ class Profile(basecontact.BaseContact, Singleton):
:param message: message
"""
try:
text = QtGui.QApplication.translate('MainWindow', 'User {} wants to add you to contact list. Message:\n{}', None, QtGui.QApplication.UnicodeUTF8)
text = QtWidgets.QApplication.translate('MainWindow', 'User {} wants to add you to contact list. Message:\n{}')
info = text.format(tox_id, message)
fr_req = QtGui.QApplication.translate('MainWindow', 'Friend request', None, QtGui.QApplication.UnicodeUTF8)
reply = QtGui.QMessageBox.question(None, fr_req, info, QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)
if reply == QtGui.QMessageBox.Yes: # accepted
fr_req = QtWidgets.QApplication.translate('MainWindow', 'Friend request')
reply = QtWidgets.QMessageBox.question(None, fr_req, info, QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.No)
if reply == QtWidgets.QMessageBox.Yes: # accepted
self.add_friend(tox_id)
data = self._tox.get_savedata()
ProfileHelper.get_instance().save_profile(data)
@ -855,9 +852,11 @@ class Profile(basecontact.BaseContact, Singleton):
self.update_filtration()
def reconnect(self):
self._waiting_for_reconnection = False
if self.status is None or all(list(map(lambda x: x.status is None, self._contacts))) and len(self._contacts):
self._waiting_for_reconnection = True
self.reset(self._screen.reset)
QtCore.QTimer.singleShot(45000, self.reconnect)
QtCore.QTimer.singleShot(50000, self.reconnect)
def close(self):
for friend in self._contacts:
@ -936,7 +935,7 @@ class Profile(basecontact.BaseContact, Singleton):
if friend_number == self.get_active_number():
item = self.create_file_transfer_item(tm)
if accepted:
self._file_transfers[(friend_number, file_number)].set_state_changed_handler(item.update)
self._file_transfers[(friend_number, file_number)].set_state_changed_handler(item.update_transfer_state)
self._messages.scrollToBottom()
else:
friend.actions = True
@ -1025,7 +1024,7 @@ class Profile(basecontact.BaseContact, Singleton):
self._file_transfers[(friend_number, file_number)] = rt
self._tox.file_control(friend_number, file_number, TOX_FILE_CONTROL['RESUME'])
if item is not None:
rt.set_state_changed_handler(item.update)
rt.set_state_changed_handler(item.update_transfer_state)
self.get_friend_by_number(friend_number).update_transfer_data(file_number,
TOX_FILE_TRANSFER_STATE['RUNNING'])
@ -1064,7 +1063,7 @@ class Profile(basecontact.BaseContact, Singleton):
st.get_file_number())
item = self.create_file_transfer_item(tm)
friend.append_message(tm)
st.set_state_changed_handler(item.update)
st.set_state_changed_handler(item.update_transfer_state)
self._messages.scrollToBottom()
def send_file(self, path, number=None, is_resend=False, file_id=None):
@ -1097,7 +1096,7 @@ class Profile(basecontact.BaseContact, Singleton):
st.get_file_number())
if friend_number == self.get_active_number():
item = self.create_file_transfer_item(tm)
st.set_state_changed_handler(item.update)
st.set_state_changed_handler(item.update_transfer_state)
self._messages.scrollToBottom()
self._contacts[friend_number].append_message(tm)
@ -1113,7 +1112,6 @@ class Profile(basecontact.BaseContact, Singleton):
"""
self._file_transfers[(friend_number, file_number)].send_chunk(position, size)
@QtCore.Slot(int, int)
def transfer_finished(self, friend_number, file_number):
transfer = self._file_transfers[(friend_number, file_number)]
t = type(transfer)
@ -1130,7 +1128,7 @@ class Profile(basecontact.BaseContact, Singleton):
if friend_number == self.get_active_number():
count = self._messages.count()
if count + i + 1 >= 0:
elem = QtGui.QListWidgetItem()
elem = QtWidgets.QListWidgetItem()
item = InlineImageItem(transfer.get_data(), self._messages.width(), elem)
elem.setSizeHint(QtCore.QSize(self._messages.width(), item.height()))
self._messages.insertItem(count + i + 1, elem)
@ -1200,11 +1198,9 @@ class Profile(basecontact.BaseContact, Singleton):
self._call(num, audio, video)
self._screen.active_call()
if video:
text = QtGui.QApplication.translate("incoming_call", "Outgoing video call", None,
QtGui.QApplication.UnicodeUTF8)
text = QtWidgets.QApplication.translate("incoming_call", "Outgoing video call")
else:
text = QtGui.QApplication.translate("incoming_call", "Outgoing audio call", None,
QtGui.QApplication.UnicodeUTF8)
text = QtWidgets.QApplication.translate("incoming_call", "Outgoing audio call")
self.get_curr_friend().append_message(InfoMessage(text, time.time()))
self.create_message_item(text, time.time(), '', MESSAGE_TYPE['INFO_MESSAGE'])
self._messages.scrollToBottom()
@ -1219,11 +1215,9 @@ class Profile(basecontact.BaseContact, Singleton):
return
friend = self.get_friend_by_number(friend_number)
if video:
text = QtGui.QApplication.translate("incoming_call", "Incoming video call", None,
QtGui.QApplication.UnicodeUTF8)
text = QtWidgets.QApplication.translate("incoming_call", "Incoming video call")
else:
text = QtGui.QApplication.translate("incoming_call", "Incoming audio call", None,
QtGui.QApplication.UnicodeUTF8)
text = QtWidgets.QApplication.translate("incoming_call", "Incoming audio call")
friend.append_message(InfoMessage(text, time.time()))
self._incoming_calls.add(friend_number)
if friend_number == self.get_active_number():
@ -1254,9 +1248,9 @@ class Profile(basecontact.BaseContact, Singleton):
"""
if friend_number in self._incoming_calls:
self._incoming_calls.remove(friend_number)
text = QtGui.QApplication.translate("incoming_call", "Call declined", None, QtGui.QApplication.UnicodeUTF8)
text = QtWidgets.QApplication.translate("incoming_call", "Call declined")
else:
text = QtGui.QApplication.translate("incoming_call", "Call finished", None, QtGui.QApplication.UnicodeUTF8)
text = QtWidgets.QApplication.translate("incoming_call", "Call finished")
self._screen.call_finished()
self._call.finish_call(friend_number, by_friend) # finish or decline call
if hasattr(self, '_call_widget'):

View File

@ -35,6 +35,7 @@ class Settings(dict, Singleton):
smileys.SmileyLoader(self)
self.locked = False
self.closing = False
self.unlockScreen = False
p = pyaudio.PyAudio()
input_devices = output_devices = 0
for i in range(p.get_device_count()):
@ -49,7 +50,7 @@ class Settings(dict, Singleton):
@staticmethod
def get_auto_profile():
p = Settings.get_default_path() + 'toxygen.json'
p = Settings.get_global_settings_path()
if os.path.isfile(p):
with open(p) as fl:
data = fl.read()
@ -60,7 +61,7 @@ class Settings(dict, Singleton):
@staticmethod
def set_auto_profile(path, name):
p = Settings.get_default_path() + 'toxygen.json'
p = Settings.get_global_settings_path()
if os.path.isfile(p):
with open(p) as fl:
data = fl.read()
@ -74,7 +75,7 @@ class Settings(dict, Singleton):
@staticmethod
def reset_auto_profile():
p = Settings.get_default_path() + 'toxygen.json'
p = Settings.get_global_settings_path()
if os.path.isfile(p):
with open(p) as fl:
data = fl.read()
@ -89,15 +90,8 @@ class Settings(dict, Singleton):
@staticmethod
def is_active_profile(path, name):
path = path + name + '.tox'
settings = Settings.get_default_path() + 'toxygen.json'
if os.path.isfile(settings):
with open(settings) as fl:
data = fl.read()
data = json.loads(data)
if 'active_profile' in data:
return path in data['active_profile']
return False
path = path + name + '.lock'
return os.path.isfile(path)
@staticmethod
def get_default_settings():
@ -176,37 +170,19 @@ class Settings(dict, Singleton):
fl.write(text)
def close(self):
path = Settings.get_default_path() + 'toxygen.json'
profile_path = ProfileHelper.get_path()
path = str(profile_path + str(self.name) + '.lock')
if os.path.isfile(path):
with open(path) as fl:
data = fl.read()
app_settings = json.loads(data)
try:
app_settings['active_profile'].remove(str(ProfileHelper.get_path() + self.name + '.tox'))
except:
pass
data = json.dumps(app_settings)
with open(path, 'w') as fl:
fl.write(data)
os.remove(path)
def set_active_profile(self):
"""
Mark current profile as active
"""
path = Settings.get_default_path() + 'toxygen.json'
if os.path.isfile(path):
with open(path) as fl:
data = fl.read()
app_settings = json.loads(data)
else:
app_settings = {}
if 'active_profile' not in app_settings:
app_settings['active_profile'] = []
profile_path = ProfileHelper.get_path()
app_settings['active_profile'].append(str(profile_path + str(self.name) + '.tox'))
data = json.dumps(app_settings)
path = str(profile_path + str(self.name) + '.lock')
with open(path, 'w') as fl:
fl.write(data)
fl.write('active')
def export(self, path):
text = json.dumps(self)
@ -216,6 +192,10 @@ class Settings(dict, Singleton):
def update_path(self):
self.path = ProfileHelper.get_path() + self.name + '.json'
@staticmethod
def get_global_settings_path():
return curr_directory() + '/toxygen.json'
@staticmethod
def get_default_path():
if system() == 'Windows':

View File

@ -2,10 +2,7 @@ import util
import json
import os
from collections import OrderedDict
try:
from PySide import QtCore
except ImportError:
from PyQt4 import QtCore
from PyQt5 import QtCore
class SmileyLoader(util.Singleton):

View File

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
try:
from PySide import QtCore
from PyQt5 import QtCore
except ImportError:
from PyQt4 import QtCore

View File

@ -2,10 +2,7 @@ import json
import urllib.request
from util import log
import settings
try:
from PySide import QtNetwork, QtCore
except:
from PyQt4 import QtNetwork, QtCore
from PyQt5 import QtNetwork, QtCore
def tox_dns(email):

View File

@ -84,98 +84,98 @@ can produce IP leak</source>
<context>
<name>MainWindow</name>
<message>
<location filename="mainscreen.py" line="118"/>
<location filename="mainscreen.py" line="123"/>
<source>Profile</source>
<translation></translation>
</message>
<message>
<location filename="mainscreen.py" line="124"/>
<location filename="mainscreen.py" line="129"/>
<source>Settings</source>
<translation></translation>
</message>
<message>
<location filename="mainscreen.py" line="414"/>
<location filename="mainscreen.py" line="426"/>
<source>About</source>
<translation></translation>
</message>
<message>
<location filename="mainscreen.py" line="117"/>
<location filename="mainscreen.py" line="122"/>
<source>Add contact</source>
<translation></translation>
</message>
<message>
<location filename="mainscreen.py" line="119"/>
<location filename="mainscreen.py" line="124"/>
<source>Privacy</source>
<translation></translation>
</message>
<message>
<location filename="mainscreen.py" line="120"/>
<location filename="mainscreen.py" line="125"/>
<source>Interface</source>
<translation></translation>
</message>
<message>
<location filename="mainscreen.py" line="121"/>
<location filename="mainscreen.py" line="126"/>
<source>Notifications</source>
<translation></translation>
</message>
<message>
<location filename="mainscreen.py" line="122"/>
<location filename="mainscreen.py" line="127"/>
<source>Network</source>
<translation></translation>
</message>
<message>
<location filename="mainscreen.py" line="123"/>
<location filename="mainscreen.py" line="128"/>
<source>About program</source>
<translation></translation>
</message>
<message>
<location filename="profile.py" line="816"/>
<location filename="profile.py" line="829"/>
<source>User {} wants to add you to contact list. Message:
{}</source>
<translation></translation>
</message>
<message>
<location filename="profile.py" line="818"/>
<location filename="profile.py" line="831"/>
<source>Friend request</source>
<translation></translation>
</message>
<message>
<location filename="mainscreen.py" line="509"/>
<location filename="mainscreen.py" line="528"/>
<source>Choose file</source>
<translation>Choose file</translation>
</message>
<message>
<location filename="mainscreen.py" line="574"/>
<location filename="mainscreen.py" line="593"/>
<source>Disallow auto accept</source>
<translation></translation>
</message>
<message>
<location filename="mainscreen.py" line="575"/>
<location filename="mainscreen.py" line="594"/>
<source>Allow auto accept</source>
<translation></translation>
</message>
<message>
<location filename="mainscreen.py" line="577"/>
<location filename="mainscreen.py" line="596"/>
<source>Set alias</source>
<translation></translation>
</message>
<message>
<location filename="mainscreen.py" line="580"/>
<location filename="mainscreen.py" line="599"/>
<source>Clear history</source>
<translation></translation>
</message>
<message>
<location filename="mainscreen.py" line="590"/>
<location filename="mainscreen.py" line="609"/>
<source>Remove friend</source>
<translation></translation>
</message>
<message>
<location filename="profile.py" line="655"/>
<location filename="profile.py" line="668"/>
<source>Enter new alias for friend {} or leave empty to use friend&apos;s name:</source>
<translation>Enter new alias for friend {} or leave empty to use friend&apos;s name:</translation>
</message>
<message>
<location filename="mainscreen.py" line="125"/>
<location filename="mainscreen.py" line="130"/>
<source>Audio</source>
<translation>Audio</translation>
</message>
@ -185,24 +185,24 @@ can produce IP leak</source>
<translation type="obsolete">Find contact</translation>
</message>
<message>
<location filename="profile.py" line="788"/>
<location filename="profile.py" line="801"/>
<source>Friend added</source>
<translation>Friend added</translation>
</message>
<message>
<location filename="mainscreen.py" line="415"/>
<location filename="mainscreen.py" line="427"/>
<source>Toxygen is Tox client written on Python.
Version: </source>
<translation>Toxygen is Tox client written on Python.
Version:</translation>
</message>
<message>
<location filename="profile.py" line="789"/>
<location filename="profile.py" line="802"/>
<source>Friend added without sending friend request</source>
<translation>Friend added without sending friend request</translation>
</message>
<message>
<location filename="mainscreen.py" line="632"/>
<location filename="mainscreen.py" line="655"/>
<source>Choose folder</source>
<translation>Choose folder</translation>
</message>
@ -217,47 +217,47 @@ Version:</translation>
<translation type="obsolete">Send file</translation>
</message>
<message>
<location filename="mainscreen.py" line="128"/>
<location filename="mainscreen.py" line="133"/>
<source>Send message</source>
<translation>Send message</translation>
</message>
<message>
<location filename="mainscreen.py" line="129"/>
<location filename="mainscreen.py" line="134"/>
<source>Start audio call with friend</source>
<translation>Start audio call with friend</translation>
</message>
<message>
<location filename="mainscreen.py" line="595"/>
<location filename="mainscreen.py" line="617"/>
<source>Plugins</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="113"/>
<location filename="mainscreen.py" line="118"/>
<source>List of plugins</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="127"/>
<location filename="mainscreen_widgets.py" line="462"/>
<source>Search</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="131"/>
<location filename="mainscreen.py" line="136"/>
<source>All</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="132"/>
<location filename="mainscreen.py" line="137"/>
<source>Online</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="591"/>
<location filename="mainscreen.py" line="611"/>
<source>Notes</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="616"/>
<location filename="mainscreen.py" line="639"/>
<source>Notes about user</source>
<translation type="unfinished"></translation>
</message>
@ -307,42 +307,42 @@ Version:</translation>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="profile.py" line="303"/>
<location filename="profile.py" line="315"/>
<source>User {} is now known as {}</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="list_items.py" line="167"/>
<location filename="list_items.py" line="168"/>
<source>Delete message</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="111"/>
<location filename="mainscreen.py" line="116"/>
<source>Lock</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="482"/>
<location filename="mainscreen.py" line="501"/>
<source>Cannot lock app</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="485"/>
<location filename="mainscreen.py" line="504"/>
<source>Error. Profile password is not set.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="585"/>
<location filename="mainscreen.py" line="604"/>
<source>Name</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="586"/>
<location filename="mainscreen.py" line="605"/>
<source>Status message</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="587"/>
<location filename="mainscreen.py" line="606"/>
<source>Public key</source>
<translation type="unfinished"></translation>
</message>
@ -367,65 +367,85 @@ Version:</translation>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="140"/>
<location filename="mainscreen.py" line="145"/>
<source>Import plugin</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="460"/>
<location filename="mainscreen.py" line="479"/>
<source>Choose folder with plugin</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="469"/>
<location filename="mainscreen.py" line="488"/>
<source>Restart Toxygen</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="472"/>
<location filename="mainscreen.py" line="491"/>
<source>Plugin will be loaded after restart</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="list_items.py" line="48"/>
<location filename="list_items.py" line="49"/>
<source>Quote selected text</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="579"/>
<location filename="mainscreen.py" line="598"/>
<source>Chat history</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="581"/>
<location filename="mainscreen.py" line="600"/>
<source>Export as text</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="582"/>
<location filename="mainscreen.py" line="601"/>
<source>Export as HTML</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="126"/>
<location filename="mainscreen.py" line="131"/>
<source>Updates</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="133"/>
<location filename="mainscreen.py" line="138"/>
<source>Online first</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="135"/>
<location filename="mainscreen.py" line="140"/>
<source>Online and by name</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="136"/>
<location filename="mainscreen.py" line="141"/>
<source>Online first and by name</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="610"/>
<source>Block friend</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen_widgets.py" line="528"/>
<source>Not found</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen_widgets.py" line="524"/>
<source>Text &quot;{}&quot; was not found</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="146"/>
<source>Reload plugins</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>MenuWindow</name>
@ -758,30 +778,25 @@ Version:</translation>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen_widgets.py" line="374"/>
<location filename="mainscreen_widgets.py" line="370"/>
<source>Toxygen supports faux offline messages and file transfers. Send message or file to offline friend and he will get it later.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen_widgets.py" line="386"/>
<location filename="mainscreen_widgets.py" line="382"/>
<source>Set new NoSpam to avoid spam friend requests: Profile -&gt; Settings -&gt; Set new NoSpam.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen_widgets.py" line="378"/>
<location filename="mainscreen_widgets.py" line="374"/>
<source>Delete single message in chat: make right click on spinner or message time and choose &quot;Delete&quot; in menu</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen_widgets.py" line="382"/>
<location filename="mainscreen_widgets.py" line="378"/>
<source>Use right click on inline image to save it</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen_widgets.py" line="370"/>
<source>New in Toxygen v0.2.6:&lt;br&gt;Updater&lt;br&gt;Better contact sorting&lt;br&gt;Plugins improvements</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>audioSettingsForm</name>
@ -804,32 +819,32 @@ Version:</translation>
<context>
<name>incoming_call</name>
<message>
<location filename="profile.py" line="1214"/>
<location filename="profile.py" line="1229"/>
<source>Incoming video call</source>
<translation>Incoming video call</translation>
</message>
<message>
<location filename="profile.py" line="1217"/>
<location filename="profile.py" line="1232"/>
<source>Incoming audio call</source>
<translation>Incoming audio call</translation>
</message>
<message>
<location filename="profile.py" line="1195"/>
<location filename="profile.py" line="1210"/>
<source>Outgoing video call</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="profile.py" line="1198"/>
<location filename="profile.py" line="1213"/>
<source>Outgoing audio call</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="profile.py" line="1248"/>
<location filename="profile.py" line="1263"/>
<source>Call declined</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="profile.py" line="1250"/>
<location filename="profile.py" line="1265"/>
<source>Call finished</source>
<translation type="unfinished"></translation>
</message>
@ -985,7 +1000,7 @@ Version:</translation>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="main.py" line="288"/>
<location filename="main.py" line="290"/>
<source>Update for Toxygen was found. Download and install it?</source>
<translation type="unfinished"></translation>
</message>
@ -1122,32 +1137,32 @@ Version:</translation>
<context>
<name>tray</name>
<message>
<location filename="main.py" line="228"/>
<location filename="main.py" line="229"/>
<source>Open Toxygen</source>
<translation></translation>
</message>
<message>
<location filename="main.py" line="237"/>
<location filename="main.py" line="238"/>
<source>Exit</source>
<translation></translation>
</message>
<message>
<location filename="main.py" line="229"/>
<location filename="main.py" line="230"/>
<source>Set status</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="main.py" line="230"/>
<location filename="main.py" line="231"/>
<source>Online</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="main.py" line="231"/>
<location filename="main.py" line="232"/>
<source>Away</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="main.py" line="232"/>
<location filename="main.py" line="233"/>
<source>Busy</source>
<translation type="unfinished"></translation>
</message>

View File

@ -84,58 +84,58 @@ can produce IP leak</source>
<context>
<name>MainWindow</name>
<message>
<location filename="mainscreen.py" line="118"/>
<location filename="mainscreen.py" line="123"/>
<source>Profile</source>
<translation>Profile</translation>
</message>
<message>
<location filename="mainscreen.py" line="124"/>
<location filename="mainscreen.py" line="129"/>
<source>Settings</source>
<translation>Paramêtres</translation>
</message>
<message>
<location filename="mainscreen.py" line="414"/>
<location filename="mainscreen.py" line="426"/>
<source>About</source>
<translation>À Propos</translation>
</message>
<message>
<location filename="mainscreen.py" line="117"/>
<location filename="mainscreen.py" line="122"/>
<source>Add contact</source>
<translation>Rajouter un contact</translation>
</message>
<message>
<location filename="mainscreen.py" line="119"/>
<location filename="mainscreen.py" line="124"/>
<source>Privacy</source>
<translation>Confidentialité</translation>
</message>
<message>
<location filename="mainscreen.py" line="120"/>
<location filename="mainscreen.py" line="125"/>
<source>Interface</source>
<translation>Interface</translation>
</message>
<message>
<location filename="mainscreen.py" line="121"/>
<location filename="mainscreen.py" line="126"/>
<source>Notifications</source>
<translation>Notifications</translation>
</message>
<message>
<location filename="mainscreen.py" line="122"/>
<location filename="mainscreen.py" line="127"/>
<source>Network</source>
<translation>Réseau</translation>
</message>
<message>
<location filename="mainscreen.py" line="123"/>
<location filename="mainscreen.py" line="128"/>
<source>About program</source>
<translation>À propos du programme</translation>
</message>
<message>
<location filename="profile.py" line="816"/>
<location filename="profile.py" line="829"/>
<source>User {} wants to add you to contact list. Message:
{}</source>
<translation>L&apos;Utilisateur {} veut vout rajouter à sa liste de contacts. Message : {}</translation>
</message>
<message>
<location filename="profile.py" line="818"/>
<location filename="profile.py" line="831"/>
<source>Friend request</source>
<translation>Demande d&apos;amis</translation>
</message>
@ -145,27 +145,27 @@ can produce IP leak</source>
<translation type="obsolete">Toxygen est un client Tox écris en Python 2.7. Version : </translation>
</message>
<message>
<location filename="mainscreen.py" line="509"/>
<location filename="mainscreen.py" line="528"/>
<source>Choose file</source>
<translation>Choisir un fichier</translation>
</message>
<message>
<location filename="mainscreen.py" line="574"/>
<location filename="mainscreen.py" line="593"/>
<source>Disallow auto accept</source>
<translation>Désactiver l&apos;auto-réception</translation>
</message>
<message>
<location filename="mainscreen.py" line="575"/>
<location filename="mainscreen.py" line="594"/>
<source>Allow auto accept</source>
<translation>Activer l&apos;auto-réception</translation>
</message>
<message>
<location filename="mainscreen.py" line="577"/>
<location filename="mainscreen.py" line="596"/>
<source>Set alias</source>
<translation>Définir un alias</translation>
</message>
<message>
<location filename="mainscreen.py" line="580"/>
<location filename="mainscreen.py" line="599"/>
<source>Clear history</source>
<translation>Vider l&apos;historique</translation>
</message>
@ -175,17 +175,17 @@ can produce IP leak</source>
<translation type="obsolete">Copier la clé publique</translation>
</message>
<message>
<location filename="mainscreen.py" line="590"/>
<location filename="mainscreen.py" line="609"/>
<source>Remove friend</source>
<translation>Retirer un ami</translation>
</message>
<message>
<location filename="profile.py" line="655"/>
<location filename="profile.py" line="668"/>
<source>Enter new alias for friend {} or leave empty to use friend&apos;s name:</source>
<translation>Entrez un nouvel alias pour l&apos;ami {} ou laissez vide pour garder son nom de base :</translation>
</message>
<message>
<location filename="mainscreen.py" line="125"/>
<location filename="mainscreen.py" line="130"/>
<source>Audio</source>
<translation>Audio</translation>
</message>
@ -195,24 +195,24 @@ can produce IP leak</source>
<translation type="obsolete">Trouver le contact</translation>
</message>
<message>
<location filename="profile.py" line="788"/>
<location filename="profile.py" line="801"/>
<source>Friend added</source>
<translation>Ami rajouté</translation>
</message>
<message>
<location filename="mainscreen.py" line="415"/>
<location filename="mainscreen.py" line="427"/>
<source>Toxygen is Tox client written on Python.
Version: </source>
<translation>Toxygen est un client Tox écrit en Python.
Version :</translation>
</message>
<message>
<location filename="profile.py" line="789"/>
<location filename="profile.py" line="802"/>
<source>Friend added without sending friend request</source>
<translation>Ami rajouté sans avoir envoyé de demande</translation>
</message>
<message>
<location filename="mainscreen.py" line="632"/>
<location filename="mainscreen.py" line="655"/>
<source>Choose folder</source>
<translation>Choisir le dossier</translation>
</message>
@ -227,47 +227,47 @@ Version :</translation>
<translation type="obsolete">Envoyer le fichier</translation>
</message>
<message>
<location filename="mainscreen.py" line="128"/>
<location filename="mainscreen.py" line="133"/>
<source>Send message</source>
<translation>Envoyer le message</translation>
</message>
<message>
<location filename="mainscreen.py" line="129"/>
<location filename="mainscreen.py" line="134"/>
<source>Start audio call with friend</source>
<translation>Lancer un appel audio avec un ami</translation>
</message>
<message>
<location filename="mainscreen.py" line="595"/>
<location filename="mainscreen.py" line="617"/>
<source>Plugins</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="113"/>
<location filename="mainscreen.py" line="118"/>
<source>List of plugins</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="127"/>
<location filename="mainscreen_widgets.py" line="462"/>
<source>Search</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="131"/>
<location filename="mainscreen.py" line="136"/>
<source>All</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="132"/>
<location filename="mainscreen.py" line="137"/>
<source>Online</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="591"/>
<location filename="mainscreen.py" line="611"/>
<source>Notes</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="616"/>
<location filename="mainscreen.py" line="639"/>
<source>Notes about user</source>
<translation type="unfinished"></translation>
</message>
@ -317,42 +317,42 @@ Version :</translation>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="profile.py" line="303"/>
<location filename="profile.py" line="315"/>
<source>User {} is now known as {}</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="list_items.py" line="167"/>
<location filename="list_items.py" line="168"/>
<source>Delete message</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="111"/>
<location filename="mainscreen.py" line="116"/>
<source>Lock</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="482"/>
<location filename="mainscreen.py" line="501"/>
<source>Cannot lock app</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="485"/>
<location filename="mainscreen.py" line="504"/>
<source>Error. Profile password is not set.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="585"/>
<location filename="mainscreen.py" line="604"/>
<source>Name</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="586"/>
<location filename="mainscreen.py" line="605"/>
<source>Status message</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="587"/>
<location filename="mainscreen.py" line="606"/>
<source>Public key</source>
<translation type="unfinished"></translation>
</message>
@ -377,65 +377,85 @@ Version :</translation>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="140"/>
<location filename="mainscreen.py" line="145"/>
<source>Import plugin</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="460"/>
<location filename="mainscreen.py" line="479"/>
<source>Choose folder with plugin</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="469"/>
<location filename="mainscreen.py" line="488"/>
<source>Restart Toxygen</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="472"/>
<location filename="mainscreen.py" line="491"/>
<source>Plugin will be loaded after restart</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="list_items.py" line="48"/>
<location filename="list_items.py" line="49"/>
<source>Quote selected text</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="579"/>
<location filename="mainscreen.py" line="598"/>
<source>Chat history</source>
<translation type="unfinished">Historique de chat</translation>
</message>
<message>
<location filename="mainscreen.py" line="581"/>
<location filename="mainscreen.py" line="600"/>
<source>Export as text</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="582"/>
<location filename="mainscreen.py" line="601"/>
<source>Export as HTML</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="126"/>
<location filename="mainscreen.py" line="131"/>
<source>Updates</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="133"/>
<location filename="mainscreen.py" line="138"/>
<source>Online first</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="135"/>
<location filename="mainscreen.py" line="140"/>
<source>Online and by name</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="136"/>
<location filename="mainscreen.py" line="141"/>
<source>Online first and by name</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="610"/>
<source>Block friend</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen_widgets.py" line="528"/>
<source>Not found</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen_widgets.py" line="524"/>
<source>Text &quot;{}&quot; was not found</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen.py" line="146"/>
<source>Reload plugins</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>MenuWindow</name>
@ -768,30 +788,25 @@ Version :</translation>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen_widgets.py" line="374"/>
<location filename="mainscreen_widgets.py" line="370"/>
<source>Toxygen supports faux offline messages and file transfers. Send message or file to offline friend and he will get it later.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen_widgets.py" line="386"/>
<location filename="mainscreen_widgets.py" line="382"/>
<source>Set new NoSpam to avoid spam friend requests: Profile -&gt; Settings -&gt; Set new NoSpam.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen_widgets.py" line="378"/>
<location filename="mainscreen_widgets.py" line="374"/>
<source>Delete single message in chat: make right click on spinner or message time and choose &quot;Delete&quot; in menu</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen_widgets.py" line="382"/>
<location filename="mainscreen_widgets.py" line="378"/>
<source>Use right click on inline image to save it</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainscreen_widgets.py" line="370"/>
<source>New in Toxygen v0.2.6:&lt;br&gt;Updater&lt;br&gt;Better contact sorting&lt;br&gt;Plugins improvements</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>audioSettingsForm</name>
@ -814,32 +829,32 @@ Version :</translation>
<context>
<name>incoming_call</name>
<message>
<location filename="profile.py" line="1214"/>
<location filename="profile.py" line="1229"/>
<source>Incoming video call</source>
<translation>Appel vidéo entrant</translation>
</message>
<message>
<location filename="profile.py" line="1217"/>
<location filename="profile.py" line="1232"/>
<source>Incoming audio call</source>
<translation>Appel audio entrant</translation>
</message>
<message>
<location filename="profile.py" line="1195"/>
<location filename="profile.py" line="1210"/>
<source>Outgoing video call</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="profile.py" line="1198"/>
<location filename="profile.py" line="1213"/>
<source>Outgoing audio call</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="profile.py" line="1248"/>
<location filename="profile.py" line="1263"/>
<source>Call declined</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="profile.py" line="1250"/>
<location filename="profile.py" line="1265"/>
<source>Call finished</source>
<translation type="unfinished"></translation>
</message>
@ -1000,7 +1015,7 @@ Version :</translation>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="main.py" line="288"/>
<location filename="main.py" line="290"/>
<source>Update for Toxygen was found. Download and install it?</source>
<translation type="unfinished"></translation>
</message>
@ -1137,32 +1152,32 @@ Version :</translation>
<context>
<name>tray</name>
<message>
<location filename="main.py" line="228"/>
<location filename="main.py" line="229"/>
<source>Open Toxygen</source>
<translation>Ouvrir Toxygen</translation>
</message>
<message>
<location filename="main.py" line="237"/>
<location filename="main.py" line="238"/>
<source>Exit</source>
<translation>Quitter</translation>
</message>
<message>
<location filename="main.py" line="229"/>
<location filename="main.py" line="230"/>
<source>Set status</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="main.py" line="230"/>
<location filename="main.py" line="231"/>
<source>Online</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="main.py" line="231"/>
<location filename="main.py" line="232"/>
<source>Away</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="main.py" line="232"/>
<location filename="main.py" line="233"/>
<source>Busy</source>
<translation type="unfinished"></translation>
</message>

Binary file not shown.

View File

@ -87,84 +87,84 @@ can produce IP leak</source>
<context>
<name>MainWindow</name>
<message>
<location filename="mainscreen.py" line="118"/>
<location filename="mainscreen.py" line="123"/>
<source>Profile</source>
<translation>Профиль</translation>
</message>
<message>
<location filename="mainscreen.py" line="124"/>
<location filename="mainscreen.py" line="129"/>
<source>Settings</source>
<translation>Настройки</translation>
</message>
<message>
<location filename="mainscreen.py" line="414"/>
<location filename="mainscreen.py" line="426"/>
<source>About</source>
<translation>О программе</translation>
</message>
<message>
<location filename="mainscreen.py" line="117"/>
<location filename="mainscreen.py" line="122"/>
<source>Add contact</source>
<translation>Добавить контакт</translation>
</message>
<message>
<location filename="mainscreen.py" line="119"/>
<location filename="mainscreen.py" line="124"/>
<source>Privacy</source>
<translation>Приватность</translation>
</message>
<message>
<location filename="mainscreen.py" line="120"/>
<location filename="mainscreen.py" line="125"/>
<source>Interface</source>
<translation>Интерфейс</translation>
</message>
<message>
<location filename="mainscreen.py" line="121"/>
<location filename="mainscreen.py" line="126"/>
<source>Notifications</source>
<translation>Уведомления</translation>
</message>
<message>
<location filename="mainscreen.py" line="122"/>
<location filename="mainscreen.py" line="127"/>
<source>Network</source>
<translation>Сеть</translation>
</message>
<message>
<location filename="mainscreen.py" line="123"/>
<location filename="mainscreen.py" line="128"/>
<source>About program</source>
<translation>О программе</translation>
</message>
<message>
<location filename="profile.py" line="816"/>
<location filename="profile.py" line="829"/>
<source>User {} wants to add you to contact list. Message:
{}</source>
<translation>Пользователь {} хочет добавить Вас в список контактов. Сообщение:
{}</translation>
</message>
<message>
<location filename="profile.py" line="818"/>
<location filename="profile.py" line="831"/>
<source>Friend request</source>
<translation>Запрос на добавление в друзья</translation>
</message>
<message>
<location filename="mainscreen.py" line="509"/>
<location filename="mainscreen.py" line="528"/>
<source>Choose file</source>
<translation>Выберите файл</translation>
</message>
<message>
<location filename="mainscreen.py" line="574"/>
<location filename="mainscreen.py" line="593"/>
<source>Disallow auto accept</source>
<translation>Запретить автоматическое получение файлов</translation>
</message>
<message>
<location filename="mainscreen.py" line="575"/>
<location filename="mainscreen.py" line="594"/>
<source>Allow auto accept</source>
<translation>Разрешить автоматическое получение файлов</translation>
</message>
<message>
<location filename="mainscreen.py" line="577"/>
<location filename="mainscreen.py" line="596"/>
<source>Set alias</source>
<translation>Изменить псевдоним</translation>
</message>
<message>
<location filename="mainscreen.py" line="580"/>
<location filename="mainscreen.py" line="599"/>
<source>Clear history</source>
<translation>Очистить историю</translation>
</message>
@ -174,17 +174,17 @@ can produce IP leak</source>
<translation type="obsolete">Копировать публичный ключ</translation>
</message>
<message>
<location filename="mainscreen.py" line="590"/>
<location filename="mainscreen.py" line="609"/>
<source>Remove friend</source>
<translation>Удалить друга</translation>
</message>
<message>
<location filename="profile.py" line="655"/>
<location filename="profile.py" line="668"/>
<source>Enter new alias for friend {} or leave empty to use friend&apos;s name:</source>
<translation>Введите новый псевдоним для друга {} или оставьте пустым для использования его имени:</translation>
</message>
<message>
<location filename="mainscreen.py" line="125"/>
<location filename="mainscreen.py" line="130"/>
<source>Audio</source>
<translation>Аудио</translation>
</message>
@ -194,23 +194,23 @@ can produce IP leak</source>
<translation type="obsolete">Найти контакт</translation>
</message>
<message>
<location filename="profile.py" line="788"/>
<location filename="profile.py" line="801"/>
<source>Friend added</source>
<translation>Друг добавлен</translation>
</message>
<message>
<location filename="mainscreen.py" line="415"/>
<location filename="mainscreen.py" line="427"/>
<source>Toxygen is Tox client written on Python.
Version: </source>
<translation>Toxygen - клиент для мессенджера Tox, написанный на Python. Версия: </translation>
</message>
<message>
<location filename="profile.py" line="789"/>
<location filename="profile.py" line="802"/>
<source>Friend added without sending friend request</source>
<translation>Друг добавлен без отправки запроса на добавление в друзья</translation>
</message>
<message>
<location filename="mainscreen.py" line="632"/>
<location filename="mainscreen.py" line="655"/>
<source>Choose folder</source>
<translation>Выбрать папку</translation>
</message>
@ -225,47 +225,47 @@ Version: </source>
<translation type="obsolete">Отправить файл</translation>
</message>
<message>
<location filename="mainscreen.py" line="128"/>
<location filename="mainscreen.py" line="133"/>
<source>Send message</source>
<translation>Отправить сообщение</translation>
</message>
<message>
<location filename="mainscreen.py" line="129"/>
<location filename="mainscreen.py" line="134"/>
<source>Start audio call with friend</source>
<translation>Начать аудиозвонок с другом</translation>
</message>
<message>
<location filename="mainscreen.py" line="595"/>
<location filename="mainscreen.py" line="617"/>
<source>Plugins</source>
<translation>Плагины</translation>
</message>
<message>
<location filename="mainscreen.py" line="113"/>
<location filename="mainscreen.py" line="118"/>
<source>List of plugins</source>
<translation>Список плагинов</translation>
</message>
<message>
<location filename="mainscreen.py" line="127"/>
<location filename="mainscreen_widgets.py" line="462"/>
<source>Search</source>
<translation>Поиск</translation>
</message>
<message>
<location filename="mainscreen.py" line="131"/>
<location filename="mainscreen.py" line="136"/>
<source>All</source>
<translation>Все</translation>
</message>
<message>
<location filename="mainscreen.py" line="132"/>
<location filename="mainscreen.py" line="137"/>
<source>Online</source>
<translation>Онлайн</translation>
</message>
<message>
<location filename="mainscreen.py" line="591"/>
<location filename="mainscreen.py" line="611"/>
<source>Notes</source>
<translation>Заметки</translation>
</message>
<message>
<location filename="mainscreen.py" line="616"/>
<location filename="mainscreen.py" line="639"/>
<source>Notes about user</source>
<translation>Заметки о пользователе</translation>
</message>
@ -315,42 +315,42 @@ Version: </source>
<translation>Сохранить</translation>
</message>
<message>
<location filename="profile.py" line="303"/>
<location filename="profile.py" line="315"/>
<source>User {} is now known as {}</source>
<translation>Пользователь {} сейчас известен как {}</translation>
</message>
<message>
<location filename="list_items.py" line="167"/>
<location filename="list_items.py" line="168"/>
<source>Delete message</source>
<translation>Удалить сообщение</translation>
</message>
<message>
<location filename="mainscreen.py" line="111"/>
<location filename="mainscreen.py" line="116"/>
<source>Lock</source>
<translation>Заблокировать</translation>
</message>
<message>
<location filename="mainscreen.py" line="482"/>
<location filename="mainscreen.py" line="501"/>
<source>Cannot lock app</source>
<translation>Невозможно заблокировать приложение</translation>
</message>
<message>
<location filename="mainscreen.py" line="485"/>
<location filename="mainscreen.py" line="504"/>
<source>Error. Profile password is not set.</source>
<translation>Ошибка. Пароль профиля не установлен.</translation>
</message>
<message>
<location filename="mainscreen.py" line="585"/>
<location filename="mainscreen.py" line="604"/>
<source>Name</source>
<translation>Имя</translation>
</message>
<message>
<location filename="mainscreen.py" line="586"/>
<location filename="mainscreen.py" line="605"/>
<source>Status message</source>
<translation>Статус</translation>
</message>
<message>
<location filename="mainscreen.py" line="587"/>
<location filename="mainscreen.py" line="606"/>
<source>Public key</source>
<translation>Публичный ключ</translation>
</message>
@ -375,65 +375,85 @@ Version: </source>
<translation>Выберите папку с паком смайлов</translation>
</message>
<message>
<location filename="mainscreen.py" line="140"/>
<location filename="mainscreen.py" line="145"/>
<source>Import plugin</source>
<translation>Импортировать плагин</translation>
</message>
<message>
<location filename="mainscreen.py" line="460"/>
<location filename="mainscreen.py" line="479"/>
<source>Choose folder with plugin</source>
<translation>Выберите папку с плагином</translation>
</message>
<message>
<location filename="mainscreen.py" line="469"/>
<location filename="mainscreen.py" line="488"/>
<source>Restart Toxygen</source>
<translation>Перезапустите Toxygen</translation>
</message>
<message>
<location filename="mainscreen.py" line="472"/>
<location filename="mainscreen.py" line="491"/>
<source>Plugin will be loaded after restart</source>
<translation>Плагин будет загружен после перезапуска</translation>
</message>
<message>
<location filename="list_items.py" line="48"/>
<location filename="list_items.py" line="49"/>
<source>Quote selected text</source>
<translation>Цитировать выбранный текст</translation>
</message>
<message>
<location filename="mainscreen.py" line="579"/>
<location filename="mainscreen.py" line="598"/>
<source>Chat history</source>
<translation>История чата</translation>
</message>
<message>
<location filename="mainscreen.py" line="581"/>
<location filename="mainscreen.py" line="600"/>
<source>Export as text</source>
<translation>Экспортировать как текст</translation>
</message>
<message>
<location filename="mainscreen.py" line="582"/>
<location filename="mainscreen.py" line="601"/>
<source>Export as HTML</source>
<translation>Экспортировать как HTML</translation>
</message>
<message>
<location filename="mainscreen.py" line="126"/>
<location filename="mainscreen.py" line="131"/>
<source>Updates</source>
<translation>Обновления</translation>
</message>
<message>
<location filename="mainscreen.py" line="133"/>
<location filename="mainscreen.py" line="138"/>
<source>Online first</source>
<translation>Сначала онлайн</translation>
</message>
<message>
<location filename="mainscreen.py" line="135"/>
<location filename="mainscreen.py" line="140"/>
<source>Online and by name</source>
<translation>Онлайн и по имени</translation>
</message>
<message>
<location filename="mainscreen.py" line="136"/>
<location filename="mainscreen.py" line="141"/>
<source>Online first and by name</source>
<translation>Сначала онлайн и по имени</translation>
</message>
<message>
<location filename="mainscreen.py" line="610"/>
<source>Block friend</source>
<translation>Заблокировать друга</translation>
</message>
<message>
<location filename="mainscreen_widgets.py" line="528"/>
<source>Not found</source>
<translation>Не найдено</translation>
</message>
<message>
<location filename="mainscreen_widgets.py" line="524"/>
<source>Text &quot;{}&quot; was not found</source>
<translation>Текст &quot;{}&quot; не был найден</translation>
</message>
<message>
<location filename="mainscreen.py" line="146"/>
<source>Reload plugins</source>
<translation>Перезагрузить плагины</translation>
</message>
</context>
<context>
<name>MenuWindow</name>
@ -796,12 +816,12 @@ Version: </source>
<translation>Используйте Настройки -&gt; Интерфейс для настройки интерфейса.</translation>
</message>
<message>
<location filename="mainscreen_widgets.py" line="374"/>
<location filename="mainscreen_widgets.py" line="370"/>
<source>Toxygen supports faux offline messages and file transfers. Send message or file to offline friend and he will get it later.</source>
<translation>Toxygen поддерживает псевдооффлайн сообщения и файл трансферы.</translation>
</message>
<message>
<location filename="mainscreen_widgets.py" line="386"/>
<location filename="mainscreen_widgets.py" line="382"/>
<source>Set new NoSpam to avoid spam friend requests: Profile -&gt; Settings -&gt; Set new NoSpam.</source>
<translation>Установите новый NoSpam, чтобы избежать спам запросов в друзья: Профиль-&gt;Настройки-&gt;Новый NoSpam.</translation>
</message>
@ -811,12 +831,12 @@ Version: </source>
<translation type="obsolete">Новое в Toxygen 0.2.3:&lt;br&gt;Соответствие TCS&lt;br&gt;Импорт плагинов, смайлов и стикеров&lt;br&gt;Исправления ошибок</translation>
</message>
<message>
<location filename="mainscreen_widgets.py" line="378"/>
<location filename="mainscreen_widgets.py" line="374"/>
<source>Delete single message in chat: make right click on spinner or message time and choose &quot;Delete&quot; in menu</source>
<translation>Чтобы удалить отдельное сообщение в чате сделайте правый клик на спиннер или время сообщения и выберите &quot;Удалить&quot; в меню</translation>
</message>
<message>
<location filename="mainscreen_widgets.py" line="382"/>
<location filename="mainscreen_widgets.py" line="378"/>
<source>Use right click on inline image to save it</source>
<translation>Правый клик на инлайн изображении позволит сохранить его</translation>
</message>
@ -828,7 +848,7 @@ Version: </source>
<message>
<location filename="mainscreen_widgets.py" line="370"/>
<source>New in Toxygen v0.2.6:&lt;br&gt;Updater&lt;br&gt;Better contact sorting&lt;br&gt;Plugins improvements</source>
<translation>Новое в Toxygen v0.2.6:&lt;br&gt;Поддержка обновлений&lt;br&gt;Улучшенная сортировка контактов&lt;br&gt;Улучшения в работе плагинов</translation>
<translation type="obsolete">Новое в Toxygen v0.2.6:&lt;br&gt;Поддержка обновлений&lt;br&gt;Улучшенная сортировка контактов&lt;br&gt;Улучшения в работе плагинов</translation>
</message>
</context>
<context>
@ -852,32 +872,32 @@ Version: </source>
<context>
<name>incoming_call</name>
<message>
<location filename="profile.py" line="1214"/>
<location filename="profile.py" line="1229"/>
<source>Incoming video call</source>
<translation>Входящий видеозвонок</translation>
</message>
<message>
<location filename="profile.py" line="1217"/>
<location filename="profile.py" line="1232"/>
<source>Incoming audio call</source>
<translation>Входящий аудиозвонок</translation>
</message>
<message>
<location filename="profile.py" line="1195"/>
<location filename="profile.py" line="1210"/>
<source>Outgoing video call</source>
<translation>Исходящий видеозвонок</translation>
</message>
<message>
<location filename="profile.py" line="1198"/>
<location filename="profile.py" line="1213"/>
<source>Outgoing audio call</source>
<translation>Исходящий аудиозвонок</translation>
</message>
<message>
<location filename="profile.py" line="1248"/>
<location filename="profile.py" line="1263"/>
<source>Call declined</source>
<translation>Звонок отменен</translation>
</message>
<message>
<location filename="profile.py" line="1250"/>
<location filename="profile.py" line="1265"/>
<source>Call finished</source>
<translation>Звонок завершен</translation>
</message>
@ -1038,7 +1058,7 @@ Version: </source>
<translation>Ошибка сохранения профиля! Toxygen имеет разрешение на запись в данную папку?</translation>
</message>
<message>
<location filename="main.py" line="288"/>
<location filename="main.py" line="290"/>
<source>Update for Toxygen was found. Download and install it?</source>
<translation>Обновление для Toxygen было найдено. Загрузить и установить его?</translation>
</message>
@ -1077,7 +1097,7 @@ Version: </source>
<message>
<location filename="passwordscreen.py" line="65"/>
<source>Password:</source>
<translation>Пароль</translation>
<translation>Пароль:</translation>
</message>
<message>
<location filename="passwordscreen.py" line="66"/>
@ -1176,32 +1196,32 @@ Version: </source>
<context>
<name>tray</name>
<message>
<location filename="main.py" line="228"/>
<location filename="main.py" line="229"/>
<source>Open Toxygen</source>
<translation>Открыть Toxygen</translation>
</message>
<message>
<location filename="main.py" line="237"/>
<location filename="main.py" line="238"/>
<source>Exit</source>
<translation>Выход</translation>
</message>
<message>
<location filename="main.py" line="229"/>
<location filename="main.py" line="230"/>
<source>Set status</source>
<translation>Изменить статус</translation>
</message>
<message>
<location filename="main.py" line="230"/>
<location filename="main.py" line="231"/>
<source>Online</source>
<translation>Онлайн</translation>
</message>
<message>
<location filename="main.py" line="231"/>
<location filename="main.py" line="232"/>
<source>Away</source>
<translation>Нет на месте</translation>
</message>
<message>
<location filename="main.py" line="232"/>
<location filename="main.py" line="233"/>
<source>Busy</source>
<translation>Занят</translation>
</message>

View File

@ -3,10 +3,7 @@ import os
import settings
import platform
import urllib
try:
from PySide import QtNetwork, QtCore
except ImportError:
from PyQt4 import QtNetwork, QtCore
from PyQt5 import QtNetwork, QtCore
import subprocess

View File

@ -4,7 +4,7 @@ import shutil
import sys
import re
program_version = '0.2.7'
program_version = '0.2.8'
def log(data):

View File

@ -1,10 +1,7 @@
try:
from PySide import QtCore, QtGui
except ImportError:
from PyQt4 import QtCore, QtGui
from PyQt5 import QtCore, QtGui, QtWidgets
class DataLabel(QtGui.QLabel):
class DataLabel(QtWidgets.QLabel):
"""
Label with elided text
"""
@ -15,14 +12,14 @@ class DataLabel(QtGui.QLabel):
super().setText(text)
class ComboBox(QtGui.QComboBox):
class ComboBox(QtWidgets.QComboBox):
def __init__(self, *args):
super().__init__(*args)
self.view().setSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.Expanding)
self.view().setSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Expanding)
class CenteredWidget(QtGui.QWidget):
class CenteredWidget(QtWidgets.QWidget):
def __init__(self):
super(CenteredWidget, self).__init__()
@ -30,12 +27,12 @@ class CenteredWidget(QtGui.QWidget):
def center(self):
qr = self.frameGeometry()
cp = QtGui.QDesktopWidget().availableGeometry().center()
cp = QtWidgets.QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.topLeft())
class LineEdit(QtGui.QLineEdit):
class LineEdit(QtWidgets.QLineEdit):
def __init__(self, parent=None):
super(LineEdit, self).__init__(parent)
@ -46,25 +43,27 @@ class LineEdit(QtGui.QLineEdit):
del menu
class QRightClickButton(QtGui.QPushButton):
class QRightClickButton(QtWidgets.QPushButton):
"""
Button with right click support
"""
rightClicked = QtCore.pyqtSignal()
def __init__(self, parent):
super(QRightClickButton, self).__init__(parent)
def mousePressEvent(self, event):
if event.button() == QtCore.Qt.RightButton:
self.emit(QtCore.SIGNAL("rightClicked()"))
self.rightClicked.emit()
else:
super(QRightClickButton, self).mousePressEvent(event)
class RubberBand(QtGui.QRubberBand):
class RubberBand(QtWidgets.QRubberBand):
def __init__(self):
super(RubberBand, self).__init__(QtGui.QRubberBand.Rectangle, None)
super(RubberBand, self).__init__(QtWidgets.QRubberBand.Rectangle, None)
self.setPalette(QtGui.QPalette(QtCore.Qt.transparent))
self.pen = QtGui.QPen(QtCore.Qt.blue, 4)
self.pen.setStyle(QtCore.Qt.SolidLine)
@ -86,29 +85,21 @@ def create_menu(menu):
text = action.text()
if 'Link Location' in text:
text = text.replace('Copy &Link Location',
QtGui.QApplication.translate("MainWindow", "Copy link location", None,
QtGui.QApplication.UnicodeUTF8))
QtWidgets.QApplication.translate("MainWindow", "Copy link location"))
elif '&Copy' in text:
text = text.replace('&Copy', QtGui.QApplication.translate("MainWindow", "Copy", None,
QtGui.QApplication.UnicodeUTF8))
text = text.replace('&Copy', QtWidgets.QApplication.translate("MainWindow", "Copy"))
elif 'All' in text:
text = text.replace('Select All', QtGui.QApplication.translate("MainWindow", "Select all", None,
QtGui.QApplication.UnicodeUTF8))
text = text.replace('Select All', QtWidgets.QApplication.translate("MainWindow", "Select all"))
elif 'Delete' in text:
text = text.replace('Delete', QtGui.QApplication.translate("MainWindow", "Delete", None,
QtGui.QApplication.UnicodeUTF8))
text = text.replace('Delete', QtWidgets.QApplication.translate("MainWindow", "Delete"))
elif '&Paste' in text:
text = text.replace('&Paste', QtGui.QApplication.translate("MainWindow", "Paste", None,
QtGui.QApplication.UnicodeUTF8))
text = text.replace('&Paste', QtWidgets.QApplication.translate("MainWindow", "Paste"))
elif 'Cu&t' in text:
text = text.replace('Cu&t', QtGui.QApplication.translate("MainWindow", "Cut", None,
QtGui.QApplication.UnicodeUTF8))
text = text.replace('Cu&t', QtWidgets.QApplication.translate("MainWindow", "Cut"))
elif '&Undo' in text:
text = text.replace('&Undo', QtGui.QApplication.translate("MainWindow", "Undo", None,
QtGui.QApplication.UnicodeUTF8))
text = text.replace('&Undo', QtWidgets.QApplication.translate("MainWindow", "Undo"))
elif '&Redo' in text:
text = text.replace('&Redo', QtGui.QApplication.translate("MainWindow", "Redo", None,
QtGui.QApplication.UnicodeUTF8))
text = text.replace('&Redo', QtWidgets.QApplication.translate("MainWindow", "Redo"))
else:
menu.removeAction(action)
continue
@ -124,12 +115,12 @@ class MultilineEdit(CenteredWidget):
self.setMinimumSize(QtCore.QSize(350, 200))
self.setMaximumSize(QtCore.QSize(350, 200))
self.setWindowTitle(title)
self.edit = QtGui.QTextEdit(self)
self.edit = QtWidgets.QTextEdit(self)
self.edit.setGeometry(QtCore.QRect(0, 0, 350, 150))
self.edit.setText(text)
self.button = QtGui.QPushButton(self)
self.button = QtWidgets.QPushButton(self)
self.button.setGeometry(QtCore.QRect(0, 150, 350, 50))
self.button.setText(QtGui.QApplication.translate("MainWindow", "Save", None, QtGui.QApplication.UnicodeUTF8))
self.button.setText(QtWidgets.QApplication.translate("MainWindow", "Save"))
self.button.clicked.connect(self.button_click)
self.center()
self.save = save