c021e8b380776afd57956b67ef94cbe1632333ae
[electrum-nvc.git] / gui / qt / util.py
1 from electrum.i18n import _
2 from PyQt4.QtGui import *
3 from PyQt4.QtCore import *
4 import os.path
5 import time
6 import traceback
7 import sys
8 import threading
9
10 class WaitingDialog(QThread):
11     def __init__(self, parent, message, run_task, on_complete=None):
12         QThread.__init__(self)
13         self.parent = parent
14         self.d = QDialog(parent)
15         self.d.setWindowTitle('Please wait')
16         l = QLabel(message)
17         vbox = QVBoxLayout(self.d)
18         vbox.addWidget(l)
19         self.run_task = run_task
20         self.on_complete = on_complete
21         self.d.connect(self.d, SIGNAL('done'), self.close)
22         self.d.show()
23
24     def run(self):
25         self.error = None
26         try:
27             self.result = self.run_task()
28         except Exception as e:
29             traceback.print_exc(file=sys.stdout)
30             self.error = str(e)
31         self.d.emit(SIGNAL('done'))
32
33     def close(self):
34         self.d.accept()
35         if self.error:
36             QMessageBox.warning(self.parent, _('Error'), self.error, _('OK'))
37             return
38
39         if self.on_complete:
40             if type(self.result) is tuple:
41                 self.on_complete(*self.result)
42             else:
43                 self.on_complete(self.result)
44
45
46
47 class Timer(QThread):
48     def run(self):
49         while True:
50             self.emit(SIGNAL('timersignal'))
51             time.sleep(0.5)
52
53
54 class EnterButton(QPushButton):
55     def __init__(self, text, func):
56         QPushButton.__init__(self, text)
57         self.func = func
58         self.clicked.connect(func)
59
60     def keyPressEvent(self, e):
61         if e.key() == Qt.Key_Return:
62             apply(self.func,())
63
64
65
66
67
68 class HelpButton(QPushButton):
69     def __init__(self, text):
70         QPushButton.__init__(self, '?')
71         self.help_text = text
72         self.setFocusPolicy(Qt.NoFocus)
73         self.setFixedWidth(20)
74         self.alt = None
75         self.clicked.connect(self.onclick)
76
77     def set_alt(self, func):
78         self.alt = func
79
80     def onclick(self):
81         if self.alt:
82             apply(self.alt)
83         else:
84             QMessageBox.information(self, 'Help', self.help_text, 'OK')
85
86
87
88 def close_button(dialog, label=_("Close") ):
89     hbox = QHBoxLayout()
90     hbox.addStretch(1)
91     b = QPushButton(label)
92     hbox.addWidget(b)
93     b.clicked.connect(dialog.close)
94     b.setDefault(True)
95     return hbox
96
97 def ok_cancel_buttons2(dialog, ok_label=_("OK") ):
98     hbox = QHBoxLayout()
99     hbox.addStretch(1)
100     b = QPushButton(_("Cancel"))
101     hbox.addWidget(b)
102     b.clicked.connect(dialog.reject)
103     b = QPushButton(ok_label)
104     hbox.addWidget(b)
105     b.clicked.connect(dialog.accept)
106     b.setDefault(True)
107     return hbox, b
108
109 def ok_cancel_buttons(dialog, ok_label=_("OK") ):
110     hbox, b = ok_cancel_buttons2(dialog, ok_label)
111     return hbox
112
113 def line_dialog(parent, title, label, ok_label, default=None):
114     dialog = QDialog(parent)
115     dialog.setMinimumWidth(500)
116     dialog.setWindowTitle(title)
117     dialog.setModal(1)
118     l = QVBoxLayout()
119     dialog.setLayout(l)
120     l.addWidget(QLabel(label))
121     txt = QLineEdit()
122     if default:
123         txt.setText(default)
124     l.addWidget(txt)
125     l.addLayout(ok_cancel_buttons(dialog, ok_label))
126     if dialog.exec_():
127         return unicode(txt.text())
128
129 def text_dialog(parent, title, label, ok_label, default=None):
130     from qrtextedit import QRTextEdit
131     dialog = QDialog(parent)
132     dialog.setMinimumWidth(500)
133     dialog.setWindowTitle(title)
134     dialog.setModal(1)
135     l = QVBoxLayout()
136     dialog.setLayout(l)
137     l.addWidget(QLabel(label))
138     txt = QRTextEdit()
139     if default:
140         txt.setText(default)
141     l.addWidget(txt)
142     l.addLayout(ok_cancel_buttons(dialog, ok_label))
143     if dialog.exec_():
144         return unicode(txt.toPlainText())
145
146
147
148 def address_field(addresses):
149     hbox = QHBoxLayout()
150     address_e = QLineEdit()
151     if addresses:
152         address_e.setText(addresses[0])
153     def func():
154         i = addresses.index(str(address_e.text())) + 1
155         i = i % len(addresses)
156         address_e.setText(addresses[i])
157     button = QPushButton(_('Address'))
158     button.clicked.connect(func)
159     hbox.addWidget(button)
160     hbox.addWidget(address_e)
161     return hbox, address_e
162
163
164 def filename_field(parent, config, defaultname, select_msg):
165
166     vbox = QVBoxLayout()
167     vbox.addWidget(QLabel(_("Format")))
168     gb = QGroupBox("format", parent)
169     b1 = QRadioButton(gb)
170     b1.setText(_("CSV"))
171     b1.setChecked(True)
172     b2 = QRadioButton(gb)
173     b2.setText(_("json"))
174     vbox.addWidget(b1)
175     vbox.addWidget(b2)
176         
177     hbox = QHBoxLayout()
178
179     directory = config.get('io_dir', unicode(os.path.expanduser('~')))
180     path = os.path.join( directory, defaultname )
181     filename_e = QLineEdit()
182     filename_e.setText(path)
183
184     def func():
185         text = unicode(filename_e.text())
186         _filter = "*.csv" if text.endswith(".csv") else "*.json" if text.endswith(".json") else None
187         p = unicode( QFileDialog.getSaveFileName(None, select_msg, text, _filter))
188         if p:
189             filename_e.setText(p)
190
191     button = QPushButton(_('File'))
192     button.clicked.connect(func)
193     hbox.addWidget(button)
194     hbox.addWidget(filename_e)
195     vbox.addLayout(hbox)
196
197     def set_csv(v):
198         text = unicode(filename_e.text())
199         text = text.replace(".json",".csv") if v else text.replace(".csv",".json")
200         filename_e.setText(text)
201
202     b1.clicked.connect(lambda: set_csv(True))
203     b2.clicked.connect(lambda: set_csv(False))
204
205     return vbox, filename_e, b1
206
207
208
209 class MyTreeWidget(QTreeWidget):
210     def __init__(self, parent):
211         QTreeWidget.__init__(self, parent)
212         self.setContextMenuPolicy(Qt.CustomContextMenu)
213         self.connect(self, SIGNAL('itemActivated(QTreeWidgetItem*, int)'), self.itemactivated)
214
215     def itemactivated(self, item):
216         if not item: return
217         for i in range(0,self.viewport().height()/5):
218             if self.itemAt(QPoint(0,i*5)) == item:
219                 break
220         else:
221             return
222         for j in range(0,30):
223             if self.itemAt(QPoint(0,i*5 + j)) != item:
224                 break
225         self.emit(SIGNAL('customContextMenuRequested(const QPoint&)'), QPoint(50, i*5 + j - 1))
226
227
228
229
230 if __name__ == "__main__":
231     app = QApplication([])
232     t = WaitingDialog(None, 'testing ...', lambda: [time.sleep(1)], lambda x: QMessageBox.information(None, 'done', "done", _('OK')))
233     t.start()
234     app.exec_()