2013-06-12 10:05:20 +02:00
try :
import locale
except :
pass
2013-05-11 18:33:16 +02:00
withMessagingMenu = False
2013-05-10 21:47:01 +02:00
try :
from gi . repository import MessagingMenu
2013-05-11 18:33:16 +02:00
from gi . repository import Notify
withMessagingMenu = True
2013-05-10 21:47:01 +02:00
except ImportError :
MessagingMenu = None
2013-05-02 17:53:54 +02:00
from addresses import *
import shared
from bitmessageui import *
2013-07-07 17:34:43 +02:00
from namecoin import namecoinConnection , ensureNamecoinOptions
2013-05-02 17:53:54 +02:00
from newaddressdialog import *
2013-12-01 05:15:18 +01:00
from addaddressdialog import *
2013-05-02 17:53:54 +02:00
from newsubscriptiondialog import *
from regenerateaddresses import *
2013-07-22 07:10:22 +02:00
from newchandialog import *
2013-05-02 17:53:54 +02:00
from specialaddressbehavior import *
from settings import *
from about import *
from help import *
from iconglossary import *
2013-07-24 17:46:28 +02:00
from connect import *
2013-05-02 17:53:54 +02:00
import sys
from time import strftime , localtime , gmtime
import time
import os
2013-11-02 00:25:24 +01:00
import hashlib
2013-05-02 17:53:54 +02:00
from pyelliptic . openssl import OpenSSL
2013-05-03 21:53:38 +02:00
import pickle
2013-05-14 17:44:51 +02:00
import platform
2014-01-28 20:32:16 +01:00
import textwrap
2013-07-15 21:45:03 +02:00
import debug
from debug import logger
2013-07-15 18:58:22 +02:00
import subprocess
2013-07-31 23:25:34 +02:00
import datetime
2013-08-27 02:01:19 +02:00
from helper_sql import *
2013-05-02 17:53:54 +02:00
2013-06-25 22:26:12 +02:00
try :
from PyQt4 import QtCore , QtGui
from PyQt4 . QtCore import *
from PyQt4 . QtGui import *
2013-07-15 18:01:12 +02:00
2013-06-25 22:26:12 +02:00
except Exception as err :
print ' PyBitmessage requires PyQt unless you want to run it as a daemon and interact with it using the API. 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 ( )
try :
_encoding = QtGui . QApplication . UnicodeUTF8
except AttributeError :
print ' QtGui.QApplication.UnicodeUTF8 error: ' , err
def _translate ( context , text ) :
return QtGui . QApplication . translate ( context , text )
2013-11-07 20:35:11 +01:00
2013-08-27 11:47:14 +02:00
def identiconize ( address ) :
2013-09-18 17:39:45 +02:00
size = 48
2013-09-16 21:08:55 +02:00
2013-09-18 17:39:45 +02:00
# If you include another identicon library, please generate an
# example identicon with the following md5 hash:
# 3fd4bf901b9d4ea1394f0fb358725b28
2013-09-17 10:55:26 +02:00
try :
2013-11-02 00:25:24 +01:00
identicon_lib = shared . config . get ( ' bitmessagesettings ' , ' identiconlib ' )
2013-09-17 10:55:26 +02:00
except :
2013-11-02 00:25:24 +01:00
# default to qidenticon_two_x
identicon_lib = ' qidenticon_two_x '
# As an 'identiconsuffix' you could put "@bitmessge.ch" or "@bm.addr" to make it compatible with other identicon generators. (Note however, that E-Mail programs might convert the BM-address to lowercase first.)
# It can be used as a pseudo-password to salt the generation of the identicons to decrease the risk
# of attacks where someone creates an address to mimic someone else's identicon.
identiconsuffix = shared . config . get ( ' bitmessagesettings ' , ' identiconsuffix ' )
2013-09-17 10:55:26 +02:00
2013-11-02 00:25:24 +01:00
if not shared . config . getboolean ( ' bitmessagesettings ' , ' useidenticons ' ) :
idcon = QtGui . QIcon ( )
return idcon
2013-09-19 21:28:22 +02:00
2013-09-17 10:55:26 +02:00
if ( identicon_lib [ : len ( ' qidenticon ' ) ] == ' qidenticon ' ) :
# print identicon_lib
2013-09-16 21:08:55 +02:00
# originally by:
# :Author:Shin Adachi <shn@glucose.jp>
# Licesensed under FreeBSD License.
2013-09-19 21:28:22 +02:00
# stripped from PIL and uses QT instead (by sendiulo, same license)
import qidenticon
2013-09-17 10:55:26 +02:00
hash = hashlib . md5 ( addBMIfNotPresent ( address ) + identiconsuffix ) . hexdigest ( )
use_two_colors = ( identicon_lib [ : len ( ' qidenticon_two ' ) ] == ' qidenticon_two ' )
2013-09-18 17:39:45 +02:00
opacity = int ( not ( ( identicon_lib == ' qidenticon_x ' ) | ( identicon_lib == ' qidenticon_two_x ' ) | ( identicon_lib == ' qidenticon_b ' ) | ( identicon_lib == ' qidenticon_two_b ' ) ) ) * 255
2013-09-17 10:55:26 +02:00
penwidth = 0
2013-09-18 17:39:45 +02:00
image = qidenticon . render_identicon ( int ( hash , 16 ) , size , use_two_colors , opacity , penwidth )
# filename = './images/identicons/'+hash+'.png'
# image.save(filename)
2013-09-21 13:21:36 +02:00
idcon = QtGui . QIcon ( )
2013-09-18 17:39:45 +02:00
idcon . addPixmap ( image , QtGui . QIcon . Normal , QtGui . QIcon . Off )
2013-09-16 21:08:55 +02:00
return idcon
2013-09-17 10:55:26 +02:00
elif identicon_lib == ' pydenticon ' :
2013-09-16 21:08:55 +02:00
# print identicon_lib
2013-09-17 10:55:26 +02:00
# Here you could load pydenticon.py (just put it in the "src" folder of your Bitmessage source)
2013-09-16 21:08:55 +02:00
from pydenticon import Pydenticon
2013-09-17 10:55:26 +02:00
# It is not included in the source, because it is licensed under GPLv3
# GPLv3 is a copyleft license that would influence our licensing
# Find the source here: http://boottunes.googlecode.com/svn-history/r302/trunk/src/pydenticon.py
# note that it requires PIL to be installed: http://www.pythonware.com/products/pil/
2013-09-18 17:39:45 +02:00
idcon_render = Pydenticon ( addBMIfNotPresent ( address ) + identiconsuffix , size * 3 )
2013-09-17 10:55:26 +02:00
rendering = idcon_render . _render ( )
data = rendering . convert ( " RGBA " ) . tostring ( " raw " , " RGBA " )
qim = QImage ( data , size , size , QImage . Format_ARGB32 )
pix = QPixmap . fromImage ( qim )
2013-09-16 21:08:55 +02:00
idcon = QtGui . QIcon ( )
idcon . addPixmap ( pix , QtGui . QIcon . Normal , QtGui . QIcon . Off )
return idcon
2013-09-19 21:28:22 +02:00
2013-11-02 00:25:24 +01:00
def avatarize ( address ) :
2013-09-21 13:21:36 +02:00
"""
loads a supported image for the given address ' hash form ' avatars ' folder
falls back to default avatar if ' default.* ' file exists
2013-11-02 00:25:24 +01:00
falls back to identiconize ( address )
2013-09-21 13:21:36 +02:00
"""
2013-09-19 21:28:22 +02:00
idcon = QtGui . QIcon ( )
2013-11-02 00:25:24 +01:00
hash = hashlib . md5 ( addBMIfNotPresent ( address ) ) . hexdigest ( )
str_broadcast_subscribers = ' [Broadcast subscribers] '
if address == str_broadcast_subscribers :
# don't hash [Broadcast subscribers]
hash = address
# http://pyqt.sourceforge.net/Docs/PyQt4/qimagereader.html#supportedImageFormats
# print QImageReader.supportedImageFormats ()
# QImageReader.supportedImageFormats ()
extensions = [ ' PNG ' , ' GIF ' , ' JPG ' , ' JPEG ' , ' SVG ' , ' BMP ' , ' MNG ' , ' PBM ' , ' PGM ' , ' PPM ' , ' TIFF ' , ' XBM ' , ' XPM ' , ' TGA ' ]
# try to find a specific avatar
for ext in extensions :
lower_hash = shared . appdata + ' avatars/ ' + hash + ' . ' + ext . lower ( )
upper_hash = shared . appdata + ' avatars/ ' + hash + ' . ' + ext . upper ( )
if os . path . isfile ( lower_hash ) :
# print 'found avatar of ', address
idcon . addFile ( lower_hash )
return idcon
elif os . path . isfile ( upper_hash ) :
# print 'found avatar of ', address
idcon . addFile ( upper_hash )
return idcon
# if we haven't found any, try to find a default avatar
for ext in extensions :
lower_default = shared . appdata + ' avatars/ ' + ' default. ' + ext . lower ( )
upper_default = shared . appdata + ' avatars/ ' + ' default. ' + ext . upper ( )
if os . path . isfile ( lower_default ) :
default = lower_default
idcon . addFile ( lower_default )
return idcon
elif os . path . isfile ( upper_default ) :
default = upper_default
idcon . addFile ( upper_default )
return idcon
# If no avatar is found
return identiconize ( address )
2013-05-02 17:53:54 +02:00
class MyForm ( QtGui . QMainWindow ) :
2013-05-10 21:47:01 +02:00
2013-07-15 18:01:12 +02:00
# sound type constants
SOUND_NONE = 0
SOUND_KNOWN = 1
SOUND_UNKNOWN = 2
SOUND_CONNECTED = 3
SOUND_DISCONNECTED = 4
SOUND_CONNECTION_GREEN = 5
2013-07-31 23:25:34 +02:00
# the last time that a message arrival sound was played
lastSoundTime = datetime . datetime . now ( ) - datetime . timedelta ( days = 1 )
# the maximum frequency of message sounds in seconds
maxSoundFrequencySec = 60
2013-05-14 17:06:01 +02:00
str_broadcast_subscribers = ' [Broadcast subscribers] '
2013-07-22 07:10:22 +02:00
str_chan = ' [chan] '
2013-05-14 17:06:01 +02:00
2013-11-07 20:35:11 +01:00
def init_file_menu ( self ) :
2013-06-12 23:12:32 +02:00
QtCore . QObject . connect ( self . ui . actionExit , QtCore . SIGNAL (
" triggered() " ) , self . quit )
QtCore . QObject . connect ( self . ui . actionManageKeys , QtCore . SIGNAL (
" triggered() " ) , self . click_actionManageKeys )
2013-11-07 20:35:11 +01:00
QtCore . QObject . connect ( self . ui . actionDeleteAllTrashedMessages ,
QtCore . SIGNAL (
" triggered() " ) ,
self . click_actionDeleteAllTrashedMessages )
QtCore . QObject . connect ( self . ui . actionRegenerateDeterministicAddresses ,
QtCore . SIGNAL (
" triggered() " ) ,
self . click_actionRegenerateDeterministicAddresses )
2013-07-22 07:10:22 +02:00
QtCore . QObject . connect ( self . ui . actionJoinChan , QtCore . SIGNAL (
2013-11-07 20:35:11 +01:00
" triggered() " ) ,
self . click_actionJoinChan ) # also used for creating chans.
2013-06-12 23:12:32 +02:00
QtCore . QObject . connect ( self . ui . pushButtonNewAddress , QtCore . SIGNAL (
" clicked() " ) , self . click_NewAddressDialog )
QtCore . QObject . connect ( self . ui . comboBoxSendFrom , QtCore . SIGNAL (
" activated(int) " ) , self . redrawLabelFrom )
QtCore . QObject . connect ( self . ui . pushButtonAddAddressBook , QtCore . SIGNAL (
" clicked() " ) , self . click_pushButtonAddAddressBook )
QtCore . QObject . connect ( self . ui . pushButtonAddSubscription , QtCore . SIGNAL (
" clicked() " ) , self . click_pushButtonAddSubscription )
QtCore . QObject . connect ( self . ui . pushButtonAddBlacklist , QtCore . SIGNAL (
" clicked() " ) , self . click_pushButtonAddBlacklist )
QtCore . QObject . connect ( self . ui . pushButtonSend , QtCore . SIGNAL (
" clicked() " ) , self . click_pushButtonSend )
2013-11-07 20:35:11 +01:00
QtCore . QObject . connect ( self . ui . pushButtonLoadFromAddressBook ,
QtCore . SIGNAL (
" clicked() " ) ,
self . click_pushButtonLoadFromAddressBook )
2013-07-04 22:06:30 +02:00
QtCore . QObject . connect ( self . ui . pushButtonFetchNamecoinID , QtCore . SIGNAL (
" clicked() " ) , self . click_pushButtonFetchNamecoinID )
2013-06-12 23:12:32 +02:00
QtCore . QObject . connect ( self . ui . radioButtonBlacklist , QtCore . SIGNAL (
" clicked() " ) , self . click_radioButtonBlacklist )
QtCore . QObject . connect ( self . ui . radioButtonWhitelist , QtCore . SIGNAL (
" clicked() " ) , self . click_radioButtonWhitelist )
QtCore . QObject . connect ( self . ui . pushButtonStatusIcon , QtCore . SIGNAL (
" clicked() " ) , self . click_pushButtonStatusIcon )
QtCore . QObject . connect ( self . ui . actionSettings , QtCore . SIGNAL (
" triggered() " ) , self . click_actionSettings )
QtCore . QObject . connect ( self . ui . actionAbout , QtCore . SIGNAL (
" triggered() " ) , self . click_actionAbout )
QtCore . QObject . connect ( self . ui . actionHelp , QtCore . SIGNAL (
" triggered() " ) , self . click_actionHelp )
2013-11-07 20:35:11 +01:00
def init_inbox_popup_menu ( self ) :
2013-06-12 23:12:32 +02:00
# Popup menu for the Inbox tab
2013-05-02 17:53:54 +02:00
self . ui . inboxContextMenuToolbar = QtGui . QToolBar ( )
2013-11-07 20:35:11 +01:00
# Actions
2013-06-13 09:59:40 +02:00
self . actionReply = self . ui . inboxContextMenuToolbar . addAction ( _translate (
" MainWindow " , " Reply " ) , self . on_action_InboxReply )
2013-11-07 20:35:11 +01:00
self . actionAddSenderToAddressBook = self . ui . inboxContextMenuToolbar . addAction (
_translate (
" MainWindow " , " Add sender to your Address Book " ) ,
self . on_action_InboxAddSenderToAddressBook )
2013-06-12 23:12:32 +02:00
self . actionTrashInboxMessage = self . ui . inboxContextMenuToolbar . addAction (
2013-11-07 20:35:11 +01:00
_translate ( " MainWindow " , " Move to Trash " ) ,
self . on_action_InboxTrash )
self . actionForceHtml = self . ui . inboxContextMenuToolbar . addAction (
_translate (
" MainWindow " , " View HTML code as formatted text " ) ,
self . on_action_InboxMessageForceHtml )
self . actionSaveMessageAs = self . ui . inboxContextMenuToolbar . addAction (
_translate (
" MainWindow " , " Save message as... " ) ,
self . on_action_InboxSaveMessageAs )
self . actionMarkUnread = self . ui . inboxContextMenuToolbar . addAction (
_translate (
" MainWindow " , " Mark Unread " ) , self . on_action_InboxMarkUnread )
2013-06-12 23:12:32 +02:00
self . ui . tableWidgetInbox . setContextMenuPolicy (
QtCore . Qt . CustomContextMenu )
self . connect ( self . ui . tableWidgetInbox , QtCore . SIGNAL (
2013-11-07 20:35:11 +01:00
' customContextMenuRequested(const QPoint&) ' ) ,
self . on_context_menuInbox )
2013-06-12 23:12:32 +02:00
self . popMenuInbox = QtGui . QMenu ( self )
self . popMenuInbox . addAction ( self . actionForceHtml )
2013-07-26 04:00:54 +02:00
self . popMenuInbox . addAction ( self . actionMarkUnread )
2013-05-02 17:53:54 +02:00
self . popMenuInbox . addSeparator ( )
2013-06-12 23:12:32 +02:00
self . popMenuInbox . addAction ( self . actionReply )
self . popMenuInbox . addAction ( self . actionAddSenderToAddressBook )
2013-05-02 17:53:54 +02:00
self . popMenuInbox . addSeparator ( )
2013-11-07 20:35:11 +01:00
self . popMenuInbox . addAction ( self . actionSaveMessageAs )
self . popMenuInbox . addAction ( self . actionTrashInboxMessage )
2013-05-02 17:53:54 +02:00
2013-11-07 20:35:11 +01:00
def init_identities_popup_menu ( self ) :
2013-06-12 23:12:32 +02:00
# Popup menu for the Your Identities tab
2013-05-02 17:53:54 +02:00
self . ui . addressContextMenuToolbar = QtGui . QToolBar ( )
2013-11-07 20:35:11 +01:00
# Actions
2013-06-13 09:59:40 +02:00
self . actionNew = self . ui . addressContextMenuToolbar . addAction ( _translate (
2013-06-12 23:12:32 +02:00
" MainWindow " , " New " ) , self . on_action_YourIdentitiesNew )
2013-11-07 20:35:11 +01:00
self . actionEnable = self . ui . addressContextMenuToolbar . addAction (
_translate (
" MainWindow " , " Enable " ) , self . on_action_YourIdentitiesEnable )
self . actionDisable = self . ui . addressContextMenuToolbar . addAction (
_translate (
" MainWindow " , " Disable " ) , self . on_action_YourIdentitiesDisable )
self . actionSetAvatar = self . ui . addressContextMenuToolbar . addAction (
_translate (
" MainWindow " , " Set avatar... " ) ,
self . on_action_YourIdentitiesSetAvatar )
self . actionClipboard = self . ui . addressContextMenuToolbar . addAction (
_translate (
" MainWindow " , " Copy address to clipboard " ) ,
self . on_action_YourIdentitiesClipboard )
self . actionSpecialAddressBehavior = self . ui . addressContextMenuToolbar . addAction (
_translate (
" MainWindow " , " Special address behavior... " ) ,
self . on_action_SpecialAddressBehaviorDialog )
2013-06-12 23:12:32 +02:00
self . ui . tableWidgetYourIdentities . setContextMenuPolicy (
QtCore . Qt . CustomContextMenu )
self . connect ( self . ui . tableWidgetYourIdentities , QtCore . SIGNAL (
2013-11-07 20:35:11 +01:00
' customContextMenuRequested(const QPoint&) ' ) ,
self . on_context_menuYourIdentities )
2013-06-12 23:12:32 +02:00
self . popMenu = QtGui . QMenu ( self )
self . popMenu . addAction ( self . actionNew )
2013-05-02 17:53:54 +02:00
self . popMenu . addSeparator ( )
2013-06-12 23:12:32 +02:00
self . popMenu . addAction ( self . actionClipboard )
2013-05-02 17:53:54 +02:00
self . popMenu . addSeparator ( )
2013-06-12 23:12:32 +02:00
self . popMenu . addAction ( self . actionEnable )
self . popMenu . addAction ( self . actionDisable )
2013-09-20 14:30:53 +02:00
self . popMenu . addAction ( self . actionSetAvatar )
2013-06-12 23:12:32 +02:00
self . popMenu . addAction ( self . actionSpecialAddressBehavior )
2013-05-02 17:53:54 +02:00
2013-11-07 20:35:11 +01:00
def init_addressbook_popup_menu ( self ) :
2013-06-12 23:12:32 +02:00
# Popup menu for the Address Book page
2013-05-02 17:53:54 +02:00
self . ui . addressBookContextMenuToolbar = QtGui . QToolBar ( )
2013-11-07 20:35:11 +01:00
# Actions
self . actionAddressBookSend = self . ui . addressBookContextMenuToolbar . addAction (
_translate (
" MainWindow " , " Send message to this address " ) ,
self . on_action_AddressBookSend )
self . actionAddressBookClipboard = self . ui . addressBookContextMenuToolbar . addAction (
_translate (
" MainWindow " , " Copy address to clipboard " ) ,
self . on_action_AddressBookClipboard )
self . actionAddressBookSubscribe = self . ui . addressBookContextMenuToolbar . addAction (
_translate (
" MainWindow " , " Subscribe to this address " ) ,
self . on_action_AddressBookSubscribe )
self . actionAddressBookSetAvatar = self . ui . addressBookContextMenuToolbar . addAction (
_translate (
" MainWindow " , " Set avatar... " ) ,
self . on_action_AddressBookSetAvatar )
self . actionAddressBookNew = self . ui . addressBookContextMenuToolbar . addAction (
_translate (
" MainWindow " , " Add New Address " ) , self . on_action_AddressBookNew )
self . actionAddressBookDelete = self . ui . addressBookContextMenuToolbar . addAction (
_translate (
" MainWindow " , " Delete " ) , self . on_action_AddressBookDelete )
2013-06-12 23:12:32 +02:00
self . ui . tableWidgetAddressBook . setContextMenuPolicy (
QtCore . Qt . CustomContextMenu )
self . connect ( self . ui . tableWidgetAddressBook , QtCore . SIGNAL (
2013-11-07 20:35:11 +01:00
' customContextMenuRequested(const QPoint&) ' ) ,
self . on_context_menuAddressBook )
2013-06-12 23:12:32 +02:00
self . popMenuAddressBook = QtGui . QMenu ( self )
self . popMenuAddressBook . addAction ( self . actionAddressBookSend )
self . popMenuAddressBook . addAction ( self . actionAddressBookClipboard )
2013-09-21 09:41:23 +02:00
self . popMenuAddressBook . addAction ( self . actionAddressBookSubscribe )
self . popMenuAddressBook . addAction ( self . actionAddressBookSetAvatar )
2013-05-02 17:53:54 +02:00
self . popMenuAddressBook . addSeparator ( )
2013-06-12 23:12:32 +02:00
self . popMenuAddressBook . addAction ( self . actionAddressBookNew )
self . popMenuAddressBook . addAction ( self . actionAddressBookDelete )
2013-05-02 17:53:54 +02:00
2013-11-07 20:35:11 +01:00
def init_subscriptions_popup_menu ( self ) :
2013-06-12 23:12:32 +02:00
# Popup menu for the Subscriptions page
2013-05-02 17:53:54 +02:00
self . ui . subscriptionsContextMenuToolbar = QtGui . QToolBar ( )
2013-11-07 20:35:11 +01:00
# Actions
2013-06-12 23:12:32 +02:00
self . actionsubscriptionsNew = self . ui . subscriptionsContextMenuToolbar . addAction (
2013-06-13 09:59:40 +02:00
_translate ( " MainWindow " , " New " ) , self . on_action_SubscriptionsNew )
2013-06-12 23:12:32 +02:00
self . actionsubscriptionsDelete = self . ui . subscriptionsContextMenuToolbar . addAction (
2013-11-07 20:35:11 +01:00
_translate ( " MainWindow " , " Delete " ) ,
self . on_action_SubscriptionsDelete )
2013-06-12 23:12:32 +02:00
self . actionsubscriptionsClipboard = self . ui . subscriptionsContextMenuToolbar . addAction (
2013-11-07 20:35:11 +01:00
_translate ( " MainWindow " , " Copy address to clipboard " ) ,
self . on_action_SubscriptionsClipboard )
2013-06-12 23:12:32 +02:00
self . actionsubscriptionsEnable = self . ui . subscriptionsContextMenuToolbar . addAction (
2013-11-07 20:35:11 +01:00
_translate ( " MainWindow " , " Enable " ) ,
self . on_action_SubscriptionsEnable )
2013-06-12 23:12:32 +02:00
self . actionsubscriptionsDisable = self . ui . subscriptionsContextMenuToolbar . addAction (
2013-11-07 20:35:11 +01:00
_translate ( " MainWindow " , " Disable " ) ,
self . on_action_SubscriptionsDisable )
2013-09-21 09:41:23 +02:00
self . actionsubscriptionsSetAvatar = self . ui . subscriptionsContextMenuToolbar . addAction (
2013-11-07 20:35:11 +01:00
_translate ( " MainWindow " , " Set avatar... " ) ,
self . on_action_SubscriptionsSetAvatar )
2013-06-12 23:12:32 +02:00
self . ui . tableWidgetSubscriptions . setContextMenuPolicy (
QtCore . Qt . CustomContextMenu )
self . connect ( self . ui . tableWidgetSubscriptions , QtCore . SIGNAL (
2013-11-07 20:35:11 +01:00
' customContextMenuRequested(const QPoint&) ' ) ,
self . on_context_menuSubscriptions )
2013-06-12 23:12:32 +02:00
self . popMenuSubscriptions = QtGui . QMenu ( self )
self . popMenuSubscriptions . addAction ( self . actionsubscriptionsNew )
self . popMenuSubscriptions . addAction ( self . actionsubscriptionsDelete )
2013-05-02 17:53:54 +02:00
self . popMenuSubscriptions . addSeparator ( )
2013-06-12 23:12:32 +02:00
self . popMenuSubscriptions . addAction ( self . actionsubscriptionsEnable )
self . popMenuSubscriptions . addAction ( self . actionsubscriptionsDisable )
2013-09-21 09:41:23 +02:00
self . popMenuSubscriptions . addAction ( self . actionsubscriptionsSetAvatar )
2013-05-02 17:53:54 +02:00
self . popMenuSubscriptions . addSeparator ( )
2013-06-12 23:12:32 +02:00
self . popMenuSubscriptions . addAction ( self . actionsubscriptionsClipboard )
2013-05-02 17:53:54 +02:00
2013-11-07 20:35:11 +01:00
def init_sent_popup_menu ( self ) :
2013-06-12 23:12:32 +02:00
# Popup menu for the Sent page
2013-05-02 17:53:54 +02:00
self . ui . sentContextMenuToolbar = QtGui . QToolBar ( )
2013-11-07 20:35:11 +01:00
# Actions
self . actionTrashSentMessage = self . ui . sentContextMenuToolbar . addAction (
_translate (
" MainWindow " , " Move to Trash " ) , self . on_action_SentTrash )
self . actionSentClipboard = self . ui . sentContextMenuToolbar . addAction (
_translate (
" MainWindow " , " Copy destination address to clipboard " ) ,
self . on_action_SentClipboard )
self . actionForceSend = self . ui . sentContextMenuToolbar . addAction (
_translate (
" MainWindow " , " Force send " ) , self . on_action_ForceSend )
2013-06-12 23:12:32 +02:00
self . ui . tableWidgetSent . setContextMenuPolicy (
QtCore . Qt . CustomContextMenu )
self . connect ( self . ui . tableWidgetSent , QtCore . SIGNAL (
2013-11-07 20:35:11 +01:00
' customContextMenuRequested(const QPoint&) ' ) ,
self . on_context_menuSent )
2013-06-12 23:12:32 +02:00
# self.popMenuSent = QtGui.QMenu( self )
# self.popMenuSent.addAction( self.actionSentClipboard )
# self.popMenuSent.addAction( self.actionTrashSentMessage )
2013-11-07 20:35:11 +01:00
def init_blacklist_popup_menu ( self ) :
2013-06-12 23:12:32 +02:00
# Popup menu for the Blacklist page
2013-05-02 17:53:54 +02:00
self . ui . blacklistContextMenuToolbar = QtGui . QToolBar ( )
2013-11-07 20:35:11 +01:00
# Actions
self . actionBlacklistNew = self . ui . blacklistContextMenuToolbar . addAction (
_translate (
" MainWindow " , " Add new entry " ) , self . on_action_BlacklistNew )
self . actionBlacklistDelete = self . ui . blacklistContextMenuToolbar . addAction (
_translate (
" MainWindow " , " Delete " ) , self . on_action_BlacklistDelete )
self . actionBlacklistClipboard = self . ui . blacklistContextMenuToolbar . addAction (
_translate (
" MainWindow " , " Copy address to clipboard " ) ,
self . on_action_BlacklistClipboard )
self . actionBlacklistEnable = self . ui . blacklistContextMenuToolbar . addAction (
_translate (
" MainWindow " , " Enable " ) , self . on_action_BlacklistEnable )
self . actionBlacklistDisable = self . ui . blacklistContextMenuToolbar . addAction (
_translate (
" MainWindow " , " Disable " ) , self . on_action_BlacklistDisable )
self . actionBlacklistSetAvatar = self . ui . blacklistContextMenuToolbar . addAction (
_translate (
" MainWindow " , " Set avatar... " ) ,
self . on_action_BlacklistSetAvatar )
2013-06-12 23:12:32 +02:00
self . ui . tableWidgetBlacklist . setContextMenuPolicy (
QtCore . Qt . CustomContextMenu )
self . connect ( self . ui . tableWidgetBlacklist , QtCore . SIGNAL (
2013-11-07 20:35:11 +01:00
' customContextMenuRequested(const QPoint&) ' ) ,
self . on_context_menuBlacklist )
2013-06-12 23:12:32 +02:00
self . popMenuBlacklist = QtGui . QMenu ( self )
# self.popMenuBlacklist.addAction( self.actionBlacklistNew )
self . popMenuBlacklist . addAction ( self . actionBlacklistDelete )
2013-05-02 17:53:54 +02:00
self . popMenuBlacklist . addSeparator ( )
2013-06-12 23:12:32 +02:00
self . popMenuBlacklist . addAction ( self . actionBlacklistClipboard )
2013-05-02 17:53:54 +02:00
self . popMenuBlacklist . addSeparator ( )
2013-06-12 23:12:32 +02:00
self . popMenuBlacklist . addAction ( self . actionBlacklistEnable )
self . popMenuBlacklist . addAction ( self . actionBlacklistDisable )
2013-09-21 09:41:23 +02:00
self . popMenuBlacklist . addAction ( self . actionBlacklistSetAvatar )
2013-05-02 17:53:54 +02:00
2013-11-07 20:35:11 +01:00
def __init__ ( self , parent = None ) :
QtGui . QWidget . __init__ ( self , parent )
self . ui = Ui_MainWindow ( )
self . ui . setupUi ( self )
# Ask the user if we may delete their old version 1 addresses if they
# have any.
configSections = shared . config . sections ( )
for addressInKeysFile in configSections :
if addressInKeysFile != ' bitmessagesettings ' :
status , addressVersionNumber , streamNumber , hash = decodeAddress (
addressInKeysFile )
if addressVersionNumber == 1 :
displayMsg = _translate (
" MainWindow " , " One of your addresses, % 1, is an old version 1 address. Version 1 addresses are no longer supported. "
+ " May we delete it now? " ) . arg ( addressInKeysFile )
reply = QtGui . QMessageBox . question (
self , ' Message ' , displayMsg , QtGui . QMessageBox . Yes , QtGui . QMessageBox . No )
if reply == QtGui . QMessageBox . Yes :
shared . config . remove_section ( addressInKeysFile )
with open ( shared . appdata + ' keys.dat ' , ' wb ' ) as configfile :
shared . config . write ( configfile )
# Configure Bitmessage to start on startup (or remove the
# configuration) based on the setting in the keys.dat file
if ' win32 ' in sys . platform or ' win64 ' in sys . platform :
# Auto-startup for Windows
RUN_PATH = " HKEY_CURRENT_USER \\ Software \\ Microsoft \\ Windows \\ CurrentVersion \\ Run "
self . settings = QSettings ( RUN_PATH , QSettings . NativeFormat )
self . settings . remove (
" PyBitmessage " ) # In case the user moves the program and the registry entry is no longer valid, this will delete the old registry entry.
if shared . config . getboolean ( ' bitmessagesettings ' , ' startonlogon ' ) :
self . settings . setValue ( " PyBitmessage " , sys . argv [ 0 ] )
elif ' darwin ' in sys . platform :
# startup for mac
pass
elif ' linux ' in sys . platform :
# startup for linux
pass
2014-08-01 22:35:48 +02:00
self . totalNumberOfBytesReceived = 0
self . totalNumberOfBytesSent = 0
2013-11-07 20:35:11 +01:00
self . ui . labelSendBroadcastWarning . setVisible ( False )
self . timer = QtCore . QTimer ( )
self . timer . start ( 2000 ) # milliseconds
QtCore . QObject . connect ( self . timer , QtCore . SIGNAL ( " timeout() " ) , self . runEveryTwoSeconds )
self . init_file_menu ( )
self . init_inbox_popup_menu ( )
self . init_identities_popup_menu ( )
self . init_addressbook_popup_menu ( )
self . init_subscriptions_popup_menu ( )
self . init_sent_popup_menu ( )
self . init_blacklist_popup_menu ( )
2013-06-12 23:12:32 +02:00
# Initialize the user's list of addresses on the 'Your Identities' tab.
2013-05-02 17:53:54 +02:00
configSections = shared . config . sections ( )
for addressInKeysFile in configSections :
2013-06-12 23:12:32 +02:00
if addressInKeysFile != ' bitmessagesettings ' :
isEnabled = shared . config . getboolean (
addressInKeysFile , ' enabled ' )
newItem = QtGui . QTableWidgetItem ( unicode (
shared . config . get ( addressInKeysFile , ' label ' ) , ' utf-8) ' ) )
2013-05-02 17:53:54 +02:00
if not isEnabled :
2013-06-12 23:12:32 +02:00
newItem . setTextColor ( QtGui . QColor ( 128 , 128 , 128 ) )
2013-05-02 17:53:54 +02:00
self . ui . tableWidgetYourIdentities . insertRow ( 0 )
2013-09-19 21:28:22 +02:00
newItem . setIcon ( avatarize ( addressInKeysFile ) )
2013-05-02 17:53:54 +02:00
self . ui . tableWidgetYourIdentities . setItem ( 0 , 0 , newItem )
newItem = QtGui . QTableWidgetItem ( addressInKeysFile )
2013-06-12 23:12:32 +02:00
newItem . setFlags (
QtCore . Qt . ItemIsSelectable | QtCore . Qt . ItemIsEnabled )
2013-07-22 07:10:22 +02:00
if shared . safeConfigGetBoolean ( addressInKeysFile , ' chan ' ) :
newItem . setTextColor ( QtGui . QColor ( 216 , 119 , 0 ) ) # orange
2013-05-02 17:53:54 +02:00
if not isEnabled :
2013-06-12 23:12:32 +02:00
newItem . setTextColor ( QtGui . QColor ( 128 , 128 , 128 ) )
if shared . safeConfigGetBoolean ( addressInKeysFile , ' mailinglist ' ) :
2013-09-21 09:41:23 +02:00
newItem . setTextColor ( QtGui . QColor ( 137 , 04 , 177 ) ) # magenta
2013-05-02 17:53:54 +02:00
self . ui . tableWidgetYourIdentities . setItem ( 0 , 1 , newItem )
2013-06-12 23:12:32 +02:00
newItem = QtGui . QTableWidgetItem ( str (
2013-09-13 06:27:34 +02:00
decodeAddress ( addressInKeysFile ) [ 2 ] ) )
2013-06-12 23:12:32 +02:00
newItem . setFlags (
QtCore . Qt . ItemIsSelectable | QtCore . Qt . ItemIsEnabled )
2013-05-02 17:53:54 +02:00
if not isEnabled :
2013-06-12 23:12:32 +02:00
newItem . setTextColor ( QtGui . QColor ( 128 , 128 , 128 ) )
2013-05-02 17:53:54 +02:00
self . ui . tableWidgetYourIdentities . setItem ( 0 , 2 , newItem )
if isEnabled :
2013-06-12 23:12:32 +02:00
status , addressVersionNumber , streamNumber , hash = decodeAddress (
addressInKeysFile )
2013-05-02 17:53:54 +02:00
2013-06-12 23:12:32 +02:00
# Load inbox from messages database file
2013-07-12 10:24:24 +02:00
self . loadInbox ( )
2013-06-11 00:53:15 +02:00
2013-06-12 23:12:32 +02:00
# Load Sent items from database
2013-07-12 10:24:24 +02:00
self . loadSent ( )
2013-05-02 17:53:54 +02:00
2013-06-12 23:12:32 +02:00
# Initialize the address book
2013-09-05 12:31:52 +02:00
self . rerenderAddressBook ( )
2013-06-12 23:12:32 +02:00
# Initialize the Subscriptions
2013-05-24 22:12:16 +02:00
self . rerenderSubscriptions ( )
2013-05-02 17:53:54 +02:00
2013-07-12 10:24:24 +02:00
# Initialize the inbox search
QtCore . QObject . connect ( self . ui . inboxSearchLineEdit , QtCore . SIGNAL (
" returnPressed() " ) , self . inboxSearchLineEditPressed )
2013-07-12 10:42:52 +02:00
# Initialize the sent search
QtCore . QObject . connect ( self . ui . sentSearchLineEdit , QtCore . SIGNAL (
" returnPressed() " ) , self . sentSearchLineEditPressed )
2013-06-12 23:12:32 +02:00
# Initialize the Blacklist or Whitelist
2013-05-02 17:53:54 +02:00
if shared . config . get ( ' bitmessagesettings ' , ' blackwhitelist ' ) == ' black ' :
self . loadBlackWhiteList ( )
else :
2013-06-12 23:12:32 +02:00
self . ui . tabWidget . setTabText ( 6 , ' Whitelist ' )
2013-05-02 17:53:54 +02:00
self . ui . radioButtonWhitelist . click ( )
self . loadBlackWhiteList ( )
2013-06-12 23:12:32 +02:00
QtCore . QObject . connect ( self . ui . tableWidgetYourIdentities , QtCore . SIGNAL (
" itemChanged(QTableWidgetItem *) " ) , self . tableWidgetYourIdentitiesItemChanged )
QtCore . QObject . connect ( self . ui . tableWidgetAddressBook , QtCore . SIGNAL (
" itemChanged(QTableWidgetItem *) " ) , self . tableWidgetAddressBookItemChanged )
QtCore . QObject . connect ( self . ui . tableWidgetSubscriptions , QtCore . SIGNAL (
" itemChanged(QTableWidgetItem *) " ) , self . tableWidgetSubscriptionsItemChanged )
QtCore . QObject . connect ( self . ui . tableWidgetInbox , QtCore . SIGNAL (
" itemSelectionChanged () " ) , self . tableWidgetInboxItemClicked )
QtCore . QObject . connect ( self . ui . tableWidgetSent , QtCore . SIGNAL (
" itemSelectionChanged () " ) , self . tableWidgetSentItemClicked )
# Put the colored icon on the status bar
# self.ui.pushButtonStatusIcon.setIcon(QIcon(":/newPrefix/images/yellowicon.png"))
2013-05-02 17:53:54 +02:00
self . statusbar = self . statusBar ( )
2013-06-12 23:12:32 +02:00
self . statusbar . insertPermanentWidget ( 0 , self . ui . pushButtonStatusIcon )
2013-06-13 09:59:40 +02:00
self . ui . labelStartupTime . setText ( _translate ( " MainWindow " , " Since startup on % 1 " ) . arg (
2013-06-18 19:11:30 +02:00
unicode ( strftime ( shared . config . get ( ' bitmessagesettings ' , ' timeformat ' ) , localtime ( int ( time . time ( ) ) ) ) , ' utf-8 ' ) ) )
2013-05-02 17:53:54 +02:00
self . numberOfMessagesProcessed = 0
self . numberOfBroadcastsProcessed = 0
self . numberOfPubkeysProcessed = 0
2013-08-27 11:47:14 +02:00
# Set the icon sizes for the identicons
identicon_size = 3 * 7
self . ui . tableWidgetInbox . setIconSize ( QtCore . QSize ( identicon_size , identicon_size ) )
self . ui . tableWidgetSent . setIconSize ( QtCore . QSize ( identicon_size , identicon_size ) )
self . ui . tableWidgetYourIdentities . setIconSize ( QtCore . QSize ( identicon_size , identicon_size ) )
self . ui . tableWidgetSubscriptions . setIconSize ( QtCore . QSize ( identicon_size , identicon_size ) )
self . ui . tableWidgetAddressBook . setIconSize ( QtCore . QSize ( identicon_size , identicon_size ) )
self . ui . tableWidgetBlacklist . setIconSize ( QtCore . QSize ( identicon_size , identicon_size ) )
2013-05-02 17:53:54 +02:00
self . UISignalThread = UISignaler ( )
2013-06-12 23:12:32 +02:00
QtCore . QObject . connect ( self . UISignalThread , QtCore . SIGNAL (
" writeNewAddressToTable(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject) " ) , self . writeNewAddressToTable )
QtCore . QObject . connect ( self . UISignalThread , QtCore . SIGNAL (
" updateStatusBar(PyQt_PyObject) " ) , self . updateStatusBar )
QtCore . QObject . connect ( self . UISignalThread , QtCore . SIGNAL (
" updateSentItemStatusByHash(PyQt_PyObject,PyQt_PyObject) " ) , self . updateSentItemStatusByHash )
QtCore . QObject . connect ( self . UISignalThread , QtCore . SIGNAL (
" updateSentItemStatusByAckdata(PyQt_PyObject,PyQt_PyObject) " ) , self . updateSentItemStatusByAckdata )
QtCore . QObject . connect ( self . UISignalThread , QtCore . SIGNAL (
" displayNewInboxMessage(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject) " ) , self . displayNewInboxMessage )
QtCore . QObject . connect ( self . UISignalThread , QtCore . SIGNAL (
" displayNewSentMessage(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject) " ) , self . displayNewSentMessage )
QtCore . QObject . connect ( self . UISignalThread , QtCore . SIGNAL (
" updateNetworkStatusTab() " ) , self . updateNetworkStatusTab )
QtCore . QObject . connect ( self . UISignalThread , QtCore . SIGNAL (
2013-08-25 01:40:48 +02:00
" updateNumberOfMessagesProcessed() " ) , self . updateNumberOfMessagesProcessed )
2013-06-12 23:12:32 +02:00
QtCore . QObject . connect ( self . UISignalThread , QtCore . SIGNAL (
2013-08-25 01:40:48 +02:00
" updateNumberOfPubkeysProcessed() " ) , self . updateNumberOfPubkeysProcessed )
2013-06-12 23:12:32 +02:00
QtCore . QObject . connect ( self . UISignalThread , QtCore . SIGNAL (
2013-08-25 01:40:48 +02:00
" updateNumberOfBroadcastsProcessed() " ) , self . updateNumberOfBroadcastsProcessed )
2013-06-12 23:12:32 +02:00
QtCore . QObject . connect ( self . UISignalThread , QtCore . SIGNAL (
" setStatusIcon(PyQt_PyObject) " ) , self . setStatusIcon )
2013-11-29 02:05:53 +01:00
QtCore . QObject . connect ( self . UISignalThread , QtCore . SIGNAL (
" changedInboxUnread(PyQt_PyObject) " ) , self . changedInboxUnread )
2013-06-12 23:12:32 +02:00
QtCore . QObject . connect ( self . UISignalThread , QtCore . SIGNAL (
" rerenderInboxFromLabels() " ) , self . rerenderInboxFromLabels )
2013-09-05 12:31:52 +02:00
QtCore . QObject . connect ( self . UISignalThread , QtCore . SIGNAL (
" rerenderSentToLabels() " ) , self . rerenderSentToLabels )
QtCore . QObject . connect ( self . UISignalThread , QtCore . SIGNAL (
" rerenderAddressBook() " ) , self . rerenderAddressBook )
2013-06-12 23:12:32 +02:00
QtCore . QObject . connect ( self . UISignalThread , QtCore . SIGNAL (
" rerenderSubscriptions() " ) , self . rerenderSubscriptions )
QtCore . QObject . connect ( self . UISignalThread , QtCore . SIGNAL (
" removeInboxRowByMsgid(PyQt_PyObject) " ) , self . removeInboxRowByMsgid )
2013-09-05 02:14:25 +02:00
QtCore . QObject . connect ( self . UISignalThread , QtCore . SIGNAL (
" displayAlert(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject) " ) , self . displayAlert )
2013-05-02 17:53:54 +02:00
self . UISignalThread . start ( )
2013-08-15 00:59:50 +02:00
# Below this point, it would be good if all of the necessary global data
# structures were initialized.
2013-05-02 17:53:54 +02:00
2013-05-08 22:42:28 +02:00
self . rerenderComboBoxSendFrom ( )
2013-08-15 00:59:50 +02:00
# Check to see whether we can connect to namecoin. Hide the 'Fetch Namecoin ID' button if we can't.
2013-08-15 01:46:59 +02:00
try :
options = { }
options [ " type " ] = shared . config . get ( ' bitmessagesettings ' , ' namecoinrpctype ' )
options [ " host " ] = shared . config . get ( ' bitmessagesettings ' , ' namecoinrpchost ' )
options [ " port " ] = shared . config . get ( ' bitmessagesettings ' , ' namecoinrpcport ' )
options [ " user " ] = shared . config . get ( ' bitmessagesettings ' , ' namecoinrpcuser ' )
options [ " password " ] = shared . config . get ( ' bitmessagesettings ' , ' namecoinrpcpassword ' )
nc = namecoinConnection ( options )
if nc . test ( ) [ 0 ] == ' failed ' :
self . ui . pushButtonFetchNamecoinID . hide ( )
except :
print ' There was a problem testing for a Namecoin daemon. Hiding the Fetch Namecoin ID button '
2013-08-15 00:59:50 +02:00
self . ui . pushButtonFetchNamecoinID . hide ( )
2013-05-02 17:53:54 +02:00
2013-07-24 17:46:28 +02:00
2013-06-12 23:12:32 +02:00
# Show or hide the application window after clicking an item within the
# tray icon or, on Windows, the try icon itself.
2013-05-08 22:42:28 +02:00
def appIndicatorShowOrHideWindow ( self ) :
if not self . actionShow . isChecked ( ) :
self . hide ( )
else :
if sys . platform [ 0 : 3 ] == ' win ' :
self . setWindowFlags ( Qt . Window )
2013-06-12 23:12:32 +02:00
# else:
# self.showMaximized()
2013-05-25 19:59:00 +02:00
self . show ( )
2013-06-12 23:12:32 +02:00
self . setWindowState (
self . windowState ( ) & ~ QtCore . Qt . WindowMinimized | QtCore . Qt . WindowActive )
2013-05-15 18:36:30 +02:00
self . activateWindow ( )
2013-05-07 23:22:34 +02:00
2013-05-10 00:57:46 +02:00
# pointer to the application
2013-06-12 23:12:32 +02:00
# app = None
2013-05-14 17:06:01 +02:00
# The most recent message
newMessageItem = None
# The most recent broadcast
newBroadcastItem = None
2013-05-07 23:22:34 +02:00
# show the application window
def appIndicatorShow ( self ) :
2013-06-12 23:12:32 +02:00
if self . actionShow is None :
2013-05-07 23:22:34 +02:00
return
2013-05-14 17:44:51 +02:00
if not self . actionShow . isChecked ( ) :
self . actionShow . setChecked ( True )
self . appIndicatorShowOrHideWindow ( )
2013-05-07 23:22:34 +02:00
2013-05-13 13:20:29 +02:00
# unchecks the show item on the application indicator
def appIndicatorHide ( self ) :
2013-06-12 23:12:32 +02:00
if self . actionShow is None :
2013-05-13 13:20:29 +02:00
return
2013-05-14 17:44:51 +02:00
if self . actionShow . isChecked ( ) :
self . actionShow . setChecked ( False )
self . appIndicatorShowOrHideWindow ( )
2013-05-13 13:20:29 +02:00