more refacrtoring - contact provider, deps creation

This commit is contained in:
ingvar1995 2018-04-26 23:54:39 +03:00
parent 68328d9846
commit a9d2d3d809
20 changed files with 500 additions and 345 deletions

View file

@ -3,9 +3,9 @@ from ui.list_items import *
class ItemsFactory:
def __init__(self, friends_list, messages):
self._friends = friends_list
self._messages = messages
def __init__(self, settings, plugin_loader, smiley_loader, main_screen):
self._settings, self._plugin_loader = settings, plugin_loader
self._smiley_loader, self._main_screen = smiley_loader, main_screen
def friend_item(self):
item = ContactItem()

View file

@ -10,208 +10,6 @@ from user_data import settings
import re
class MessageEdit(QtWidgets.QTextBrowser):
def __init__(self, text, width, message_type, parent=None):
super(MessageEdit, self).__init__(parent)
self.urls = {}
self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.setWordWrapMode(QtGui.QTextOption.WrapAtWordBoundaryOrAnywhere)
self.document().setTextWidth(width)
self.setOpenExternalLinks(True)
self.setAcceptRichText(True)
self.setOpenLinks(False)
path = smileys.SmileyLoader.get_instance().get_smileys_path()
if path is not None:
self.setSearchPaths([path])
self.document().setDefaultStyleSheet('a { color: #306EFF; }')
text = self.decoratedText(text)
if message_type != TOX_MESSAGE_TYPE['NORMAL']:
self.setHtml('<p style="color: #5CB3FF; font: italic; font-size: 20px;" >' + text + '</p>')
else:
self.setHtml(text)
font = QtGui.QFont()
font.setFamily(settings.Settings.get_instance()['font'])
font.setPixelSize(settings.Settings.get_instance()['message_font_size'])
font.setBold(False)
self.setFont(font)
self.resize(width, self.document().size().height())
self.setTextInteractionFlags(QtCore.Qt.TextSelectableByMouse | QtCore.Qt.LinksAccessibleByMouse)
self.anchorClicked.connect(self.on_anchor_clicked)
def contextMenuEvent(self, event):
menu = create_menu(self.createStandardContextMenu(event.pos()))
quote = menu.addAction(QtWidgets.QApplication.translate("MainWindow", 'Quote selected text'))
quote.triggered.connect(self.quote_text)
text = self.textCursor().selection().toPlainText()
if not text:
quote.setEnabled(False)
else:
import plugin_support
submenu = plugin_support.PluginLoader.get_instance().get_message_menu(menu, text)
if len(submenu):
plug = menu.addMenu(QtWidgets.QApplication.translate("MainWindow", 'Plugins'))
plug.addActions(submenu)
menu.popup(event.globalPos())
menu.exec_(event.globalPos())
del menu
def quote_text(self):
text = self.textCursor().selection().toPlainText()
if text:
from ui import main_screen
window = main_screen.MainWindow.get_instance()
text = '>' + '\n>'.join(text.split('\n'))
if window.messageEdit.toPlainText():
text = '\n' + text
window.messageEdit.appendPlainText(text)
def on_anchor_clicked(self, url):
text = str(url.toString())
if text.startswith('tox:'):
from ui import menu
self.add_contact = menu.AddContact(text[4:])
self.add_contact.show()
else:
QtGui.QDesktopServices.openUrl(url)
self.clearFocus()
def addAnimation(self, url, fileName):
movie = QtGui.QMovie(self)
movie.setFileName(fileName)
self.urls[movie] = url
movie.frameChanged[int].connect(lambda x: self.animate(movie))
movie.start()
def animate(self, movie):
self.document().addResource(QtGui.QTextDocument.ImageResource,
self.urls[movie],
movie.currentPixmap())
self.setLineWrapColumnOrWidth(self.lineWrapColumnOrWidth())
def decoratedText(self, text):
text = h.escape(text) # replace < and >
exp = QtCore.QRegExp(
'('
'(?:\\b)((www\\.)|(http[s]?|ftp)://)'
'\\w+\\S+)'
'|(?:\\b)(file:///)([\\S| ]*)'
'|(?:\\b)(tox:[a-zA-Z\\d]{76}$)'
'|(?:\\b)(mailto:\\S+@\\S+\\.\\S+)'
'|(?:\\b)(tox:\\S+@\\S+)')
offset = exp.indexIn(text, 0)
while offset != -1: # add links
url = exp.cap()
if exp.cap(2) == 'www.':
html = '<a href="http://{0}">{0}</a>'.format(url)
else:
html = '<a href="{0}">{0}</a>'.format(url)
text = text[:offset] + html + text[offset + len(exp.cap()):]
offset += len(html)
offset = exp.indexIn(text, offset)
arr = text.split('\n')
for i in range(len(arr)): # quotes
if arr[i].startswith('&gt;'):
arr[i] = '<font color="green"><b>' + arr[i][4:] + '</b></font>'
text = '<br>'.join(arr)
text = smileys.SmileyLoader.get_instance().add_smileys_to_text(text, self) # smileys
return text
class MessageItem(QtWidgets.QWidget):
"""
Message in messages list
"""
def __init__(self, text, time, user='', sent=True, message_type=TOX_MESSAGE_TYPE['NORMAL'], parent=None):
QtWidgets.QWidget.__init__(self, parent)
self.name = DataLabel(self)
self.name.setGeometry(QtCore.QRect(2, 2, 95, 23))
self.name.setTextFormat(QtCore.Qt.PlainText)
font = QtGui.QFont()
font.setFamily(settings.Settings.get_instance()['font'])
font.setPointSize(11)
font.setBold(True)
self.name.setFont(font)
self.name.setText(user)
self.time = QtWidgets.QLabel(self)
self.time.setGeometry(QtCore.QRect(parent.width() - 60, 0, 50, 25))
font.setPointSize(10)
font.setBold(False)
self.time.setFont(font)
self._time = time
if not sent:
movie = QtGui.QMovie(curr_directory() + '/images/spinner.gif')
self.time.setMovie(movie)
movie.start()
self.t = True
else:
self.time.setText(convert_time(time))
self.t = False
self.message = MessageEdit(text, parent.width() - 160, message_type, self)
if message_type != TOX_MESSAGE_TYPE['NORMAL']:
self.name.setStyleSheet("QLabel { color: #5CB3FF; }")
self.message.setAlignment(QtCore.Qt.AlignCenter)
self.time.setStyleSheet("QLabel { color: #5CB3FF; }")
self.message.setGeometry(QtCore.QRect(100, 0, parent.width() - 160, self.message.height()))
self.setFixedHeight(self.message.height())
def mouseReleaseEvent(self, event):
if event.button() == QtCore.Qt.RightButton and event.x() > self.time.x():
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()
def delete(self):
pr = profile.Profile.get_instance()
pr.delete_message(self._time)
def mark_as_sent(self):
if self.t:
self.time.setText(convert_time(self._time))
self.t = False
return True
return False
def set_avatar(self, pixmap):
self.name.setAlignment(QtCore.Qt.AlignCenter)
self.message.setAlignment(QtCore.Qt.AlignVCenter)
self.setFixedHeight(max(self.height(), 36))
self.name.setFixedHeight(self.height())
self.message.setFixedHeight(self.height())
self.name.setPixmap(pixmap.scaled(30, 30, QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation))
def select_text(self, text):
tmp = self.message.toHtml()
text = h.escape(text)
strings = re.findall(text, tmp, flags=re.IGNORECASE)
for s in strings:
tmp = self.replace_all(tmp, s)
self.message.setHtml(tmp)
@staticmethod
def replace_all(text, substring):
i, l = 0, len(substring)
while i < len(text) - l + 1:
index = text[i:].find(substring)
if index == -1:
break
i += index
lgt, rgt = text[i:].find('<'), text[i:].find('>')
if rgt < lgt:
i += rgt + 1
continue
sub = '<font color="red"><b>{}</b></font>'.format(substring)
text = text[:i] + sub + text[i + l:]
i += len(sub)
return text
class ContactItem(QtWidgets.QWidget):
"""
Contact in friends list

View file

@ -21,6 +21,7 @@ class MainWindow(QtWidgets.QMainWindow):
self._saved = False
if settings['show_welcome_screen']:
self.ws = WelcomeScreen()
self.profile = None
def setup_menu(self, window):
self.menubar = QtWidgets.QMenuBar(window)
@ -108,42 +109,42 @@ class MainWindow(QtWidgets.QMainWindow):
if event.type() == QtCore.QEvent.WindowActivate:
self.tray.setIcon(QtGui.QIcon(curr_directory() + '/images/icon.png'))
self.messages.repaint()
return super(MainWindow, self).event(event)
return super().event(event)
def retranslateUi(self):
self.lockApp.setText(QtWidgets.QApplication.translate("MainWindow", "Lock"))
self.menuPlugins.setTitle(QtWidgets.QApplication.translate("MainWindow", "Plugins"))
self.pluginData.setText(QtWidgets.QApplication.translate("MainWindow", "List of plugins"))
self.menuProfile.setTitle(QtWidgets.QApplication.translate("MainWindow", "Profile"))
self.menuSettings.setTitle(QtWidgets.QApplication.translate("MainWindow", "Settings"))
self.menuAbout.setTitle(QtWidgets.QApplication.translate("MainWindow", "About"))
self.actionAdd_friend.setText(QtWidgets.QApplication.translate("MainWindow", "Add contact"))
self.actionAdd_gc.setText(QtWidgets.QApplication.translate("MainWindow", "Create group chat"))
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.videoSettings.setText(QtWidgets.QApplication.translate("MainWindow", "Video"))
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.lockApp.setText(util_ui.tr("Lock"))
self.menuPlugins.setTitle(util_ui.tr("Plugins"))
self.pluginData.setText(util_ui.tr("List of plugins"))
self.menuProfile.setTitle(util_ui.tr("Profile"))
self.menuSettings.setTitle(util_ui.tr("Settings"))
self.menuAbout.setTitle(util_ui.tr("About"))
self.actionAdd_friend.setText(util_ui.tr("Add contact"))
self.actionAdd_gc.setText(util_ui.tr("Create group chat"))
self.actionprofilesettings.setText(util_ui.tr("Profile"))
self.actionPrivacy_settings.setText(util_ui.tr("Privacy"))
self.actionInterface_settings.setText(util_ui.tr("Interface"))
self.actionNotifications.setText(util_ui.tr("Notifications"))
self.actionNetwork.setText(util_ui.tr("Network"))
self.actionAbout_program.setText(util_ui.tr("About program"))
self.actionSettings.setText(util_ui.tr("Settings"))
self.audioSettings.setText(util_ui.tr("Audio"))
self.videoSettings.setText(util_ui.tr("Video"))
self.updateSettings.setText(util_ui.tr("Updates"))
self.contact_name.setPlaceholderText(util_ui.tr("Search"))
self.sendMessageButton.setToolTip(util_ui.tr("Send message"))
self.callButton.setToolTip(util_ui.tr("Start audio call with friend"))
self.online_contacts.clear()
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"))
self.online_contacts.addItem(util_ui.tr("All"))
self.online_contacts.addItem(util_ui.tr("Online"))
self.online_contacts.addItem(util_ui.tr("Online first"))
self.online_contacts.addItem(util_ui.tr("Name"))
self.online_contacts.addItem(util_ui.tr("Online and by name"))
self.online_contacts.addItem(util_ui.tr("Online first and by name"))
ind = self._settings['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(QtWidgets.QApplication.translate("MainWindow", "Import plugin"))
self.reloadPlugins.setText(QtWidgets.QApplication.translate("MainWindow", "Reload plugins"))
self.importPlugin.setText(util_ui.tr("Import plugin"))
self.reloadPlugins.setText(util_ui.tr("Reload plugins"))
def setup_right_bottom(self, Form):
Form.resize(650, 60)
@ -353,28 +354,27 @@ class MainWindow(QtWidgets.QMainWindow):
self.user_info = name
self.friend_info = info
self.retranslateUi()
self.profile = Profile(tox, self)
def closeEvent(self, event):
s = Settings.get_instance()
if not s['close_to_tray'] or s.closing:
if not self._saved:
self._saved = True
self.profile.save_history()
self.profile.close()
s['x'] = self.geometry().x()
s['y'] = self.geometry().y()
s['width'] = self.width()
s['height'] = self.height()
s.save()
QtWidgets.QApplication.closeAllWindows()
event.accept()
if not self._settings['close_to_tray'] or self._settings.closing:
if self._saved:
return
self._saved = True
self.profile.save_history()
self.profile.close()
self._settings['x'] = self.geometry().x()
self._settings['y'] = self.geometry().y()
self._settings['width'] = self.width()
self._settings['height'] = self.height()
self._settings.save()
QtWidgets.QApplication.closeAllWindows()
event.accept()
elif QtWidgets.QSystemTrayIcon.isSystemTrayAvailable():
event.ignore()
self.hide()
def close_window(self):
Settings.get_instance().closing = True
self._settings.closing = True
self.close()
def resizeEvent(self, *args, **kwargs):
@ -471,7 +471,7 @@ class MainWindow(QtWidgets.QMainWindow):
def import_plugin(self):
import util
directory = QtWidgets.QFileDialog.getExistingDirectory(self,
QtWidgets.QApplication.translate("MainWindow", 'Choose folder with plugin'),
util_ui.tr('Choose folder with plugin'),
util.curr_directory(),
QtWidgets.QFileDialog.ShowDirsOnly | QtWidgets.QFileDialog.DontUseNativeDialog)
if directory:
@ -480,9 +480,9 @@ class MainWindow(QtWidgets.QMainWindow):
util.copy(src, dest)
msgBox = QtWidgets.QMessageBox()
msgBox.setWindowTitle(
QtWidgets.QApplication.translate("MainWindow", "Restart Toxygen"))
util_ui.tr("Restart Toxygen"))
msgBox.setText(
QtWidgets.QApplication.translate("MainWindow", 'Plugin will be loaded after restart'))
util_ui.tr('Plugin will be loaded after restart'))
msgBox.exec_()
def lock_app(self):
@ -492,9 +492,9 @@ class MainWindow(QtWidgets.QMainWindow):
else:
msgBox = QtWidgets.QMessageBox()
msgBox.setWindowTitle(
QtWidgets.QApplication.translate("MainWindow", "Cannot lock app"))
util_ui.tr("Cannot lock app"))
msgBox.setText(
QtWidgets.QApplication.translate("MainWindow", 'Error. Profile password is not set.'))
util_ui.tr('Error. Profile password is not set.'))
msgBox.exec_()
def show_menu(self):
@ -517,7 +517,7 @@ class MainWindow(QtWidgets.QMainWindow):
def send_file(self):
self.menu.hide()
if self.profile.active_friend + 1and self.profile.is_active_a_friend():
choose = QtWidgets.QApplication.translate("MainWindow", 'Choose file')
choose = util_ui.tr('Choose file')
name = QtWidgets.QFileDialog.getOpenFileName(self, choose, options=QtWidgets.QFileDialog.DontUseNativeDialog)
if name[0]:
self.profile.send_file(name[0])
@ -583,33 +583,33 @@ class MainWindow(QtWidgets.QMainWindow):
return
settings = Settings.get_instance()
allowed = friend.tox_id in settings['auto_accept_from_friends']
auto = QtWidgets.QApplication.translate("MainWindow", 'Disallow auto accept') if allowed else QtWidgets.QApplication.translate("MainWindow", 'Allow auto accept')
auto = util_ui.tr('Disallow auto accept') if allowed else util_ui.tr('Allow auto accept')
if item is not None:
self.listMenu = QtWidgets.QMenu()
is_friend = type(friend) is Friend
if is_friend:
set_alias_item = self.listMenu.addAction(QtWidgets.QApplication.translate("MainWindow", 'Set alias'))
set_alias_item = self.listMenu.addAction(util_ui.tr('Set alias'))
set_alias_item.triggered.connect(lambda: self.set_alias(num))
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'))
history_menu = self.listMenu.addMenu(util_ui.tr('Chat history'))
clear_history_item = history_menu.addAction(util_ui.tr('Clear history'))
export_to_text_item = history_menu.addAction(util_ui.tr('Export as text'))
export_to_html_item = history_menu.addAction(util_ui.tr('Export as HTML'))
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_menu = self.listMenu.addMenu(util_ui.tr('Copy'))
copy_name_item = copy_menu.addAction(util_ui.tr('Name'))
copy_status_item = copy_menu.addAction(util_ui.tr('Status message'))
if is_friend:
copy_key_item = copy_menu.addAction(QtWidgets.QApplication.translate("MainWindow", 'Public key'))
copy_key_item = copy_menu.addAction(util_ui.tr('Public key'))
auto_accept_item = self.listMenu.addAction(auto)
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'))
remove_item = self.listMenu.addAction(util_ui.tr('Remove friend'))
block_item = self.listMenu.addAction(util_ui.tr('Block friend'))
notes_item = self.listMenu.addAction(util_ui.tr('Notes'))
chats = self.profile.get_group_chats()
if len(chats) and self.profile.is_active_online():
invite_menu = self.listMenu.addMenu(QtWidgets.QApplication.translate("MainWindow", 'Invite to group chat'))
invite_menu = self.listMenu.addMenu(util_ui.tr('Invite to group chat'))
for i in range(len(chats)):
name, number = chats[i]
item = invite_menu.addAction(name)
@ -619,7 +619,7 @@ class MainWindow(QtWidgets.QMainWindow):
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 = self.listMenu.addMenu(util_ui.tr('Plugins'))
plug.addActions(submenu)
copy_key_item.triggered.connect(lambda: self.copy_friend_key(num))
remove_item.triggered.connect(lambda: self.remove_friend(num))
@ -627,8 +627,8 @@ class MainWindow(QtWidgets.QMainWindow):
auto_accept_item.triggered.connect(lambda: self.auto_accept(num, not allowed))
notes_item.triggered.connect(lambda: self.show_note(friend))
else:
leave_item = self.listMenu.addAction(QtWidgets.QApplication.translate("MainWindow", 'Leave chat'))
set_title_item = self.listMenu.addAction(QtWidgets.QApplication.translate("MainWindow", 'Set title'))
leave_item = self.listMenu.addAction(util_ui.tr('Leave chat'))
set_title_item = self.listMenu.addAction(util_ui.tr('Set title'))
leave_item.triggered.connect(lambda: self.leave_gc(num))
set_title_item.triggered.connect(lambda: self.set_title(num))
clear_history_item.triggered.connect(lambda: self.clear_history(num))
@ -643,7 +643,7 @@ class MainWindow(QtWidgets.QMainWindow):
def show_note(self, friend):
s = Settings.get_instance()
note = s['notes'][friend.tox_id] if friend.tox_id in s['notes'] else ''
user = QtWidgets.QApplication.translate("MainWindow", 'Notes about user')
user = util_ui.tr('Notes about user')
user = '{} {}'.format(user, friend.name)
def save_note(text):

View file

@ -16,6 +16,7 @@ class AddContact(CenteredWidget):
super(AddContact, self).__init__()
self.initUI(tox_id)
self._adding = False
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
def initUI(self, tox_id):
self.setObjectName('AddContact')

View file

@ -0,0 +1,212 @@
from PyQt5 import QtWidgets, QtGui, QtCore
from wrapper.toxcore_enums_and_consts import *
import ui.widgets as widgets
import util.ui as util_ui
import util.util as util
import ui.menu as menu
import html as h
import re
class MessageEdit(QtWidgets.QTextBrowser):
def __init__(self, settings, message_edit, smileys_loader, plugin_loader, text, width, message_type, parent=None):
super().__init__(parent)
self.urls = {}
self._message_edit = message_edit
self._smileys_loader = smileys_loader
self._plugin_loader = plugin_loader
self._add_contact = None
self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.setWordWrapMode(QtGui.QTextOption.WrapAtWordBoundaryOrAnywhere)
self.document().setTextWidth(width)
self.setOpenExternalLinks(True)
self.setAcceptRichText(True)
self.setOpenLinks(False)
path = smileys_loader.get_smileys_path()
if path is not None:
self.setSearchPaths([path])
self.document().setDefaultStyleSheet('a { color: #306EFF; }')
text = self.decoratedText(text)
if message_type != TOX_MESSAGE_TYPE['NORMAL']:
self.setHtml('<p style="color: #5CB3FF; font: italic; font-size: 20px;" >' + text + '</p>')
else:
self.setHtml(text)
font = QtGui.QFont()
font.setFamily(settings['font'])
font.setPixelSize(settings['message_font_size'])
font.setBold(False)
self.setFont(font)
self.resize(width, self.document().size().height())
self.setTextInteractionFlags(QtCore.Qt.TextSelectableByMouse | QtCore.Qt.LinksAccessibleByMouse)
self.anchorClicked.connect(self.on_anchor_clicked)
def contextMenuEvent(self, event):
menu = widgets.create_menu(self.createStandardContextMenu(event.pos()))
quote = menu.addAction(util_ui.tr('Quote selected text'))
quote.triggered.connect(self.quote_text)
text = self.textCursor().selection().toPlainText()
if not text:
quote.setEnabled(False)
else:
sub_menu = self._plugin_loader.get_message_menu(menu, text)
if len(sub_menu):
plugins_menu = menu.addMenu(util_ui.tr('Plugins'))
plugins_menu.addActions(sub_menu)
menu.popup(event.globalPos())
menu.exec_(event.globalPos())
del menu
def quote_text(self):
text = self.textCursor().selection().toPlainText()
if not text:
return
text = '>' + '\n>'.join(text.split('\n'))
if self._message_edit.toPlainText():
text = '\n' + text
self._message_edit.appendPlainText(text)
def on_anchor_clicked(self, url):
text = str(url.toString())
if text.startswith('tox:'):
self._add_contact = menu.AddContact(text[4:])
self._add_contact.show()
else:
QtGui.QDesktopServices.openUrl(url)
self.clearFocus()
def addAnimation(self, url, file_name):
movie = QtGui.QMovie(self)
movie.setFileName(file_name)
self.urls[movie] = url
movie.frameChanged[int].connect(lambda x: self.animate(movie))
movie.start()
def animate(self, movie):
self.document().addResource(QtGui.QTextDocument.ImageResource,
self.urls[movie],
movie.currentPixmap())
self.setLineWrapColumnOrWidth(self.lineWrapColumnOrWidth())
def decoratedText(self, text):
text = h.escape(text) # replace < and >
exp = QtCore.QRegExp(
'('
'(?:\\b)((www\\.)|(http[s]?|ftp)://)'
'\\w+\\S+)'
'|(?:\\b)(file:///)([\\S| ]*)'
'|(?:\\b)(tox:[a-zA-Z\\d]{76}$)'
'|(?:\\b)(mailto:\\S+@\\S+\\.\\S+)'
'|(?:\\b)(tox:\\S+@\\S+)')
offset = exp.indexIn(text, 0)
while offset != -1: # add links
url = exp.cap()
if exp.cap(2) == 'www.':
html = '<a href="http://{0}">{0}</a>'.format(url)
else:
html = '<a href="{0}">{0}</a>'.format(url)
text = text[:offset] + html + text[offset + len(exp.cap()):]
offset += len(html)
offset = exp.indexIn(text, offset)
arr = text.split('\n')
for i in range(len(arr)): # quotes
if arr[i].startswith('&gt;'):
arr[i] = '<font color="green"><b>' + arr[i][4:] + '</b></font>'
text = '<br>'.join(arr)
text = self._smileys_loader.add_smileys_to_text(text, self) # smileys
return text
class MessageItem(QtWidgets.QWidget):
"""
Message in messages list
"""
def __init__(self, settings, message_edit_factory, text_message, parent=None):
QtWidgets.QWidget.__init__(self, parent)
self.name = widgets.DataLabel(self)
self.name.setGeometry(QtCore.QRect(2, 2, 95, 23))
self.name.setTextFormat(QtCore.Qt.PlainText)
font = QtGui.QFont()
font.setFamily(settings['font'])
font.setPointSize(11)
font.setBold(True)
self.name.setFont(font)
self.name.setText(text_message.user)
self.time = QtWidgets.QLabel(self)
self.time.setGeometry(QtCore.QRect(parent.width() - 60, 0, 50, 25))
font.setPointSize(10)
font.setBold(False)
self.time.setFont(font)
self._time = time
if not sent:
movie = QtGui.QMovie(util.join_path(util.get_images_directory(), 'spinner.gif'))
self.time.setMovie(movie)
movie.start()
self.t = True
else:
self.time.setText(util.convert_time(time))
self.t = False
self.message = MessageEdit(text, parent.width() - 160, message_type, self)
if message_type != TOX_MESSAGE_TYPE['NORMAL']:
self.name.setStyleSheet("QLabel { color: #5CB3FF; }")
self.message.setAlignment(QtCore.Qt.AlignCenter)
self.time.setStyleSheet("QLabel { color: #5CB3FF; }")
self.message.setGeometry(QtCore.QRect(100, 0, parent.width() - 160, self.message.height()))
self.setFixedHeight(self.message.height())
def mouseReleaseEvent(self, event):
if event.button() == QtCore.Qt.RightButton and event.x() > self.time.x():
self.listMenu = QtWidgets.QMenu()
delete_item = self.listMenu.addAction(util_ui.tr('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()
def delete(self):
pr = profile.Profile.get_instance()
pr.delete_message(self._time)
def mark_as_sent(self):
if self.t:
self.time.setText(convert_time(self._time))
self.t = False
return True
return False
def set_avatar(self, pixmap):
self.name.setAlignment(QtCore.Qt.AlignCenter)
self.message.setAlignment(QtCore.Qt.AlignVCenter)
self.setFixedHeight(max(self.height(), 36))
self.name.setFixedHeight(self.height())
self.message.setFixedHeight(self.height())
self.name.setPixmap(pixmap.scaled(30, 30, QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation))
def select_text(self, text):
tmp = self.message.toHtml()
text = h.escape(text)
strings = re.findall(text, tmp, flags=re.IGNORECASE)
for s in strings:
tmp = self.replace_all(tmp, s)
self.message.setHtml(tmp)
@staticmethod
def replace_all(text, substring):
i, l = 0, len(substring)
while i < len(text) - l + 1:
index = text[i:].find(substring)
if index == -1:
break
i += index
lgt, rgt = text[i:].find('<'), text[i:].find('>')
if rgt < lgt:
i += rgt + 1
continue
sub = '<font color="red"><b>{}</b></font>'.format(substring)
text = text[:i] + sub + text[i + l:]
i += len(sub)
return text

View file

@ -66,14 +66,14 @@ class QRightClickButton(QtWidgets.QPushButton):
rightClicked = QtCore.pyqtSignal()
def __init__(self, parent):
super(QRightClickButton, self).__init__(parent)
def __init__(self, parent=None):
super().__init__(parent)
def mousePressEvent(self, event):
if event.button() == QtCore.Qt.RightButton:
self.rightClicked.emit()
else:
super(QRightClickButton, self).mousePressEvent(event)
super().mousePressEvent(event)
class RubberBand(QtWidgets.QRubberBand):