commit 608d4cad744da11f80ccae10be968713b2b0f0f1
parent 4e54081c5c99967ce8172cd33d47aa8d69cea7cb
Author: Maran <maran.hidskes@gmail.com>
Date: Thu, 2 Aug 2012 18:07:25 +0200
Merge branch 'cobleebuilder'
Diffstat:
9 files changed, 220 insertions(+), 129 deletions(-)
diff --git a/README b/README
@@ -29,6 +29,11 @@ python mki18n.py
pyrcc4 icons.qrc -o lib/icons_rc.py
python setup.py sdist --format=zip,gztar
+On Mac OS X:
+
+ sudo python setup-release.py py2app
+ sudo hdiutil create -fs HFS+ -volname "Electrum" -srcfolder dist/Electrum.app dist/electrum-v0.61-macosx.dmg
+
== BROWSER CONFIGURATION ==
diff --git a/data/icons/accounts.png b/data/icons/accounts.png
Binary files differ.
diff --git a/data/icons/expand.png b/data/icons/expand.png
Binary files differ.
diff --git a/data/icons/interact.png b/data/icons/interact.png
Binary files differ.
diff --git a/data/style.css b/data/style.css
@@ -1,35 +1,80 @@
#main_window
{
- background-image: url(background.png);
+ background: qlineargradient(x1: 0, y1: 0, x2:0,y2:1, stop: 0 white , stop: 1 #E8E8E8);
}
-#address_input[readOnly=true], #amount_input[readOnly=true]
-{
- font: italic;
- color: gray;
+MiniWindow QPushButton {
+ color: #777;
+ border: 1px solid #CCC;
+ border-radius: 0px;
+ background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
+ stop: 0 white, stop: 1 #E6E6E6);
+ min-height: 25px;
+ min-width: 30px;
}
-#address_input[readOnly=false], #amount_input[readOnly=false]
-{
- font: normal;
- color: black;
+
+#send_button{
+ color: #E5F2FF;
+ border: 1px solid #3786E6;
+ border-radius: 4px;
+ background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
+ stop: 0 #72B2F8, stop: 1 #3484E6);
+ min-width: 80px;
+ min-height: 23px;
+ padding: 2px;
+}
+
+#send_button:disabled{
+ color: #D3E8FE;
+ border: 1px solid #6DAEF7;
+ border-radius: 4px;
+ background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
+ stop: 0 #A5CFFA, stop: 1 #72B2F8);
+ min-width: 80px;
+ min-height: 23px;
+ padding: 2px;
}
-#valid_address::indicator
+#address_input, #amount_input
{
- width: 24px;
- height: 24px;
+ color: #000;
+ padding: 5px;
+ border-radius: 4px;
+ border: 1px solid #AAA9A9;
+ width: 225px;
+ margin-top: 4px;
}
-#valid_address::indicator:checked
+
+#address_input[isValid=true]
{
- image: url(icons/confirmed.png);
+ color: #4D9948;
+ padding: 5px;
+ border-radius: 4px;
+ border: 1px solid #AAA9A9;
+ width: 225px;
+ margin-top: 4px;
}
-#valid_address::indicator:unchecked
+
+#address_input[isValid=false]
{
- image: url(icons/unconfirmed.png);
+ color: #CE4141;
+ padding: 5px;
+ border-radius: 4px;
+ border: 1px solid #AAA9A9;
+ width: 225px;
+ margin-top: 4px;
}
+#address_input[isValid=placeholder]
+{
+ color: blue;
+ padding: 5px;
+ border-radius: 4px;
+ border: 1px solid #AAA9A9;
+ width: 225px;
+ margin-top: 4px;
+}
#balance_label
{
- color: white;
+ color: #333;
}
-
diff --git a/electrum.icns b/electrum.icns
Binary files differ.
diff --git a/lib/gui_lite.py b/lib/gui_lite.py
@@ -109,34 +109,6 @@ class MiniWindow(QDialog):
self.actuator = actuator
- accounts_button = IconButton(rsrc("icons", "accounts.png"))
- accounts_button.setObjectName("accounts_button")
-
- self.accounts_selector = QMenu()
- accounts_button.setMenu(self.accounts_selector)
-
- interact_button = IconButton(rsrc("icons", "interact.png"))
- interact_button.setObjectName("interact_button")
-
- app_menu = QMenu(interact_button)
- acceptbit_action = app_menu.addAction(_("A&cceptBit"))
- report_action = app_menu.addAction(_("&Report Bug"))
- about_action = app_menu.addAction(_("&About Electrum"))
- app_menu.addSeparator()
- quit_action = app_menu.addAction(_("&Quit"))
- interact_button.setMenu(app_menu)
-
- self.connect(acceptbit_action, SIGNAL("triggered()"),
- self.acceptbit)
- self.connect(report_action, SIGNAL("triggered()"),
- self.show_report_bug)
- self.connect(about_action, SIGNAL("triggered()"), self.show_about)
- self.connect(quit_action, SIGNAL("triggered()"), self.close)
-
- expand_button = IconButton(rsrc("icons", "expand.png"))
- expand_button.setObjectName("expand_button")
- self.connect(expand_button, SIGNAL("clicked()"), expand_callback)
-
self.btc_balance = None
self.quote_currencies = ["EUR", "USD", "GBP"]
self.actuator.set_configured_currency(self.set_quote_currency)
@@ -151,15 +123,16 @@ class MiniWindow(QDialog):
self.receive_button = QPushButton(_("&Receive"))
self.receive_button.setObjectName("receive_button")
self.receive_button.setDefault(True)
- self.connect(self.receive_button, SIGNAL("clicked()"),
- self.copy_address)
+ self.connect(self.receive_button, SIGNAL("clicked()"), self.copy_address)
- self.address_input = TextedLineEdit(_("Enter a Bitcoin address..."))
+ # Bitcoin address code
+ self.address_input = QLineEdit()
+ self.address_input.setPlaceholderText(_("Enter a Bitcoin address..."))
self.address_input.setObjectName("address_input")
- self.connect(self.address_input, SIGNAL("textEdited(QString)"),
- self.address_field_changed)
- resize_line_edit_width(self.address_input,
- "1BtaFUr3qVvAmwrsuDuu5zk6e4s2rxd2Gy")
+
+
+ self.connect(self.address_input, SIGNAL("textEdited(QString)"), self.address_field_changed)
+ resize_line_edit_width(self.address_input, "1BtaFUr3qVvAmwrsuDuu5zk6e4s2rxd2Gy")
self.address_completions = QStringListModel()
address_completer = QCompleter(self.address_input)
@@ -167,16 +140,11 @@ class MiniWindow(QDialog):
address_completer.setModel(self.address_completions)
self.address_input.setCompleter(address_completer)
- self.valid_address = QCheckBox()
- self.valid_address.setObjectName("valid_address")
- self.valid_address.setEnabled(False)
- self.valid_address.setChecked(False)
-
address_layout = QHBoxLayout()
address_layout.addWidget(self.address_input)
- address_layout.addWidget(self.valid_address)
- self.amount_input = TextedLineEdit(_("... and amount"))
+ self.amount_input = QLineEdit()
+ self.amount_input.setPlaceholderText(_("... and amount"))
self.amount_input.setObjectName("amount_input")
# This is changed according to the user's displayed balance
self.amount_validator = QDoubleValidator(self.amount_input)
@@ -184,29 +152,50 @@ class MiniWindow(QDialog):
self.amount_validator.setDecimals(8)
self.amount_input.setValidator(self.amount_validator)
+ # This removes the very ugly OSX highlighting, please leave this in :D
+ self.address_input.setAttribute(Qt.WA_MacShowFocusRect, 0)
+ self.amount_input.setAttribute(Qt.WA_MacShowFocusRect, 0)
+
self.connect(self.amount_input, SIGNAL("textChanged(QString)"),
self.amount_input_changed)
- amount_layout = QHBoxLayout()
- amount_layout.addWidget(self.amount_input)
- amount_layout.addStretch()
-
- send_button = QPushButton(_("&Send"))
- send_button.setObjectName("send_button")
- self.connect(send_button, SIGNAL("clicked()"), self.send)
+ self.send_button = QPushButton(_("&Send"))
+ self.send_button.setObjectName("send_button")
+ self.send_button.setDisabled(True);
+ self.connect(self.send_button, SIGNAL("clicked()"), self.send)
main_layout = QGridLayout(self)
- main_layout.addWidget(accounts_button, 0, 0)
- main_layout.addWidget(interact_button, 1, 0)
- main_layout.addWidget(expand_button, 2, 0)
- main_layout.addWidget(self.balance_label, 0, 1)
- main_layout.addWidget(self.receive_button, 0, 2)
+ main_layout.addWidget(self.balance_label, 0, 0)
+ main_layout.addWidget(self.receive_button, 0, 1)
+
+ main_layout.addWidget(self.address_input, 1, 0, 1, -1)
- main_layout.addLayout(address_layout, 1, 1, 1, -1)
+ main_layout.addWidget(self.amount_input, 2, 0)
+ main_layout.addWidget(self.send_button, 2, 1)
- main_layout.addLayout(amount_layout, 2, 1)
- main_layout.addWidget(send_button, 2, 2)
+ menubar = QMenuBar()
+ electrum_menu = menubar.addMenu(_("&Electrum"))
+ electrum_menu.addMenu(_("&Servers"))
+ electrum_menu.addSeparator()
+ electrum_menu.addAction(_("&Quit"))
+
+ view_menu = menubar.addMenu(_("&View"))
+ expert_gui = view_menu.addAction(_("&Pro Mode"))
+ self.connect(expert_gui, SIGNAL("triggered()"), expand_callback)
+ view_menu.addMenu(_("&Themes"))
+ view_menu.addSeparator()
+ view_menu.addAction(_("Show History"))
+
+ settings_menu = menubar.addMenu(_("&Settings"))
+ settings_menu.addAction(_("&Configure Electrum"))
+
+ help_menu = menubar.addMenu(_("&Help"))
+ help_menu.addAction(_("&Contents"))
+ help_menu.addSeparator()
+ help_menu.addAction(_("&Report Bug"))
+ help_menu.addAction(_("&About"))
+ main_layout.setMenuBar(menubar)
quit_shortcut = QShortcut(QKeySequence("Ctrl+Q"), self)
self.connect(quit_shortcut, SIGNAL("activated()"), self.close)
@@ -219,16 +208,18 @@ class MiniWindow(QDialog):
self.layout().setSizeConstraint(QLayout.SetFixedSize)
self.setObjectName("main_window")
self.show()
+
+ def recompute_style(self):
+ qApp.style().unpolish(self)
+ qApp.style().polish(self)
def closeEvent(self, event):
super(MiniWindow, self).closeEvent(event)
qApp.quit()
def set_payment_fields(self, dest_address, amount):
- self.address_input.become_active()
self.address_input.setText(dest_address)
self.address_field_changed(dest_address)
- self.amount_input.become_active()
self.amount_input.setText(amount)
def activate(self):
@@ -264,14 +255,11 @@ class MiniWindow(QDialog):
quote_text = "(%s)" % quote_text
btc_balance = "%.2f" % (btc_balance / bitcoin(1))
self.balance_label.set_balance_text(btc_balance, quote_text)
- main_account_info = \
- "Checking - %s BTC" % btc_balance
- self.setWindowTitle("Electrum - %s" % main_account_info)
- self.accounts_selector.clear()
- self.accounts_selector.addAction("%s %s" % (main_account_info,
- quote_text))
+ self.setWindowTitle("Electrum - %s BTC" % btc_balance)
def amount_input_changed(self, amount_text):
+ self.check_button_status()
+
try:
amount = D(str(amount_text))
except decimal.InvalidOperation:
@@ -295,16 +283,33 @@ class MiniWindow(QDialog):
return quote_text
def send(self):
- if self.actuator.send(self.address_input.text(),
- self.amount_input.text(), self):
- self.address_input.become_inactive()
- self.amount_input.become_inactive()
+ if self.actuator.send(self.address_input.text(), self.amount_input.text(), self):
+ self.address_input.setText("")
+ self.amount_input.setText("")
+
+ def check_button_status(self):
+ if self.address_input.property("isValid") == True and len(self.amount_input.text()) != 0:
+ self.send_button.setDisabled(False)
+ else:
+ self.send_button.setDisabled(True)
def address_field_changed(self, address):
if self.actuator.is_valid(address):
- self.valid_address.setChecked(True)
+ self.check_button_status()
+ self.address_input.setProperty("isValid", True)
+ self.recompute_style(self.address_input)
else:
- self.valid_address.setChecked(False)
+ self.send_button.setDisabled(True)
+ self.address_input.setProperty("isValid", False)
+ self.recompute_style(self.address_input)
+
+ if len(address) == 0:
+ self.address_input.setProperty("isValid", None)
+ self.recompute_style(self.address_input)
+
+ def recompute_style(self, element):
+ self.style().unpolish(element)
+ self.style().polish(element)
def copy_address(self):
receive_popup = ReceivePopup(self.receive_button)
@@ -344,7 +349,7 @@ class BalanceLabel(QLabel):
def set_balance_text(self, btc_balance, quote_text):
if self.state == self.SHOW_CONNECTING:
self.state = self.SHOW_BALANCE
- self.balance_text = "<span style='font-size: 16pt'>%s</span> <span style='font-size: 10pt'>BTC</span> <span style='font-size: 10pt'>%s</span>" % (btc_balance, quote_text)
+ self.balance_text = "<span style='font-size: 18pt'>%s</span> <span style='font-size: 10pt'>BTC</span> <span style='font-size: 10pt'>%s</span>" % (btc_balance, quote_text)
if self.state == self.SHOW_BALANCE:
self.setText(self.balance_text)
@@ -363,44 +368,6 @@ class BalanceLabel(QLabel):
self.state = self.SHOW_AMOUNT
self.setText(self.amount_text)
-class TextedLineEdit(QLineEdit):
-
- def __init__(self, inactive_text, parent=None):
- super(QLineEdit, self).__init__(parent)
- self.inactive_text = inactive_text
- self.become_inactive()
-
- def mousePressEvent(self, event):
- if self.isReadOnly():
- self.become_active()
- QLineEdit.mousePressEvent(self, event)
-
- def focusOutEvent(self, event):
- if self.text() == "":
- self.become_inactive()
- QLineEdit.focusOutEvent(self, event)
-
- def focusInEvent(self, event):
- if self.isReadOnly():
- self.become_active()
- QLineEdit.focusInEvent(self, event)
-
- def become_inactive(self):
- self.setReadOnly(True)
- self.recompute_style()
- self.setText(self.inactive_text)
-
- def become_active(self):
- self.setReadOnly(False)
- self.recompute_style()
- self.setText("")
-
- def recompute_style(self):
- qApp.style().unpolish(self)
- qApp.style().polish(self)
- # also possible but more expensive:
- #qApp.setStyleSheet(qApp.styleSheet())
-
def ok_cancel_buttons(dialog):
row_layout = QHBoxLayout()
row_layout.addStretch(1)
diff --git a/lib/gui_qt.py b/lib/gui_qt.py
@@ -153,7 +153,7 @@ class QRCodeWidget(QWidget):
def paintEvent(self, e):
qp = QtGui.QPainter()
qp.begin(self)
- boxsize = 7
+ boxsize = 6
size = self.qr.getModuleCount()*boxsize
k = self.qr.getModuleCount()
black = QColor(0, 0, 0, 255)
diff --git a/setup-release.py b/setup-release.py
@@ -0,0 +1,74 @@
+"""
+py2app/py2exe build script for Electrum Litecoin
+
+Usage (Mac OS X):
+ python setup.py py2app
+
+Usage (Windows):
+ python setup.py py2exe
+"""
+
+import sys, os, shutil, re
+from setuptools import setup
+from lib.version import ELECTRUM_VERSION as version
+from lib.util import print_error
+
+
+name = "Electrum"
+mainscript = 'electrum'
+
+if sys.version_info[:3] < (2,6,0):
+ print_error("Error: " + name + " requires Python version >= 2.6.0...")
+ sys.exit(1)
+
+if sys.platform == 'darwin':
+ shutil.copy(mainscript, mainscript + '.py')
+ mainscript += '.py'
+ extra_options = dict(
+ setup_requires=['py2app'],
+ app=[mainscript],
+ options=dict(py2app=dict(argv_emulation=True,
+ iconfile='electrum.icns',
+ resources=["data/background.png", "data/style.css", "data/icons"])),
+ )
+elif sys.platform == 'win32':
+ extra_options = dict(
+ setup_requires=['py2exe'],
+ app=[mainscript],
+ )
+else:
+ extra_options = dict(
+ # Normally unix-like platforms will use "setup.py install"
+ # and install the main script as such
+ scripts=[mainscript],
+ )
+
+setup(
+ name = name,
+ version = version,
+ **extra_options
+)
+
+if sys.platform == 'darwin':
+ # Remove the copied py file
+ os.remove(mainscript)
+ resource = "dist/" + name + ".app/Contents/Resources/"
+
+ # Try to locate qt_menu
+ # Let's try the port version first!
+ if os.path.isfile("/opt/local/lib/Resources/qt_menu.nib"):
+ qt_menu_location = "/opt/local/lib/Resources/qt_menu.nib"
+ else:
+ # No dice? Then let's try the brew version
+ qt_menu_location = os.popen("mdfind -name qt_menu.nib | grep Cellar | head").read()
+ qt_menu_location = re.sub('\n','', qt_menu_location)
+
+ if(len(qt_menu_location) == 0):
+ print "Sorry couldn't find your qt_menu.nib this probably won't work"
+
+ # Need to include a copy of qt_menu.nib
+ shutil.copytree(qt_menu_location, resource + "qt_menu.nib")
+ # Need to touch qt.conf to avoid loading 2 sets of Qt libraries
+ fname = resource + "qt.conf"
+ with file(fname, 'a'):
+ os.utime(fname, None)