# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-import sys, time, datetime, re
+import sys, time, datetime, re, threading
from i18n import _, set_language
from electrum.util import print_error, print_msg
import os.path, json, ast, traceback
-from qrcodewidget import QRCodeWidget
+import shutil
+
try:
import PyQt4
from PyQt4.QtGui import *
from PyQt4.QtCore import *
import PyQt4.QtCore as QtCore
-import PyQt4.QtGui as QtGui
-from electrum.interface import DEFAULT_SERVERS, DEFAULT_PORTS
+
from electrum.bitcoin import MIN_RELAY_TX_FEE
try:
import exchange_rate
from amountedit import AmountEdit
+from network_dialog import NetworkDialog
+from qrcodewidget import QRCodeWidget
from decimal import Decimal
from electrum import ELECTRUM_VERSION
import re
-class UpdateLabel(QtGui.QLabel):
+from qt_util import *
+
+class UpdateLabel(QLabel):
def __init__(self, config, parent=None):
- QtGui.QLabel.__init__(self, parent)
+ QLabel.__init__(self, parent)
self.new_version = False
try:
w.destroy()
-def ok_cancel_buttons(dialog, ok_label=_("OK") ):
- hbox = QHBoxLayout()
- hbox.addStretch(1)
- b = QPushButton(_("Cancel"))
- hbox.addWidget(b)
- b.clicked.connect(dialog.reject)
- b = QPushButton(ok_label)
- hbox.addWidget(b)
- b.clicked.connect(dialog.accept)
- b.setDefault(True)
- return hbox
-def text_dialog(parent, title, label, ok_label):
- dialog = QDialog(parent)
- dialog.setMinimumWidth(500)
- dialog.setWindowTitle(title)
- dialog.setModal(1)
- l = QVBoxLayout()
- dialog.setLayout(l)
- l.addWidget(QLabel(label))
- txt = QTextEdit()
- l.addWidget(txt)
- l.addLayout(ok_cancel_buttons(dialog, ok_label))
- if dialog.exec_():
- return unicode(txt.toPlainText())
-
default_column_widths = { "history":[40,140,350,140], "contacts":[350,330], "receive":[[370], [370,200,130]] }
class ElectrumWindow(QMainWindow):
+ def changeEvent(self, event):
+ flags = self.windowFlags();
+ if event and event.type() == QtCore.QEvent.WindowStateChange:
+ if self.windowState() & QtCore.Qt.WindowMinimized:
+ self.build_menu(True)
+ # The only way to toggle the icon in the window managers taskbar is to use the Qt.Tooltip flag
+ # The problem is that it somehow creates an (in)visible window that will stay active and prevent
+ # Electrum from closing.
+ # As for now I have no clue how to implement a proper 'hide to tray' functionality.
+ # self.setWindowFlags(flags & ~Qt.ToolTip)
+ elif event.oldState() & QtCore.Qt.WindowMinimized:
+ self.build_menu(False)
+ #self.setWindowFlags(flags | Qt.ToolTip)
+
+ def build_menu(self, is_hidden = False):
+ m = QMenu()
+ if self.isMinimized():
+ m.addAction(_("Show"), self.showNormal)
+ else:
+ m.addAction(_("Hide"), self.showMinimized)
+
+ m.addSeparator()
+ m.addAction(_("Exit Electrum"), self.close)
+ self.tray.setContextMenu(m)
+
+ def tray_activated(self, reason):
+ if reason == QSystemTrayIcon.DoubleClick:
+ self.showNormal()
def __init__(self, wallet, config):
QMainWindow.__init__(self)
+ self._close_electrum = False
self.lite = None
self.wallet = wallet
self.config = config
self.current_account = self.config.get("current_account", None)
+ self.icon = QIcon(os.getcwd() + '/icons/electrum.png')
+ self.tray = QSystemTrayIcon(self.icon, self)
+ self.tray.setToolTip('Electrum')
+ self.tray.activated.connect(self.tray_activated)
+
+ self.build_menu()
+ self.tray.show()
+
self.init_plugins()
self.create_status_bar()
- self.wallet.interface.register_callback('updated', lambda: self.emit(QtCore.SIGNAL('update_wallet')))
+ self.need_update = threading.Event()
+ self.wallet.interface.register_callback('updated', lambda: self.need_update.set())
self.wallet.interface.register_callback('banner', lambda: self.emit(QtCore.SIGNAL('banner_signal')))
self.wallet.interface.register_callback('disconnected', lambda: self.emit(QtCore.SIGNAL('update_status')))
self.wallet.interface.register_callback('disconnecting', lambda: self.emit(QtCore.SIGNAL('update_status')))
+ self.wallet.interface.register_callback('new_transaction', lambda: self.emit(QtCore.SIGNAL('transaction_signal')))
self.expert_mode = config.get('classic_expert_mode', False)
self.decimal_point = config.get('decimal_point', 8)
if not self.wallet.seed: title += ' [%s]' % (_('seedless'))
self.setWindowTitle( title )
+ self.init_menubar()
+
QShortcut(QKeySequence("Ctrl+W"), self, self.close)
+ QShortcut(QKeySequence("Ctrl+R"), self, self.update_wallet)
QShortcut(QKeySequence("Ctrl+Q"), self, self.close)
QShortcut(QKeySequence("Ctrl+PgUp"), self, lambda: tabs.setCurrentIndex( (tabs.currentIndex() - 1 )%tabs.count() ))
QShortcut(QKeySequence("Ctrl+PgDown"), self, lambda: tabs.setCurrentIndex( (tabs.currentIndex() + 1 )%tabs.count() ))
- self.connect(self, QtCore.SIGNAL('update_wallet'), self.update_wallet)
self.connect(self, QtCore.SIGNAL('update_status'), self.update_status)
self.connect(self, QtCore.SIGNAL('banner_signal'), lambda: self.console.showMessage(self.wallet.interface.banner) )
+ self.connect(self, QtCore.SIGNAL('transaction_signal'), lambda: self.notify_transactions() )
self.history_list.setFocus(True)
self.exchanger = exchange_rate.Exchanger(self)
# set initial message
self.console.showMessage(self.wallet.interface.banner)
+ # Once GUI has been initialized check if we want to announce something since the callback has been called before the GUI was initialized
+ self.notify_transactions()
+
# plugins that need to change the GUI do it here
self.run_hook('init_gui')
+ def select_wallet_file(self):
+ wallet_folder = self.wallet.config.path
+ re.sub("(\/\w*.dat)$", "", wallet_folder)
+ file_name = QFileDialog.getOpenFileName(self, "Select your wallet file", wallet_folder, "*.dat")
+ if not file_name:
+ return
+ else:
+ self.load_wallet(file_name)
+
+
+ def init_menubar(self):
+ menubar = QMenuBar()
+
+ electrum_menu = menubar.addMenu(_("&File"))
+ open_wallet_action = electrum_menu.addAction(_("Open wallet"))
+ open_wallet_action.triggered.connect(self.select_wallet_file)
+
+ preferences_name = _("Preferences")
+ if sys.platform == 'darwin':
+ preferences_name = _("Electrum preferences") # Settings / Preferences are all reserved keywords in OSX using this as work around
+
+ preferences_menu = electrum_menu.addAction(preferences_name)
+ preferences_menu.triggered.connect(self.settings_dialog)
+ electrum_menu.addSeparator()
+
+ raw_transaction_menu = electrum_menu.addMenu(_("&Load raw transaction"))
+
+ raw_transaction_file = raw_transaction_menu.addAction(_("&From file"))
+ raw_transaction_file.triggered.connect(self.do_process_from_file)
+
+ raw_transaction_text = raw_transaction_menu.addAction(_("&From text"))
+ raw_transaction_text.triggered.connect(self.do_process_from_text)
+
+ electrum_menu.addSeparator()
+ quit_item = electrum_menu.addAction(_("&Close"))
+ quit_item.triggered.connect(self.close)
+
+ wallet_menu = menubar.addMenu(_("&Wallet"))
+ wallet_backup = wallet_menu.addAction(_("&Create backup"))
+ wallet_backup.triggered.connect(lambda: backup_wallet(self.config.path))
+
+ show_menu = wallet_menu.addMenu(_("Show"))
+
+ if self.wallet.seed:
+ show_seed = show_menu.addAction(_("&Seed"))
+ show_seed.triggered.connect(self.show_seed_dialog)
+
+ show_mpk = show_menu.addAction(_("&Master Public Key"))
+ show_mpk.triggered.connect(self.show_master_public_key)
+
+ wallet_menu.addSeparator()
+ new_contact = wallet_menu.addAction(_("&New contact"))
+ new_contact.triggered.connect(self.new_contact_dialog)
+
+ new_account = wallet_menu.addAction(_("&New account"))
+ new_account.triggered.connect(self.new_account_dialog)
+
+ import_menu = menubar.addMenu(_("&Import"))
+ in_labels = import_menu.addAction(_("&Labels"))
+ in_labels.triggered.connect(self.do_import_labels)
+
+ in_private_keys = import_menu.addAction(_("&Private keys"))
+ in_private_keys.triggered.connect(self.do_import_privkey)
+
+ export_menu = menubar.addMenu(_("&Export"))
+ ex_private_keys = export_menu.addAction(_("&Private keys"))
+ ex_private_keys.triggered.connect(self.do_export_privkeys)
+
+ ex_history = export_menu.addAction(_("&History"))
+ ex_history.triggered.connect(self.do_export_history)
+
+ ex_labels = export_menu.addAction(_("&Labels"))
+ ex_labels.triggered.connect(self.do_export_labels)
+
+ help_menu = menubar.addMenu(_("&Help"))
+ doc_open = help_menu.addAction(_("&Documentation"))
+ doc_open.triggered.connect(lambda: webbrowser.open("http://electrum.org/documentation.html"))
+ web_open = help_menu.addAction(_("&Official website"))
+ web_open.triggered.connect(lambda: webbrowser.open("http://electrum.org"))
+
+ self.setMenuBar(menubar)
+
+ def load_wallet(self, filename):
+ import electrum
+
+ config = electrum.SimpleConfig({'wallet_path': filename})
+ if not config.wallet_file_exists:
+ self.show_message("file not found "+ filename)
+ return
+
+ #self.wallet.verifier.stop()
+ interface = self.wallet.interface
+ verifier = self.wallet.verifier
+ self.wallet.synchronizer.stop()
+
+ self.config = config
+ self.wallet = electrum.Wallet(self.config)
+ self.wallet.interface = interface
+ self.wallet.verifier = verifier
+
+ synchronizer = electrum.WalletSynchronizer(self.wallet, self.config)
+ synchronizer.start()
+
+ self.update_wallet()
+
+ def notify_transactions(self):
+ print_error("Notifying GUI")
+ if len(self.wallet.interface.pending_transactions_for_notifications) > 0:
+ # Combine the transactions if there are more then three
+ tx_amount = len(self.wallet.interface.pending_transactions_for_notifications)
+ if(tx_amount >= 3):
+ total_amount = 0
+ for tx in self.wallet.interface.pending_transactions_for_notifications:
+ is_relevant, is_mine, v, fee = self.wallet.get_tx_value(tx)
+ if(v > 0):
+ total_amount += v
+
+ self.notify("%s new transactions received. Total amount received in the new transactions %s %s" \
+ % (tx_amount, self.format_amount(total_amount), self.base_unit()))
+
+ self.wallet.interface.pending_transactions_for_notifications = []
+ else:
+ for tx in self.wallet.interface.pending_transactions_for_notifications:
+ if tx:
+ self.wallet.interface.pending_transactions_for_notifications.remove(tx)
+ is_relevant, is_mine, v, fee = self.wallet.get_tx_value(tx)
+ if(v > 0):
+ self.notify("New transaction received. %s %s" % (self.format_amount(v), self.base_unit()))
+
+ def notify(self, message):
+ self.tray.showMessage("Electrum", message, QSystemTrayIcon.Information, 20000)
# plugins
def init_plugins(self):
if text:
if old_text != text:
self.wallet.labels[name] = text
+ self.wallet.config.set_key('labels', self.wallet.labels)
changed = True
else:
if old_text:
self.previous_payto_e=''
def timer_actions(self):
+ if self.need_update.is_set():
+ self.update_wallet()
+ self.need_update.clear()
self.run_hook('timer_actions')
- def format_amount(self, x, is_diff=False):
- return format_satoshis(x, is_diff, self.wallet.num_zeros, self.decimal_point)
+ def format_amount(self, x, is_diff=False, whitespaces=False):
+ return format_satoshis(x, is_diff, self.wallet.num_zeros, self.decimal_point, whitespaces)
def read_amount(self, x):
if x in['.', '']: return None
text = _( "Balance" ) + ": %s "%( self.format_amount(c) ) + self.base_unit()
if u: text += " [%s unconfirmed]"%( self.format_amount(u,True).strip() )
text += self.create_quote_text(Decimal(c+u)/100000000)
+ self.tray.setToolTip(text)
icon = QIcon(":icons/status_connected.png")
else:
text = _("Not connected")
icon = QIcon(":icons/status_disconnected.png")
- self.status_text = text
- self.statusBar().showMessage(text)
+ self.balance_label.setText(text)
self.status_button.setIcon( icon )
def update_wallet(self):
if conf == -1:
time_str = 'unverified'
- icon = None
+ icon = QIcon(":icons/unconfirmed.png")
elif conf == 0:
time_str = 'pending'
icon = QIcon(":icons/unconfirmed.png")
icon = QIcon(":icons/confirmed.png")
if value is not None:
- v_str = self.format_amount(value, True)
+ v_str = self.format_amount(value, True, whitespaces=True)
else:
v_str = '--'
- balance_str = self.format_amount(balance)
+ balance_str = self.format_amount(balance, whitespaces=True)
if tx_hash:
label, is_default_label = self.wallet.get_label(tx_hash)
if inputs:
palette = QPalette()
palette.setColor(self.amount_e.foregroundRole(), QColor('black'))
- text = self.status_text
+ text = ""
else:
palette = QPalette()
palette.setColor(self.amount_e.foregroundRole(), QColor('red'))
return lambda s, *args: s.do_protect(func, args)
- @protected
- def do_send(self, password):
+ def do_send(self):
label = unicode( self.message_e.text() )
r = unicode( self.payto_e.text() )
QMessageBox.warning(self, _('Error'), _('Invalid Fee'), _('OK'))
return
+ confirm_amount = self.config.get('confirm_amount', 100000000)
+ if amount >= confirm_amount:
+ if not self.question("send %s to %s?"%(self.format_amount(amount) + ' '+ self.base_unit(), to_address)):
+ return
+
+ self.send_tx(to_address, amount, fee, label)
+
+
+ @protected
+ def send_tx(self, to_address, amount, fee, label, password):
+
try:
tx = self.wallet.mktx( [(to_address, amount)], password, fee, account=self.current_account)
except BaseException, e:
+ traceback.print_exc(file=sys.stdout)
self.show_message(str(e))
return
self.save_column_widths()
self.expert_mode = (i == 1)
self.config.set_key('classic_expert_mode', self.expert_mode, True)
- self.wallet.save()
self.update_receive_tab()
self.connect(l, SIGNAL('itemChanged(QTreeWidgetItem*, int)'), lambda a,b: self.address_label_changed(a,b,l,0,1))
self.contacts_list = l
self.contacts_buttons_hbox = hbox
- hbox.addWidget(EnterButton(_("New"), self.new_contact_dialog))
hbox.addStretch(1)
return w
def delete_imported_key(self, addr):
if self.question(_("Do you want to remove")+" %s "%addr +_("from your wallet?")):
- self.wallet.imported_keys.pop(addr)
+ self.wallet.delete_imported_key(addr)
self.update_receive_tab()
self.update_history_tab()
- self.wallet.save()
def create_receive_menu(self, position):
def delete_contact(self, x):
if self.question(_("Do you want to remove")+" %s "%x +_("from your list of contacts?")):
- if x in self.wallet.addressbook:
- self.wallet.addressbook.remove(x)
- self.set_label(x, None)
- self.update_history_tab()
- self.update_contacts_tab()
- self.update_completions()
+ self.wallet.delete_contact(x)
+ self.set_label(x, None)
+ self.update_history_tab()
+ self.update_contacts_tab()
+ self.update_completions()
def create_contact_menu(self, position):
account_items = []
for k, account in account_items:
- name = account.get('name',str(k))
+ name = account.get_name()
c,u = self.wallet.get_account_balance(k)
account_item = QTreeWidgetItem( [ name, '', self.format_amount(c+u), ''] )
l.addTopLevelItem(account_item)
is_red = False
gap = 0
- for address in account[is_change]:
+ for address in account.get_addresses(is_change):
h = self.wallet.history.get(address,[])
if h == []:
def update_contacts_tab(self):
-
l = self.contacts_list
l.clear()
self.update_receive_tab()
def create_status_bar(self):
- self.status_text = ""
+
sb = QStatusBar()
sb.setFixedHeight(35)
qtVersion = qVersion()
+ self.balance_label = QLabel("")
+ sb.addWidget(self.balance_label)
+
update_notification = UpdateLabel(self.config)
if(update_notification.new_version):
sb.addPermanentWidget(update_notification)
sb.addPermanentWidget( StatusBarButton( QIcon(":icons/preferences.png"), _("Preferences"), self.settings_dialog ) )
if self.wallet.seed:
sb.addPermanentWidget( StatusBarButton( QIcon(":icons/seed.png"), _("Seed"), self.show_seed_dialog ) )
- self.status_button = StatusBarButton( QIcon(":icons/status_disconnected.png"), _("Network"), lambda: self.network_dialog(self.wallet, self) )
+ self.status_button = StatusBarButton( QIcon(":icons/status_disconnected.png"), _("Network"), self.run_network_dialog )
sb.addPermanentWidget( self.status_button )
self.run_hook('create_status_bar', (sb,))
address = unicode(text)
if ok:
if is_valid(address):
- self.wallet.addressbook.append(address)
- self.wallet.save()
+ self.wallet.add_contact(address)
self.update_contacts_tab()
self.update_history_tab()
self.update_completions()
else:
QMessageBox.warning(self, _('Error'), _('Invalid Address'), _('OK'))
+ def new_account_dialog(self):
+ text, ok = QInputDialog.getText(self, _('New Account'), _('Name') + ':')
+ name = unicode(text)
+ if ok:
+ self.wallet.create_new_account(name)
+ self.wallet.synchronize()
+ self.update_contacts_tab()
+ self.update_history_tab()
+ self.update_completions()
+
def show_master_public_key(self):
dialog = QDialog(self)
dialog.setModal(1)
layout.setRowStretch(3,1)
def do_verify():
- try:
- self.wallet.verify_message(verify_address.text(), str(verify_signature.toPlainText()), str(verify_message.toPlainText()))
+ if self.wallet.verify_message(verify_address.text(), str(verify_signature.toPlainText()), str(verify_message.toPlainText())):
self.show_message(_("Signature verified"))
- except BaseException, e:
- self.show_message(str(e))
- return
+ else:
+ self.show_message(_("Error: wrong signature"))
hbox = QHBoxLayout()
b = QPushButton(_("Verify"))
QMessageBox.warning(parent, _('Error'), _('Passwords do not match'), _('OK'))
return ElectrumWindow.change_password_dialog(wallet, parent) # Retry
- wallet.update_password(seed, password, new_password)
+ try:
+ wallet.update_password(seed, password, new_password)
+ except:
+ QMessageBox.warning(parent, _('Error'), _('Failed to update password'), _('OK'))
+ return
+
+ QMessageBox.information(parent, _('Success'), _('Password was updated successfully'), _('OK'))
+
if parent:
icon = QIcon(":icons/lock.png") if wallet.use_encryption else QIcon(":icons/unlock.png")
parent.password_button.setIcon( icon )
fee_e.setText(self.format_amount(self.wallet.fee).strip())
grid_wallet.addWidget(fee_e, 0, 2)
msg = _('Fee per kilobyte of transaction.') + ' ' \
- + _('Recommended value') + ': ' + self.format_amount(20000)
+ + _('Recommended value') + ': ' + self.format_amount(50000)
grid_wallet.addWidget(HelpButton(msg), 0, 3)
if not self.config.is_modifiable('fee_per_kb'):
for w in [fee_e, fee_label]: w.setEnabled(False)
+ _(' This settings affects the fields in the Send tab')+' '), 3, 3)
grid_wallet.setRowStretch(4,1)
-
- # import/export tab
- tab3 = QWidget()
- grid_io = QGridLayout(tab3)
- grid_io.setColumnStretch(0,1)
- tabs.addTab(tab3, _('Import/Export') )
-
- grid_io.addWidget(QLabel(_('Labels')), 1, 0)
- grid_io.addWidget(EnterButton(_("Export"), self.do_export_labels), 1, 1)
- grid_io.addWidget(EnterButton(_("Import"), self.do_import_labels), 1, 2)
- grid_io.addWidget(HelpButton(_('Export your labels as json')), 1, 3)
-
- grid_io.addWidget(QLabel(_('History')), 2, 0)
- grid_io.addWidget(EnterButton(_("Export"), self.do_export_history), 2, 1)
- grid_io.addWidget(HelpButton(_('Export your transaction history as csv')), 2, 3)
-
- grid_io.addWidget(QLabel(_('Private keys')), 3, 0)
-
- grid_io.addWidget(EnterButton(_("Export"), self.do_export_privkeys), 3, 1)
- grid_io.addWidget(EnterButton(_("Import"), self.do_import_privkey), 3, 2)
- grid_io.addWidget(HelpButton(_('Import private key')), 3, 3)
-
- grid_io.addWidget(QLabel(_('Master Public Key')), 4, 0)
- grid_io.addWidget(EnterButton(_("Show"), self.show_master_public_key), 4, 1)
- grid_io.addWidget(HelpButton(_('Your Master Public Key can be used to create receiving addresses, but not to sign transactions.') + ' ' \
- + _('If you give it to someone, they will be able to see your transactions, but not to spend your money.') + ' ' \
- + _('If you restore your wallet from it, a watching-only (deseeded) wallet will be created.')), 4, 3)
-
-
- grid_io.addWidget(QLabel(_("Load transaction")), 5, 0)
- grid_io.addWidget(EnterButton(_("From file"), self.do_process_from_file), 5, 1)
- grid_io.addWidget(EnterButton(_("From text"), self.do_process_from_text), 5, 2)
- grid_io.addWidget(HelpButton(_("This will give you the option to sign or broadcast a transaction based on it's status.")), 5, 3)
-
- grid_io.setRowStretch(6,1)
-
-
# plugins
if self.plugins:
tab5 = QScrollArea()
grid_plugins = QGridLayout()
grid_plugins.setColumnStretch(0,1)
- w = QtGui.QWidget()
+ w = QWidget()
w.setLayout(grid_plugins)
tab5.setWidget(w)
- tab5.setMaximumSize(tab3.size()) # optional
w.setMinimumHeight(len(self.plugins)*35)
QMessageBox.warning(self, _('Error'), _('Invalid value') +': %s'%fee, _('OK'))
return
- if self.wallet.fee != fee:
- self.wallet.fee = fee
- self.wallet.save()
+ self.wallet.set_fee(fee)
nz = unicode(nz_e.text())
try:
self.receive_tab_set_mode(expert_cb.isChecked())
-
- @staticmethod
- def network_dialog(wallet, parent=None):
- interface = wallet.interface
- if parent:
- if interface.is_connected:
- status = _("Connected to")+" %s\n%d "%(interface.host, wallet.verifier.height)+_("blocks")
- else:
- status = _("Not connected")
- server = interface.server
- else:
- import random
- status = _("Please choose a server.") + "\n" + _("Select 'Cancel' if you are offline.")
- server = interface.server
-
- plist, servers_list = interface.get_servers_list()
-
- d = QDialog(parent)
- d.setModal(1)
- d.setWindowTitle(_('Server'))
- d.setMinimumSize(375, 20)
-
- vbox = QVBoxLayout()
- vbox.setSpacing(30)
-
- hbox = QHBoxLayout()
- l = QLabel()
- l.setPixmap(QPixmap(":icons/network.png"))
- hbox.addStretch(10)
- hbox.addWidget(l)
- hbox.addWidget(QLabel(status))
- hbox.addStretch(50)
- vbox.addLayout(hbox)
-
-
- # grid layout
- grid = QGridLayout()
- grid.setSpacing(8)
- vbox.addLayout(grid)
-
- # server
- server_protocol = QComboBox()
- server_host = QLineEdit()
- server_host.setFixedWidth(200)
- server_port = QLineEdit()
- server_port.setFixedWidth(60)
-
- protocol_names = ['TCP', 'HTTP', 'SSL', 'HTTPS']
- protocol_letters = 'thsg'
- server_protocol.addItems(protocol_names)
-
- grid.addWidget(QLabel(_('Server') + ':'), 0, 0)
- grid.addWidget(server_protocol, 0, 1)
- grid.addWidget(server_host, 0, 2)
- grid.addWidget(server_port, 0, 3)
-
- def change_protocol(p):
- protocol = protocol_letters[p]
- host = unicode(server_host.text())
- pp = plist.get(host,DEFAULT_PORTS)
- if protocol not in pp.keys():
- protocol = pp.keys()[0]
- port = pp[protocol]
- server_host.setText( host )
- server_port.setText( port )
-
- server_protocol.connect(server_protocol, SIGNAL('currentIndexChanged(int)'), change_protocol)
-
- label = _('Active Servers') if wallet.interface.servers else _('Default Servers')
- servers_list_widget = QTreeWidget(parent)
- servers_list_widget.setHeaderLabels( [ label, _('Limit') ] )
- servers_list_widget.setMaximumHeight(150)
- servers_list_widget.setColumnWidth(0, 240)
- for _host in servers_list.keys():
- pruning_level = servers_list[_host].get('pruning','')
- servers_list_widget.addTopLevelItem(QTreeWidgetItem( [ _host, pruning_level ] ))
- servers_list_widget.setColumnHidden(1, not parent.expert_mode if parent else True)
-
- def change_server(host, protocol=None):
- pp = plist.get(host,DEFAULT_PORTS)
- if protocol:
- port = pp.get(protocol)
- if not port: protocol = None
-
- if not protocol:
- if 's' in pp.keys():
- protocol = 's'
- port = pp.get(protocol)
- else:
- protocol = pp.keys()[0]
- port = pp.get(protocol)
-
- server_host.setText( host )
- server_port.setText( port )
- server_protocol.setCurrentIndex(protocol_letters.index(protocol))
-
- if not plist: return
- for p in protocol_letters:
- i = protocol_letters.index(p)
- j = server_protocol.model().index(i,0)
- if p not in pp.keys() and interface.is_connected:
- server_protocol.model().setData(j, QtCore.QVariant(0), QtCore.Qt.UserRole-1)
- else:
- server_protocol.model().setData(j, QtCore.QVariant(33), QtCore.Qt.UserRole-1)
-
- if server:
- host, port, protocol = server.split(':')
- change_server(host,protocol)
-
- servers_list_widget.connect(servers_list_widget, SIGNAL('currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)'),
- lambda x,y: change_server(unicode(x.text(0))))
- grid.addWidget(servers_list_widget, 1, 1, 1, 3)
-
- if not wallet.config.is_modifiable('server'):
- for w in [server_host, server_port, server_protocol, servers_list_widget]: w.setEnabled(False)
-
- # auto cycle
- autocycle_cb = QCheckBox(_('Try random servers if disconnected'))
- autocycle_cb.setChecked(wallet.config.get('auto_cycle', True))
- grid.addWidget(autocycle_cb, 3, 1, 3, 2)
- if not wallet.config.is_modifiable('auto_cycle'): autocycle_cb.setEnabled(False)
-
- # proxy setting
- proxy_mode = QComboBox()
- proxy_host = QLineEdit()
- proxy_host.setFixedWidth(200)
- proxy_port = QLineEdit()
- proxy_port.setFixedWidth(60)
- proxy_mode.addItems(['NONE', 'SOCKS4', 'SOCKS5', 'HTTP'])
-
- def check_for_disable(index = False):
- if proxy_mode.currentText() != 'NONE':
- proxy_host.setEnabled(True)
- proxy_port.setEnabled(True)
- else:
- proxy_host.setEnabled(False)
- proxy_port.setEnabled(False)
-
- check_for_disable()
- proxy_mode.connect(proxy_mode, SIGNAL('currentIndexChanged(int)'), check_for_disable)
-
- if not wallet.config.is_modifiable('proxy'):
- for w in [proxy_host, proxy_port, proxy_mode]: w.setEnabled(False)
-
- proxy_config = interface.proxy if interface.proxy else { "mode":"none", "host":"localhost", "port":"8080"}
- proxy_mode.setCurrentIndex(proxy_mode.findText(str(proxy_config.get("mode").upper())))
- proxy_host.setText(proxy_config.get("host"))
- proxy_port.setText(proxy_config.get("port"))
-
- grid.addWidget(QLabel(_('Proxy') + ':'), 2, 0)
- grid.addWidget(proxy_mode, 2, 1)
- grid.addWidget(proxy_host, 2, 2)
- grid.addWidget(proxy_port, 2, 3)
-
- # buttons
- vbox.addLayout(ok_cancel_buttons(d))
- d.setLayout(vbox)
-
- if not d.exec_(): return
-
- server = unicode( server_host.text() ) + ':' + unicode( server_port.text() ) + ':' + (protocol_letters[server_protocol.currentIndex()])
- if proxy_mode.currentText() != 'NONE':
- proxy = { u'mode':unicode(proxy_mode.currentText()).lower(), u'host':unicode(proxy_host.text()), u'port':unicode(proxy_port.text()) }
- else:
- proxy = None
-
- wallet.config.set_key("proxy", proxy, True)
- wallet.config.set_key("server", server, True)
- interface.set_server(server, proxy)
- wallet.config.set_key('auto_cycle', autocycle_cb.isChecked(), True)
- return True
+ def run_network_dialog(self):
+ NetworkDialog(self.wallet.interface, self.config, self).do_exec()
def closeEvent(self, event):
g = self.geometry()
event.accept()
+
+
+
class ElectrumGui:
def __init__(self, wallet, config, app=None):
def network_dialog(self):
- return ElectrumWindow.network_dialog( self.wallet, parent=None )
+ return NetworkDialog(self.wallet.interface, self.config, None).do_exec()
def show_seed(self):