2015-12-14 19:43:39 +01:00
from PyQt4 import QtCore , QtGui
2016-10-22 01:45:32 +02:00
import multiprocessing
import Queue
2016-02-29 00:47:07 +01:00
from urlparse import urlparse
2015-12-14 19:43:39 +01:00
from safehtmlparser import *
2015-12-15 01:24:10 +01:00
class MessageView ( QtGui . QTextBrowser ) :
2015-12-14 19:43:39 +01:00
MODE_PLAIN = 0
MODE_HTML = 1
def __init__ ( self , parent = 0 ) :
super ( MessageView , self ) . __init__ ( parent )
self . mode = MessageView . MODE_PLAIN
self . html = None
2015-12-15 01:24:10 +01:00
self . setOpenExternalLinks ( False )
self . setOpenLinks ( False )
self . anchorClicked . connect ( self . confirmURL )
2015-12-15 03:51:06 +01:00
self . out = " "
self . outpos = 0
self . document ( ) . setUndoRedoEnabled ( False )
self . rendering = False
2016-01-04 11:13:31 +01:00
self . defaultFontPointSize = self . currentFont ( ) . pointSize ( )
2015-12-15 03:51:06 +01:00
self . verticalScrollBar ( ) . valueChanged . connect ( self . lazyRender )
2016-10-20 20:26:53 +02:00
self . setWrappingWidth ( )
def resizeEvent ( self , event ) :
super ( MessageView , self ) . resizeEvent ( event )
self . setWrappingWidth ( event . size ( ) . width ( ) )
2015-12-14 19:43:39 +01:00
def mousePressEvent ( self , event ) :
#text = textCursor.block().text()
2016-01-10 17:46:22 +01:00
if event . button ( ) == QtCore . Qt . LeftButton and self . html and self . html . has_html and self . cursorForPosition ( event . pos ( ) ) . block ( ) . blockNumber ( ) == 0 :
2015-12-14 19:43:39 +01:00
if self . mode == MessageView . MODE_PLAIN :
self . showHTML ( )
else :
self . showPlain ( )
else :
super ( MessageView , self ) . mousePressEvent ( event )
2016-01-04 11:13:31 +01:00
def wheelEvent ( self , event ) :
# super will actually automatically take care of zooming
super ( MessageView , self ) . wheelEvent ( event )
2016-01-23 09:55:12 +01:00
if ( QtGui . QApplication . queryKeyboardModifiers ( ) & QtCore . Qt . ControlModifier ) == QtCore . Qt . ControlModifier and event . orientation ( ) == QtCore . Qt . Vertical :
zoom = self . currentFont ( ) . pointSize ( ) * 100 / self . defaultFontPointSize
QtGui . QApplication . activeWindow ( ) . statusBar ( ) . showMessage ( QtGui . QApplication . translate ( " MainWindow " , " Zoom level %1% " ) . arg ( str ( zoom ) ) )
2016-01-04 11:13:31 +01:00
2016-10-20 20:26:53 +02:00
def setWrappingWidth ( self , width = None ) :
self . setLineWrapMode ( QtGui . QTextEdit . FixedPixelWidth )
if width is None :
width = self . width ( )
self . setLineWrapColumnOrWidth ( width )
2015-12-15 01:24:10 +01:00
def confirmURL ( self , link ) :
2016-02-29 00:47:07 +01:00
if link . scheme ( ) == " mailto " :
2018-01-18 15:14:29 +01:00
window = QtGui . QApplication . activeWindow ( )
window . ui . lineEditTo . setText ( link . path ( ) )
2016-02-29 00:47:07 +01:00
if link . hasQueryItem ( " subject " ) :
2018-01-18 15:14:29 +01:00
window . ui . lineEditSubject . setText (
link . queryItemValue ( " subject " ) )
2016-02-29 00:47:07 +01:00
if link . hasQueryItem ( " body " ) :
2018-01-18 15:14:29 +01:00
window . ui . textEditMessage . setText (
link . queryItemValue ( " body " ) )
window . setSendFromComboBox ( )
window . ui . tabWidgetSend . setCurrentIndex ( 0 )
window . ui . tabWidget . setCurrentIndex (
window . ui . tabWidget . indexOf ( window . ui . send )
)
window . ui . textEditMessage . setFocus ( )
2016-02-29 00:47:07 +01:00
return
2015-12-15 11:11:57 +01:00
reply = QtGui . QMessageBox . warning ( self ,
2016-10-20 20:38:21 +02:00
QtGui . QApplication . translate ( " MessageView " , " Follow external link " ) ,
2018-02-08 06:52:33 +01:00
QtGui . QApplication . translate ( " MessageView " , " The link \" % 1 \" will open in a browser. It may be a security risk, it could de-anonymise you or download malicious data. Are you sure? " ) . arg ( unicode ( link . toString ( ) ) ) ,
2015-12-15 01:24:10 +01:00
QtGui . QMessageBox . Yes , QtGui . QMessageBox . No )
if reply == QtGui . QMessageBox . Yes :
QtGui . QDesktopServices . openUrl ( link )
2015-12-14 19:43:39 +01:00
2016-03-12 09:07:16 +01:00
def loadResource ( self , restype , name ) :
2016-03-01 02:21:10 +01:00
if restype == QtGui . QTextDocument . ImageResource and name . scheme ( ) == " bmmsg " :
pass
# QImage correctImage;
# lookup the correct QImage from a cache
# return QVariant::fromValue(correctImage);
# elif restype == QtGui.QTextDocument.HtmlResource:
# elif restype == QtGui.QTextDocument.ImageResource:
# elif restype == QtGui.QTextDocument.StyleSheetResource:
# elif restype == QtGui.QTextDocument.UserResource:
else :
pass
# by default, this will interpret it as a local file
# QtGui.QTextBrowser.loadResource(restype, name)
2015-12-15 03:51:06 +01:00
def lazyRender ( self ) :
if self . rendering :
return
self . rendering = True
position = self . verticalScrollBar ( ) . value ( )
cursor = QtGui . QTextCursor ( self . document ( ) )
while self . outpos < len ( self . out ) and self . verticalScrollBar ( ) . value ( ) > = self . document ( ) . size ( ) . height ( ) - 2 * self . size ( ) . height ( ) :
startpos = self . outpos
self . outpos + = 10240
# find next end of tag
if self . mode == MessageView . MODE_HTML :
pos = self . out . find ( " > " , self . outpos )
if pos > self . outpos :
2018-02-08 11:58:38 +01:00
self . outpos = pos + 1
2015-12-15 03:51:06 +01:00
cursor . movePosition ( QtGui . QTextCursor . End , QtGui . QTextCursor . MoveAnchor )
cursor . insertHtml ( QtCore . QString ( self . out [ startpos : self . outpos ] ) )
self . verticalScrollBar ( ) . setValue ( position )
self . rendering = False
2015-12-14 19:43:39 +01:00
def showPlain ( self ) :
self . mode = MessageView . MODE_PLAIN
out = self . html . raw
if self . html . has_html :
2017-02-22 12:30:14 +01:00
out = " <div align= \" center \" style= \" text-decoration: underline; \" ><b> " + unicode ( QtGui . QApplication . translate ( " MessageView " , " HTML detected, click here to display " ) ) + " </b></div><br/> " + out
2015-12-15 03:51:06 +01:00
self . out = out
self . outpos = 0
self . setHtml ( " " )
self . lazyRender ( )
2015-12-14 19:43:39 +01:00
def showHTML ( self ) :
self . mode = MessageView . MODE_HTML
out = self . html . sanitised
2017-02-22 12:30:14 +01:00
out = " <div align= \" center \" style= \" text-decoration: underline; \" ><b> " + unicode ( QtGui . QApplication . translate ( " MessageView " , " Click here to disable HTML " ) ) + " </b></div><br/> " + out
2015-12-15 03:51:06 +01:00
self . out = out
self . outpos = 0
self . setHtml ( " " )
self . lazyRender ( )
2015-12-14 19:43:39 +01:00
def setContent ( self , data ) :
self . html = SafeHTMLParser ( )
2015-12-15 03:51:06 +01:00
self . html . reset ( )
self . html . reset_safe ( )
2016-02-25 10:13:39 +01:00
self . html . allow_picture = True
2017-05-15 12:25:30 +02:00
self . html . feed ( data )
2015-12-14 19:43:39 +01:00
self . html . close ( )
2016-02-25 10:13:39 +01:00
self . showPlain ( )