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):
"""