manually merged changes in
This commit is contained in:
commit
0842679314
3
Makefile
3
Makefile
|
@ -13,7 +13,6 @@ source:
|
|||
install:
|
||||
mkdir -m 755 -p $(DEST_APP)
|
||||
mkdir -m 755 -p $(DEST_SHARE)/applications
|
||||
mkdir -m 755 -p $(DEST_SHARE)/applications/$(APP)
|
||||
mkdir -m 755 -p $(DEST_APP)/images
|
||||
mkdir -m 755 -p $(DEST_APP)/pyelliptic
|
||||
mkdir -m 755 -p $(DEST_APP)/socks
|
||||
|
@ -37,7 +36,7 @@ install:
|
|||
install -m 644 src/bitmessageqt/*.py $(DEST_APP)/bitmessageqt
|
||||
install -m 755 debian/pybm /usr/bin/pybitmessage
|
||||
|
||||
install -m 644 desktop/$(APP).desktop $(DEST_SHARE)/applications/$(APP)/$(APP).desktop
|
||||
install -m 644 desktop/$(APP).desktop $(DEST_SHARE)/applications/$(APP).desktop
|
||||
install -m 644 src/images/can-icon-24px.png $(DEST_SHARE)/icons/hicolor/24x24/apps/$(APP).png
|
||||
install -m 644 desktop/can-icon.svg $(DEST_SHARE)/icons/hicolor/scalable/apps/$(APP).svg
|
||||
install -m 644 desktop/can-icon.svg $(DEST_SHARE)/pixmaps/$(APP).svg
|
||||
|
|
2
debian/changelog
vendored
2
debian/changelog
vendored
|
@ -1,4 +1,4 @@
|
|||
pybitmessage (0.3.0-1) unstable; urgency=low
|
||||
pybitmessage (0.3.0-1) raring; urgency=low
|
||||
|
||||
* Added new API function: getStatus
|
||||
|
||||
|
|
4
debian/control
vendored
4
debian/control
vendored
|
@ -2,7 +2,7 @@ Source: pybitmessage
|
|||
Section: contrib/comm
|
||||
Priority: extra
|
||||
Maintainer: Jonathan Warren <jonathan@bitmessage.org>
|
||||
Build-Depends: debhelper (>= 8.0.0), python (>= 2.7.0), openssl, python-qt4, libqt4-dev (>= 4.8.0), python-qt4-dev, sqlite3, libsqlite3-dev
|
||||
Build-Depends: debhelper (>= 8.0.0), python (>= 2.7.0), openssl, python-qt4, libqt4-dev (>= 4.8.0), python-qt4-dev, sqlite3, libsqlite3-dev, libmessaging-menu-dev
|
||||
Standards-Version: 3.9.2
|
||||
Homepage: https://bitmessage.org/
|
||||
Vcs-Browser: https://github.com/Bitmessage/PyBitmessage
|
||||
|
@ -10,7 +10,7 @@ Vcs-Git: https://github.com/Bitmessage/PyBitmessage.git
|
|||
|
||||
Package: pybitmessage
|
||||
Architecture: all
|
||||
Depends: ${misc:Depends}, python (>= 2.7.0), openssl, python-qt4, libqt4-dev (>= 4.8.0), python-qt4-dev, sqlite3, libsqlite3-dev
|
||||
Depends: ${misc:Depends}, python (>= 2.7.0), openssl, python-qt4, libqt4-dev (>= 4.8.0), python-qt4-dev, sqlite3, libsqlite3-dev, libmessaging-menu-dev
|
||||
Description: Send encrypted messages to another person or to many subscribers
|
||||
Bitmessage is a P2P communications protocol used to send encrypted messages
|
||||
to another person or to many subscribers. It is decentralized and trustless,
|
||||
|
|
1
debian/files
vendored
1
debian/files
vendored
|
@ -1 +0,0 @@
|
|||
pybitmessage_0.3.0-1_all.deb contrib/comm extra
|
4
debian/pybm
vendored
4
debian/pybm
vendored
|
@ -1,4 +1,4 @@
|
|||
#!/bin/bash
|
||||
#!/bin/sh
|
||||
cd /usr/share/pybitmessage
|
||||
python bitmessagemain.py
|
||||
exec python bitmessagemain.py
|
||||
|
||||
|
|
4
debian/rules
vendored
4
debian/rules
vendored
|
@ -20,11 +20,11 @@ install: build clean
|
|||
dh_testroot
|
||||
dh_prep
|
||||
dh_installdirs
|
||||
|
||||
mkdir -m 755 -p $(CURDIR)/debian/$(APP)/usr
|
||||
mkdir -m 755 -p $(CURDIR)/debian/$(APP)/usr/bin
|
||||
mkdir -m 755 -p $(DEST_APP)
|
||||
mkdir -m 755 -p $(DEST_SHARE)/applications
|
||||
mkdir -m 755 -p $(DEST_SHARE)/applications/$(APP)
|
||||
mkdir -m 755 -p $(DEST_APP)/images
|
||||
mkdir -m 755 -p $(DEST_APP)/pyelliptic
|
||||
mkdir -m 755 -p $(DEST_APP)/socks
|
||||
|
@ -48,7 +48,7 @@ install: build clean
|
|||
install -m 644 $(CURDIR)/src/bitmessageqt/*.py $(DEST_APP)/bitmessageqt
|
||||
install -m 755 $(CURDIR)/debian/pybm $(DEST_MAIN)/pybitmessage
|
||||
|
||||
install -m 644 $(CURDIR)/desktop/$(APP).desktop $(DEST_SHARE)/applications/$(APP)/$(APP).desktop
|
||||
install -m 644 $(CURDIR)/desktop/$(APP).desktop $(DEST_SHARE)/applications/$(APP).desktop
|
||||
install -m 644 $(CURDIR)/src/images/can-icon-24px.png $(DEST_SHARE)/icons/hicolor/24x24/apps/$(APP).png
|
||||
install -m 644 $(CURDIR)/desktop/can-icon.svg $(DEST_SHARE)/icons/hicolor/scalable/apps/$(APP).svg
|
||||
install -m 644 $(CURDIR)/desktop/can-icon.svg $(DEST_SHARE)/pixmaps/$(APP).svg
|
||||
|
|
3
debian/source/include-binaries
vendored
3
debian/source/include-binaries
vendored
|
@ -6,6 +6,9 @@ src/images/redicon.png
|
|||
src/images/subscriptions.png
|
||||
src/images/blacklist.png
|
||||
src/images/can-icon-24px.png
|
||||
src/images/can-icon-24px-red.png
|
||||
src/images/can-icon-24px-yellow.png
|
||||
src/images/can-icon-24px-green.png
|
||||
src/images/identities.png
|
||||
src/images/yellowicon.png
|
||||
src/images/inbox.png
|
||||
|
|
|
@ -2,8 +2,29 @@
|
|||
Type=Application
|
||||
Name=PyBitmessage
|
||||
GenericName=PyBitmessage
|
||||
X-GNOME-FullName=PyBitmessage Secure Messaging
|
||||
Comment=Send encrypted messages to another person or to many subscribers
|
||||
Exec=pybitmessage %U
|
||||
Icon=pybitmessage
|
||||
Terminal=false
|
||||
Categories=Network
|
||||
Categories=Network;Email;Application
|
||||
Keywords=Email;E-mail;Newsgroup;Messaging
|
||||
X-MessagingMenu-UsesChatSection=true
|
||||
X-Ubuntu-Gettext-Domain=pybitmessage
|
||||
|
||||
Actions=Send;Subscribe;AddressBook
|
||||
|
||||
[Desktop Action Send]
|
||||
Name=Send
|
||||
Exec=pybitmessage -s
|
||||
OnlyShowIn=Unity;
|
||||
|
||||
[Desktop Action Subscribe]
|
||||
Name=Subscribe
|
||||
Exec=pybitmessage -b
|
||||
OnlyShowIn=Unity;
|
||||
|
||||
[Desktop Action AddressBook]
|
||||
Name=Address Book
|
||||
Exec=pybitmessage -a
|
||||
OnlyShowIn=Unity;
|
|
@ -47,7 +47,7 @@ import signal #Used to capture a Ctrl-C keypress so that Bitmessage can shutdown
|
|||
from SimpleXMLRPCServer import *
|
||||
import json
|
||||
from subprocess import call #used when the API must execute an outside program
|
||||
|
||||
import singleton
|
||||
|
||||
#For each stream to which we connect, several outgoingSynSender threads will exist and will collectively create 8 connections with peers.
|
||||
class outgoingSynSender(threading.Thread):
|
||||
|
@ -3810,6 +3810,9 @@ if useVeryEasyProofOfWorkForTesting:
|
|||
shared.networkDefaultPayloadLengthExtraBytes = int(shared.networkDefaultPayloadLengthExtraBytes / 7000)
|
||||
|
||||
if __name__ == "__main__":
|
||||
# is the application already running? If yes then exit.
|
||||
thisapp = singleton.singleinstance()
|
||||
|
||||
signal.signal(signal.SIGINT, signal_handler)
|
||||
#signal.signal(signal.SIGINT, signal.SIG_DFL)
|
||||
|
||||
|
@ -3857,6 +3860,7 @@ if __name__ == "__main__":
|
|||
shared.config.set('bitmessagesettings','messagesencrypted','false')
|
||||
shared.config.set('bitmessagesettings','defaultnoncetrialsperbyte',str(shared.networkDefaultProofOfWorkNonceTrialsPerByte))
|
||||
shared.config.set('bitmessagesettings','defaultpayloadlengthextrabytes',str(shared.networkDefaultPayloadLengthExtraBytes))
|
||||
shared.config.set('bitmessagesettings','minimizeonclose','true')
|
||||
|
||||
if storeConfigFilesInSameDirectoryAsProgramByDefault:
|
||||
#Just use the same directory as the program and forget about the appdata folder
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
|
||||
try:
|
||||
from PyQt4.QtCore import *
|
||||
from PyQt4.QtGui import *
|
||||
|
@ -5,6 +6,15 @@ except Exception, err:
|
|||
print 'PyBitmessage requires PyQt. You can download it from http://www.riverbankcomputing.com/software/pyqt/download or by searching Google for \'PyQt Download\' (without quotes).'
|
||||
print 'Error message:', err
|
||||
sys.exit()
|
||||
|
||||
withMessagingMenu = False
|
||||
try:
|
||||
from gi.repository import MessagingMenu
|
||||
from gi.repository import Notify
|
||||
withMessagingMenu = True
|
||||
except ImportError:
|
||||
MessagingMenu = None
|
||||
|
||||
from addresses import *
|
||||
import shared
|
||||
from bitmessageui import *
|
||||
|
@ -22,8 +32,10 @@ import time
|
|||
import os
|
||||
from pyelliptic.openssl import OpenSSL
|
||||
import pickle
|
||||
import platform
|
||||
|
||||
class MyForm(QtGui.QMainWindow):
|
||||
|
||||
def __init__(self, parent=None):
|
||||
QtGui.QWidget.__init__(self, parent)
|
||||
self.ui = Ui_MainWindow()
|
||||
|
@ -62,7 +74,7 @@ class MyForm(QtGui.QMainWindow):
|
|||
traySignal = "activated(QSystemTrayIcon::ActivationReason)"
|
||||
QtCore.QObject.connect(self.trayIcon, QtCore.SIGNAL(traySignal), self.__icon_activated)
|
||||
menu = QtGui.QMenu()
|
||||
self.exitAction = menu.addAction("Exit", self.close)
|
||||
self.exitAction = menu.addAction("Quit", self.quit)
|
||||
self.trayIcon.setContextMenu(menu)
|
||||
#I'm currently under the impression that Mac users have different expectations for the tray icon. They don't necessairly expect it to open the main window when clicked and they still expect a program showing a tray icon to also be in the dock.
|
||||
if 'darwin' in sys.platform:
|
||||
|
@ -71,7 +83,7 @@ class MyForm(QtGui.QMainWindow):
|
|||
self.ui.labelSendBroadcastWarning.setVisible(False)
|
||||
|
||||
#FILE MENU and other buttons
|
||||
QtCore.QObject.connect(self.ui.actionExit, QtCore.SIGNAL("triggered()"), self.close)
|
||||
QtCore.QObject.connect(self.ui.actionExit, QtCore.SIGNAL("triggered()"), self.quit)
|
||||
QtCore.QObject.connect(self.ui.actionManageKeys, QtCore.SIGNAL("triggered()"), self.click_actionManageKeys)
|
||||
QtCore.QObject.connect(self.ui.actionRegenerateDeterministicAddresses, QtCore.SIGNAL("triggered()"), self.click_actionRegenerateDeterministicAddresses)
|
||||
QtCore.QObject.connect(self.ui.pushButtonNewAddress, QtCore.SIGNAL("clicked()"), self.click_NewAddressDialog)
|
||||
|
@ -228,12 +240,13 @@ class MyForm(QtGui.QMainWindow):
|
|||
shared.sqlSubmitQueue.put('')
|
||||
queryreturn = shared.sqlReturnQueue.get()
|
||||
shared.sqlLock.release()
|
||||
str_broadcast_subscribers = '[Broadcast subscribers]'
|
||||
for row in queryreturn:
|
||||
msgid, toAddress, fromAddress, subject, received, message, read = row
|
||||
|
||||
try:
|
||||
if toAddress == '[Broadcast subscribers]':
|
||||
toLabel = '[Broadcast subscribers]'
|
||||
if toAddress == str_broadcast_subscribers:
|
||||
toLabel = str_broadcast_subscribers
|
||||
else:
|
||||
toLabel = shared.config.get(toAddress, 'label')
|
||||
except:
|
||||
|
@ -459,6 +472,27 @@ class MyForm(QtGui.QMainWindow):
|
|||
#self.setWindowState(self.windowState() & ~QtCore.Qt.WindowMinimized | QtCore.Qt.WindowActive)
|
||||
#self.activateWindow()
|
||||
|
||||
|
||||
# pointer to the application
|
||||
#app = None
|
||||
|
||||
# show the application window
|
||||
def appIndicatorShow(self):
|
||||
if self.actionShow == None:
|
||||
return
|
||||
if not self.actionShow.isChecked():
|
||||
self.actionShow.setChecked(True)
|
||||
self.appIndicatorShowOrHideWindow()
|
||||
|
||||
# unchecks the show item on the application indicator
|
||||
def appIndicatorHide(self):
|
||||
if self.actionShow == None:
|
||||
return
|
||||
if self.actionShow.isChecked():
|
||||
self.actionShow.setChecked(False)
|
||||
self.appIndicatorShowOrHideWindow()
|
||||
|
||||
# application indicator show or hide
|
||||
"""# application indicator show or hide
|
||||
def appIndicatorShowBitmessage(self):
|
||||
#if self.actionShow == None:
|
||||
|
@ -470,33 +504,53 @@ class MyForm(QtGui.QMainWindow):
|
|||
else:
|
||||
self.appIndicatorShowOrHideWindow()"""
|
||||
|
||||
# returns the index of the oldest unread message
|
||||
def getUnreadMessageIndex(self):
|
||||
shared.sqlLock.acquire()
|
||||
shared.sqlSubmitQueue.put('''SELECT msgid, received, read FROM inbox where folder='inbox' ORDER BY received DESC ''')
|
||||
shared.sqlSubmitQueue.put('')
|
||||
queryreturn = shared.sqlReturnQueue.get()
|
||||
shared.sqlLock.release()
|
||||
i = 0
|
||||
index = 0
|
||||
for row in queryreturn:
|
||||
msgid, received, read = row
|
||||
if not read:
|
||||
index = i
|
||||
i = i + 1
|
||||
return index
|
||||
|
||||
# Show the program window and select inbox tab
|
||||
def appIndicatorInbox(self, mm_app, source_id):
|
||||
self.appIndicatorShow()
|
||||
# select inbox
|
||||
self.ui.tabWidget.setCurrentIndex(0)
|
||||
# select unread message
|
||||
self.ui.tableWidgetInbox.selectRow(self.getUnreadMessageIndex())
|
||||
self.tableWidgetInboxItemClicked()
|
||||
|
||||
# Show the program window and select send tab
|
||||
def appIndicatorSend(self):
|
||||
if not self.actionShow.isChecked():
|
||||
self.actionShow.setChecked(True)
|
||||
self.appIndicatorShowOrHideWindow()
|
||||
self.appIndicatorShow()
|
||||
self.ui.tabWidget.setCurrentIndex(1)
|
||||
|
||||
# Show the program window and select subscriptions tab
|
||||
def appIndicatorSubscribe(self):
|
||||
if not self.actionShow.isChecked():
|
||||
self.actionShow.setChecked(True)
|
||||
self.appIndicatorShowOrHideWindow()
|
||||
self.appIndicatorShow()
|
||||
self.ui.tabWidget.setCurrentIndex(4)
|
||||
|
||||
# Show the program window and select the address book tab
|
||||
def appIndicatorAddressBook(self):
|
||||
if not self.actionShow.isChecked():
|
||||
self.actionShow.setChecked(True)
|
||||
self.appIndicatorShowOrHideWindow()
|
||||
self.appIndicatorShow()
|
||||
self.ui.tabWidget.setCurrentIndex(5)
|
||||
|
||||
# create application indicator
|
||||
def createAppIndicator(self,app):
|
||||
self.tray = QSystemTrayIcon(QtGui.QIcon("images/can-icon-24px.png"), app)
|
||||
def appIndicatorInit(self,app):
|
||||
self.tray = QSystemTrayIcon(QtGui.QIcon("images/can-icon-24px-red.png"), app)
|
||||
if sys.platform[0:3] == 'win':
|
||||
traySignal = "activated(QSystemTrayIcon::ActivationReason)"
|
||||
QtCore.QObject.connect(self.tray, QtCore.SIGNAL(traySignal), self.__icon_activated)
|
||||
|
||||
m = QMenu()
|
||||
|
||||
self.actionStatus = QtGui.QAction('Not Connected',m,checkable=False)
|
||||
|
@ -509,7 +563,7 @@ class MyForm(QtGui.QMainWindow):
|
|||
|
||||
# show bitmessage
|
||||
self.actionShow = QtGui.QAction('Show Bitmessage',m,checkable=True)
|
||||
self.actionShow.setChecked(True)
|
||||
self.actionShow.setChecked(not shared.config.getboolean('bitmessagesettings', 'startintray'))
|
||||
self.actionShow.triggered.connect(self.appIndicatorShowOrHideWindow)
|
||||
if not sys.platform[0:3] == 'win':
|
||||
m.addAction(self.actionShow)
|
||||
|
@ -535,15 +589,133 @@ class MyForm(QtGui.QMainWindow):
|
|||
m.addAction(actionSeparator)
|
||||
|
||||
# Quit
|
||||
m.addAction("Quit", self.close)
|
||||
m.addAction("Quit", self.quit)
|
||||
|
||||
self.tray.setContextMenu(m)
|
||||
self.tray.show()
|
||||
if shared.config.getboolean('bitmessagesettings', 'startintray'):
|
||||
#myapp.trayIcon.show()#This option seems to have been obsoleted by https://github.com/Bitmessage/PyBitmessage/pull/133/files
|
||||
self.actionShow.setChecked(False)
|
||||
self.appIndicatorShowOrHideWindow()
|
||||
#if sys.platform[0:3] == 'win':
|
||||
# myapp.setWindowFlags(Qt.ToolTip)
|
||||
|
||||
# Ubuntu Messaging menu object
|
||||
mmapp = None
|
||||
|
||||
# is the operating system Ubuntu?
|
||||
def isUbuntu(self):
|
||||
for entry in platform.uname():
|
||||
if "Ubuntu" in entry:
|
||||
return True
|
||||
return False
|
||||
|
||||
# returns the number of unread messages and subscriptions
|
||||
def getUnread(self):
|
||||
str_broadcast_subscribers = '[Broadcast subscribers]'
|
||||
|
||||
unreadMessages = 0
|
||||
unreadSubscriptions = 0
|
||||
|
||||
shared.sqlLock.acquire()
|
||||
shared.sqlSubmitQueue.put('''SELECT msgid, toaddress, read FROM inbox where folder='inbox' ''')
|
||||
shared.sqlSubmitQueue.put('')
|
||||
queryreturn = shared.sqlReturnQueue.get()
|
||||
shared.sqlLock.release()
|
||||
for row in queryreturn:
|
||||
msgid, toAddress, read = row
|
||||
|
||||
try:
|
||||
if toAddress == str_broadcast_subscribers:
|
||||
toLabel = str_broadcast_subscribers
|
||||
else:
|
||||
toLabel = shared.config.get(toAddress, 'label')
|
||||
except:
|
||||
toLabel = ''
|
||||
if toLabel == '':
|
||||
toLabel = toAddress
|
||||
|
||||
if not read:
|
||||
if toLabel == str_broadcast_subscribers:
|
||||
# increment the unread subscriptions
|
||||
unreadSubscriptions = unreadSubscriptions + 1
|
||||
else:
|
||||
# increment the unread messages
|
||||
unreadMessages = unreadMessages + 1
|
||||
return unreadMessages, unreadSubscriptions
|
||||
|
||||
# show the number of unread messages and subscriptions on the messaging menu
|
||||
def ubuntuMessagingMenuUnread(self, drawAttention):
|
||||
unreadMessages, unreadSubscriptions = self.getUnread()
|
||||
# unread messages
|
||||
if unreadMessages > 0:
|
||||
self.mmapp.append_source("Messages", None, "Messages (" + str(unreadMessages) + ")")
|
||||
if drawAttention:
|
||||
self.mmapp.draw_attention("Messages")
|
||||
|
||||
# unread subscriptions
|
||||
if unreadSubscriptions > 0:
|
||||
self.mmapp.append_source("Subscriptions", None, "Subscriptions (" + str(unreadSubscriptions) + ")")
|
||||
if drawAttention:
|
||||
self.mmapp.draw_attention("Subscriptions")
|
||||
|
||||
# initialise the Ubuntu messaging menu
|
||||
def ubuntuMessagingMenuInit(self):
|
||||
global withMessagingMenu
|
||||
|
||||
# if this isn't ubuntu then don't do anything
|
||||
if not self.isUbuntu():
|
||||
return
|
||||
|
||||
# has messageing menu been installed
|
||||
if not withMessagingMenu:
|
||||
print 'WARNING: MessagingMenu is not available. Is libmessaging-menu-dev installed?'
|
||||
return
|
||||
|
||||
# create the menu server
|
||||
if withMessagingMenu:
|
||||
try:
|
||||
self.mmapp = MessagingMenu.App(desktop_id='pybitmessage.desktop')
|
||||
self.mmapp.register()
|
||||
self.mmapp.connect('activate-source', self.appIndicatorInbox)
|
||||
self.ubuntuMessagingMenuUnread(True)
|
||||
except Exception:
|
||||
withMessagingMenu = False
|
||||
print 'WARNING: messaging menu disabled'
|
||||
|
||||
# update the Ubuntu messaging menu
|
||||
def ubuntuMessagingMenuUpdate(self, drawAttention):
|
||||
global withMessagingMenu
|
||||
|
||||
# if this isn't ubuntu then don't do anything
|
||||
if not self.isUbuntu():
|
||||
return
|
||||
|
||||
# has messageing menu been installed
|
||||
if not withMessagingMenu:
|
||||
print 'WARNING: messaging menu disabled or libmessaging-menu-dev not installed'
|
||||
return
|
||||
|
||||
# Remove previous messages and subscriptions entries, then recreate them
|
||||
# There might be a better way to do it than this
|
||||
if self.mmapp.has_source("Messages"):
|
||||
self.mmapp.remove_source("Messages")
|
||||
|
||||
if self.mmapp.has_source("Subscriptions"):
|
||||
self.mmapp.remove_source("Subscriptions")
|
||||
|
||||
# update the menu entries
|
||||
self.ubuntuMessagingMenuUnread(drawAttention)
|
||||
|
||||
# initialise the message notifier
|
||||
def notifierInit(self):
|
||||
global withMessagingMenu
|
||||
if withMessagingMenu:
|
||||
Notify.init('pybitmessage')
|
||||
|
||||
# shows a notification
|
||||
def notifierShow(self, title, subtitle):
|
||||
global withMessagingMenu
|
||||
if withMessagingMenu:
|
||||
n = Notify.Notification.new(title, subtitle,'notification-message-email')
|
||||
n.show()
|
||||
return
|
||||
# Show with tray
|
||||
self.trayIcon.showMessage(title, subtitle, 1, 2000)
|
||||
|
||||
def tableWidgetInboxKeyPressEvent(self,event):
|
||||
if event.key() == QtCore.Qt.Key_Delete:
|
||||
|
@ -598,10 +770,7 @@ class MyForm(QtGui.QMainWindow):
|
|||
if shared.config.getboolean('bitmessagesettings', 'minimizetotray') and not 'darwin' in sys.platform:
|
||||
if event.type() == QtCore.QEvent.WindowStateChange:
|
||||
if self.windowState() & QtCore.Qt.WindowMinimized:
|
||||
self.hide()
|
||||
|
||||
#self.trayIcon.show() #This may have been obsoleted by https://github.com/Bitmessage/PyBitmessage/issues/135
|
||||
#self.hidden = True
|
||||
self.appIndicatorHide()
|
||||
if 'win32' in sys.platform or 'win64' in sys.platform:
|
||||
self.setWindowFlags(Qt.ToolTip)
|
||||
elif event.oldState() & QtCore.Qt.WindowMinimized:
|
||||
|
@ -688,27 +857,47 @@ class MyForm(QtGui.QMainWindow):
|
|||
elif len(shared.connectedHostsList) == 0:
|
||||
self.setStatusIcon('red')
|
||||
|
||||
# Indicates whether or not there is a connection to the Bitmessage network
|
||||
connected = False
|
||||
|
||||
def setStatusIcon(self,color):
|
||||
global withMessagingMenu
|
||||
#print 'setting status icon color'
|
||||
if color == 'red':
|
||||
self.ui.pushButtonStatusIcon.setIcon(QIcon(":/newPrefix/images/redicon.png"))
|
||||
shared.statusIconColor = 'red'
|
||||
#if self.actionStatus != None:
|
||||
# if the connection is lost then show a notification
|
||||
if self.connected:
|
||||
self.notifierShow('PyBitmessage','Connection lost')
|
||||
self.connected = False
|
||||
|
||||
if self.actionStatus != None:
|
||||
self.actionStatus.setText('Not Connected')
|
||||
self.tray.setIcon(QtGui.QIcon("images/can-icon-24px-red.png"))
|
||||
self.trayIcon.show()
|
||||
if color == 'yellow':
|
||||
if self.statusBar().currentMessage() == 'Warning: You are currently not connected. Bitmessage will do the work necessary to send the message but it won\'t send until you connect.':
|
||||
self.statusBar().showMessage('')
|
||||
self.ui.pushButtonStatusIcon.setIcon(QIcon(":/newPrefix/images/yellowicon.png"))
|
||||
shared.statusIconColor = 'yellow'
|
||||
#if self.actionStatus != None:
|
||||
# if a new connection has been established then show a notification
|
||||
if not self.connected:
|
||||
self.notifierShow('PyBitmessage','Connected')
|
||||
self.connected = True
|
||||
|
||||
if self.actionStatus != None:
|
||||
self.actionStatus.setText('Connected')
|
||||
self.tray.setIcon(QtGui.QIcon("images/can-icon-24px-yellow.png"))
|
||||
if color == 'green':
|
||||
if self.statusBar().currentMessage() == 'Warning: You are currently not connected. Bitmessage will do the work necessary to send the message but it won\'t send until you connect.':
|
||||
self.statusBar().showMessage('')
|
||||
self.ui.pushButtonStatusIcon.setIcon(QIcon(":/newPrefix/images/greenicon.png"))
|
||||
shared.statusIconColor = 'green'
|
||||
#if self.actionStatus != None:
|
||||
self.connected = True
|
||||
|
||||
if self.actionStatus != None:
|
||||
self.actionStatus.setText('Connected')
|
||||
self.tray.setIcon(QtGui.QIcon("images/can-icon-24px-green.png"))
|
||||
|
||||
def updateSentItemStatusByHash(self,toRipe,textToDisplay):
|
||||
for i in range(self.ui.tableWidgetSent.rowCount()):
|
||||
|
@ -1072,11 +1261,11 @@ class MyForm(QtGui.QMainWindow):
|
|||
if fromLabel == '':
|
||||
newItem = QtGui.QTableWidgetItem(unicode(fromAddress,'utf-8'))
|
||||
if shared.config.getboolean('bitmessagesettings', 'showtraynotifications'):
|
||||
self.trayIcon.showMessage('New Message', 'New message from '+ fromAddress, 1, 2000)
|
||||
self.notifierShow('New Message', 'From '+ fromAddress)
|
||||
else:
|
||||
newItem = QtGui.QTableWidgetItem(unicode(fromLabel,'utf-8'))
|
||||
if shared.config.getboolean('bitmessagesettings', 'showtraynotifications'):
|
||||
self.trayIcon.showMessage('New Message', 'New message from '+fromLabel, 1, 2000)
|
||||
self.notifierShow('New Message', 'From ' + fromLabel)
|
||||
newItem.setData(Qt.UserRole,str(fromAddress))
|
||||
newItem.setFont(font)
|
||||
self.ui.tableWidgetInbox.setItem(0,1,newItem)
|
||||
|
@ -1096,6 +1285,7 @@ class MyForm(QtGui.QMainWindow):
|
|||
else:
|
||||
self.ui.textEditInboxMessage.setPlainText(self.ui.tableWidgetInbox.item(0,2).data(Qt.UserRole).toPyObject())"""
|
||||
self.ui.tableWidgetInbox.setSortingEnabled(True)
|
||||
self.ubuntuMessagingMenuUpdate(True)
|
||||
|
||||
def click_pushButtonAddAddressBook(self):
|
||||
self.NewSubscriptionDialogInstance = NewSubscriptionDialog(self)
|
||||
|
@ -1400,25 +1590,43 @@ class MyForm(QtGui.QMainWindow):
|
|||
else:
|
||||
print 'new address dialog box rejected'
|
||||
|
||||
def closeEvent(self, event):
|
||||
|
||||
# Quit selected from menu or application indicator
|
||||
def quit(self):
|
||||
'''quit_msg = "Are you sure you want to exit Bitmessage?"
|
||||
reply = QtGui.QMessageBox.question(self, 'Message',
|
||||
quit_msg, QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)
|
||||
|
||||
if reply == QtGui.QMessageBox.Yes:
|
||||
event.accept()
|
||||
else:
|
||||
event.ignore()'''
|
||||
if reply is QtGui.QMessageBox.No:
|
||||
return
|
||||
'''
|
||||
shared.doCleanShutdown()
|
||||
#self.trayIcon.hide()
|
||||
self.tray.hide()
|
||||
# unregister the messaging system
|
||||
if self.mmapp is not None:
|
||||
self.mmapp.unregister()
|
||||
self.trayIcon.hide()
|
||||
self.statusBar().showMessage('All done. Closing user interface...')
|
||||
event.accept()
|
||||
shared.printLock.acquire()
|
||||
print 'Done. (passed event.accept())'
|
||||
shared.printLock.release()
|
||||
os._exit(0)
|
||||
|
||||
# window close event
|
||||
def closeEvent(self, event):
|
||||
self.appIndicatorHide()
|
||||
minimizeonclose = False
|
||||
|
||||
try:
|
||||
minimizeonclose = shared.config.getboolean('bitmessagesettings', 'minimizeonclose')
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if minimizeonclose:
|
||||
# minimize the application
|
||||
event.ignore()
|
||||
else:
|
||||
# quit the application
|
||||
event.accept()
|
||||
self.quit()
|
||||
|
||||
def on_action_InboxMessageForceHtml(self):
|
||||
currentInboxRow = self.ui.tableWidgetInbox.currentRow()
|
||||
lines = self.ui.tableWidgetInbox.item(currentInboxRow,2).data(Qt.UserRole).toPyObject().split('\n')
|
||||
|
@ -2045,12 +2253,21 @@ class UISignaler(QThread):
|
|||
else:
|
||||
sys.stderr.write('Command sent to UISignaler not recognized: %s\n' % command)
|
||||
|
||||
|
||||
def run():
|
||||
app = QtGui.QApplication(sys.argv)
|
||||
app.setStyleSheet("QStatusBar::item { border: 0px solid black }")
|
||||
myapp = MyForm()
|
||||
if not shared.config.getboolean('bitmessagesettings', 'startintray'):
|
||||
|
||||
if shared.config.getboolean('bitmessagesettings', 'startintray'):
|
||||
if not myapp.isUbuntu():
|
||||
myapp.trayIcon.show()
|
||||
if 'win32' in sys.platform or 'win64' in sys.platform:
|
||||
myapp.setWindowFlags(Qt.ToolTip)
|
||||
else:
|
||||
myapp.show()
|
||||
myapp.createAppIndicator(app)
|
||||
|
||||
myapp.appIndicatorInit(app)
|
||||
myapp.ubuntuMessagingMenuInit()
|
||||
myapp.notifierInit()
|
||||
|
||||
sys.exit(app.exec_())
|
||||
|
|
|
@ -515,7 +515,7 @@ class Ui_MainWindow(object):
|
|||
self.menuHelp.setTitle(QtGui.QApplication.translate("MainWindow", "Help", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.actionImport_keys.setText(QtGui.QApplication.translate("MainWindow", "Import keys", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.actionManageKeys.setText(QtGui.QApplication.translate("MainWindow", "Manage keys", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.actionExit.setText(QtGui.QApplication.translate("MainWindow", "Exit", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.actionExit.setText(QtGui.QApplication.translate("MainWindow", "Quit", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.actionHelp.setText(QtGui.QApplication.translate("MainWindow", "Help", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.actionAbout.setText(QtGui.QApplication.translate("MainWindow", "About", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.actionSettings.setText(QtGui.QApplication.translate("MainWindow", "Settings", None, QtGui.QApplication.UnicodeUTF8))
|
||||
|
|
|
@ -979,7 +979,7 @@ p, li { white-space: pre-wrap; }
|
|||
</action>
|
||||
<action name="actionExit">
|
||||
<property name="text">
|
||||
<string>Exit</string>
|
||||
<string>Quit</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionHelp">
|
||||
|
|
BIN
src/images/can-icon-24px-green.png
Normal file
BIN
src/images/can-icon-24px-green.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 885 B |
BIN
src/images/can-icon-24px-red.png
Normal file
BIN
src/images/can-icon-24px-red.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 867 B |
BIN
src/images/can-icon-24px-yellow.png
Normal file
BIN
src/images/can-icon-24px-yellow.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 872 B |
61
src/singleton.py
Normal file
61
src/singleton.py
Normal file
|
@ -0,0 +1,61 @@
|
|||
#! /usr/bin/env python
|
||||
|
||||
import sys
|
||||
import os
|
||||
import errno
|
||||
import tempfile
|
||||
from multiprocessing import Process
|
||||
|
||||
|
||||
class singleinstance:
|
||||
"""
|
||||
Implements a single instance application by creating a lock file based on the full path to the script file.
|
||||
|
||||
This is based upon the singleton class from tendo https://github.com/pycontribs/tendo
|
||||
which is under the Python Software Foundation License version 2
|
||||
"""
|
||||
def __init__(self, flavor_id=""):
|
||||
import sys
|
||||
self.initialized = False
|
||||
basename = os.path.splitext(os.path.abspath(sys.argv[0]))[0].replace("/", "-").replace(":", "").replace("\\", "-") + '-%s' % flavor_id + '.lock'
|
||||
self.lockfile = os.path.normpath(tempfile.gettempdir() + '/' + basename)
|
||||
|
||||
if sys.platform == 'win32':
|
||||
try:
|
||||
# file already exists, we try to remove (in case previous execution was interrupted)
|
||||
if os.path.exists(self.lockfile):
|
||||
os.unlink(self.lockfile)
|
||||
self.fd = os.open(self.lockfile, os.O_CREAT | os.O_EXCL | os.O_RDWR)
|
||||
except OSError:
|
||||
type, e, tb = sys.exc_info()
|
||||
if e.errno == 13:
|
||||
print 'Another instance of this application is already running'
|
||||
sys.exit(-1)
|
||||
print(e.errno)
|
||||
raise
|
||||
else: # non Windows
|
||||
import fcntl
|
||||
self.fp = open(self.lockfile, 'w')
|
||||
try:
|
||||
fcntl.lockf(self.fp, fcntl.LOCK_EX | fcntl.LOCK_NB)
|
||||
except IOError:
|
||||
print 'Another instance of this application is already running'
|
||||
sys.exit(-1)
|
||||
self.initialized = True
|
||||
|
||||
def __del__(self):
|
||||
import sys
|
||||
if not self.initialized:
|
||||
return
|
||||
try:
|
||||
if sys.platform == 'win32':
|
||||
if hasattr(self, 'fd'):
|
||||
os.close(self.fd)
|
||||
os.unlink(self.lockfile)
|
||||
else:
|
||||
import fcntl
|
||||
fcntl.lockf(self.fp, fcntl.LOCK_UN)
|
||||
if os.path.isfile(self.lockfile):
|
||||
os.unlink(self.lockfile)
|
||||
except Exception, e:
|
||||
sys.exit(-1)
|
Reference in New Issue
Block a user