diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index 440d36b2..c7fa6390 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -11,6 +11,7 @@ import sys import textwrap import threading import time +import base64 from datetime import datetime, timedelta from sqlite3 import register_adapter @@ -161,6 +162,8 @@ class MyForm(settingsmixin.SMainWindow): "clicked()"), self.click_pushButtonTTL) QtCore.QObject.connect(self.ui.pushButtonClear, QtCore.SIGNAL( "clicked()"), self.click_pushButtonClear) + QtCore.QObject.connect(self.ui.pushButtonAttach, QtCore.SIGNAL( + "clicked()"), self.click_pushButtonAttach) QtCore.QObject.connect(self.ui.pushButtonSend, QtCore.SIGNAL( "clicked()"), self.click_pushButtonSend) QtCore.QObject.connect(self.ui.pushButtonFetchNamecoinID, QtCore.SIGNAL( @@ -1951,6 +1954,23 @@ class MyForm(settingsmixin.SMainWindow): self.ui.textEditMessage.reset() self.ui.comboBoxSendFrom.setCurrentIndex(0) + def click_pushButtonAttach(self): + """Launch a file picker and append to the current message the base64-encoded contents of the chosen file.""" + filename = QtGui.QFileDialog.getOpenFileName(self, "Attach File") + if filename: + f = open(filename, 'rb') + data = f.read() + f.close() + data_b64 = base64.b64encode(data) + html_data = '' \ + + os.path.basename(unicode(filename)) + '' + if self.ui.tabWidgetSend.currentIndex() == self.ui.tabWidgetSend.indexOf(self.ui.sendDirect): + # send direct message + self.ui.textEditMessage.insertPlainText(html_data) + else: + # send broadcast message + self.ui.textEditMessageBroadcast.insertPlainText(html_data) + def click_pushButtonSend(self): encoding = 3 if QtGui.QApplication.queryKeyboardModifiers() & QtCore.Qt.ShiftModifier else 2 diff --git a/src/bitmessageqt/bitmessageui.py b/src/bitmessageqt/bitmessageui.py index 30d054d0..ca103dd5 100644 --- a/src/bitmessageqt/bitmessageui.py +++ b/src/bitmessageqt/bitmessageui.py @@ -340,6 +340,9 @@ class Ui_MainWindow(object): self.pushButtonClear = QtGui.QPushButton(self.send) self.pushButtonClear.setObjectName(_fromUtf8("pushButtonClear")) self.horizontalLayout_5.addWidget(self.pushButtonClear, 0, QtCore.Qt.AlignRight) + self.pushButtonAttach = QtGui.QPushButton(self.send) + self.pushButtonAttach.setObjectName(_fromUtf8("pushButtonAttach")) + self.horizontalLayout_5.addWidget(self.pushButtonAttach, 0, QtCore.Qt.AlignRight) self.pushButtonSend = QtGui.QPushButton(self.send) self.pushButtonSend.setObjectName(_fromUtf8("pushButtonSend")) self.horizontalLayout_5.addWidget(self.pushButtonSend, 0, QtCore.Qt.AlignRight) @@ -713,6 +716,7 @@ class Ui_MainWindow(object): pass self.labelHumanFriendlyTTLDescription.setText(_translate("MainWindow", "%n hour(s)", None, QtCore.QCoreApplication.CodecForTr, hours)) self.pushButtonClear.setText(_translate("MainWindow", "Clear", None)) + self.pushButtonAttach.setText(_translate("MainWindow", "Attach File", None)) self.pushButtonSend.setText(_translate("MainWindow", "Send", None)) self.tabWidget.setTabText(self.tabWidget.indexOf(self.send), _translate("MainWindow", "Send", None)) self.treeWidgetSubscriptions.headerItem().setText(0, _translate("MainWindow", "Subscriptions", None)) diff --git a/src/bitmessageqt/bitmessageui.ui b/src/bitmessageqt/bitmessageui.ui index fef40be6..b8b92b68 100644 --- a/src/bitmessageqt/bitmessageui.ui +++ b/src/bitmessageqt/bitmessageui.ui @@ -594,6 +594,19 @@ p, li { white-space: pre-wrap; } + + + + + 16777215 + 16777215 + + + + Attach File + + + diff --git a/src/bitmessageqt/messageview.py b/src/bitmessageqt/messageview.py index 45f3a79a..7a6432b0 100644 --- a/src/bitmessageqt/messageview.py +++ b/src/bitmessageqt/messageview.py @@ -5,6 +5,8 @@ src/bitmessageqt/messageview.py """ from PyQt4 import QtCore, QtGui +import re +import base64 from safehtmlparser import SafeHTMLParser @@ -64,6 +66,9 @@ class MessageView(QtGui.QTextBrowser): def confirmURL(self, link): """Show a dialog requesting URL opening confirmation""" + link_str = link.toString() + datablob_re = r'^data:.*/.*;base64,.*' + datablob_match = re.match(datablob_re, link_str) if link.scheme() == "mailto": window = QtGui.QApplication.activeWindow() window.ui.lineEditTo.setText(link.path()) @@ -80,19 +85,29 @@ class MessageView(QtGui.QTextBrowser): ) window.ui.textEditMessage.setFocus() return - reply = QtGui.QMessageBox.warning( - self, - QtGui.QApplication.translate( - "MessageView", - "Follow external link"), - 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())), - QtGui.QMessageBox.Yes, - QtGui.QMessageBox.No) - if reply == QtGui.QMessageBox.Yes: - QtGui.QDesktopServices.openUrl(link) + if datablob_match: + name = QtGui.QFileDialog.getSaveFileName(self, 'Save File') + if name: + f = open(name, 'wb') + data_begin_pos = re.finditer(";base64,", link_str).next() + data_b64 = link_str[data_begin_pos.span()[1]:] + data = base64.b64decode(data_b64) + f.write(data) + f.close() + else: + reply = QtGui.QMessageBox.warning( + self, + QtGui.QApplication.translate( + "MessageView", + "Follow external link"), + 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())), + QtGui.QMessageBox.Yes, + QtGui.QMessageBox.No) + if reply == QtGui.QMessageBox.Yes: + QtGui.QDesktopServices.openUrl(link) def loadResource(self, restype, name): """