bitcoin-ruby 0.0.6 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -1
  3. data/.travis.yml +2 -7
  4. data/COPYING +1 -1
  5. data/Gemfile +2 -6
  6. data/Gemfile.lock +34 -0
  7. data/README.rdoc +16 -68
  8. data/Rakefile +3 -6
  9. data/bin/bitcoin_shell +0 -1
  10. data/{concept-examples/blockchain-pow.rb → examples/concept-blockchain-pow.rb} +0 -0
  11. data/lib/bitcoin.rb +350 -296
  12. data/lib/bitcoin/builder.rb +3 -1
  13. data/lib/bitcoin/connection.rb +2 -1
  14. data/lib/bitcoin/contracthash.rb +76 -0
  15. data/lib/bitcoin/dogecoin.rb +97 -0
  16. data/lib/bitcoin/ffi/bitcoinconsensus.rb +74 -0
  17. data/lib/bitcoin/ffi/openssl.rb +98 -2
  18. data/lib/bitcoin/ffi/secp256k1.rb +144 -0
  19. data/lib/bitcoin/key.rb +12 -2
  20. data/lib/bitcoin/logger.rb +3 -12
  21. data/lib/bitcoin/protocol/block.rb +3 -9
  22. data/lib/bitcoin/protocol/parser.rb +6 -2
  23. data/lib/bitcoin/protocol/tx.rb +44 -13
  24. data/lib/bitcoin/protocol/txin.rb +4 -2
  25. data/lib/bitcoin/protocol/txout.rb +2 -2
  26. data/lib/bitcoin/script.rb +212 -37
  27. data/lib/bitcoin/trezor/mnemonic.rb +130 -0
  28. data/lib/bitcoin/version.rb +1 -1
  29. data/spec/bitcoin/bitcoin_spec.rb +32 -3
  30. data/spec/bitcoin/builder_spec.rb +18 -0
  31. data/spec/bitcoin/contracthash_spec.rb +45 -0
  32. data/spec/bitcoin/dogecoin_spec.rb +176 -0
  33. data/spec/bitcoin/ffi_openssl.rb +45 -0
  34. data/spec/bitcoin/fixtures/156e6e1b84c5c3bd3a0927b25e4119fadce6e6d5186f363317511d1d680fae9a.json +24 -0
  35. data/spec/bitcoin/fixtures/8d0b238a06b5a70be75d543902d02d7a514d68d3252a949a513865ac3538874c.json +24 -0
  36. data/spec/bitcoin/fixtures/coinbase-toshi.json +33 -0
  37. data/spec/bitcoin/fixtures/coinbase.json +24 -0
  38. data/spec/bitcoin/fixtures/dogecoin-block-60323982f9c5ff1b5a954eac9dc1269352835f47c2c5222691d80f0d50dcf053.bin +0 -0
  39. data/spec/bitcoin/fixtures/rawtx-01-toshi.json +46 -0
  40. data/spec/bitcoin/fixtures/rawtx-02-toshi.json +46 -0
  41. data/spec/bitcoin/fixtures/rawtx-03-toshi.json +73 -0
  42. data/spec/bitcoin/fixtures/rawtx-testnet-04fdc38d6722ab4b12d79113fc4b2896bdcc5169710690ee4e78541b98e467b4.bin +0 -0
  43. data/spec/bitcoin/fixtures/rawtx-testnet-0b294c7d11dd21bcccb8393e6744fed7d4d1981a08c00e3e88838cc421f33c9f.bin +0 -0
  44. data/spec/bitcoin/fixtures/rawtx-testnet-3bc52ac063291ad92d95ddda5fd776a342083b95607ad32ed8bc6f8f7d30449e.bin +0 -0
  45. data/spec/bitcoin/fixtures/rawtx-testnet-6f0bbdd4e71a8af4305018d738184df32dbb6f27284fdebd5b56d16947f7c181.bin +0 -0
  46. data/spec/bitcoin/fixtures/rawtx-testnet-a7c9b06e275e8674cc19a5f7d3e557c72c6d93576e635b33212dbe08ab7cdb60.bin +0 -0
  47. data/spec/bitcoin/fixtures/rawtx-testnet-f80acbd2f594d04ddb0e1cacba662132104909157dff526935a3c88abe9201a5.bin +0 -0
  48. data/spec/bitcoin/protocol/block_spec.rb +0 -22
  49. data/spec/bitcoin/protocol/tx_spec.rb +145 -2
  50. data/spec/bitcoin/script/script_spec.rb +282 -0
  51. data/spec/bitcoin/secp256k1_spec.rb +48 -0
  52. data/spec/bitcoin/spec_helper.rb +0 -51
  53. data/spec/bitcoin/trezor/mnemonic_spec.rb +161 -0
  54. metadata +48 -98
  55. data/bin/bitcoin_dns_seed +0 -130
  56. data/bin/bitcoin_gui +0 -80
  57. data/bin/bitcoin_node +0 -153
  58. data/bin/bitcoin_node_cli +0 -81
  59. data/bin/bitcoin_wallet +0 -402
  60. data/doc/CONFIG.rdoc +0 -66
  61. data/doc/EXAMPLES.rdoc +0 -13
  62. data/doc/NAMECOIN.rdoc +0 -34
  63. data/doc/NODE.rdoc +0 -225
  64. data/doc/STORAGE.rdoc +0 -33
  65. data/doc/WALLET.rdoc +0 -102
  66. data/examples/balance.rb +0 -66
  67. data/examples/forwarder.rb +0 -73
  68. data/examples/index_nhash.rb +0 -24
  69. data/examples/reindex_p2sh_addrs.rb +0 -44
  70. data/examples/relay_tx.rb +0 -22
  71. data/examples/verify_tx.rb +0 -57
  72. data/lib/bitcoin/config.rb +0 -58
  73. data/lib/bitcoin/gui/addr_view.rb +0 -44
  74. data/lib/bitcoin/gui/bitcoin-ruby.png +0 -0
  75. data/lib/bitcoin/gui/bitcoin-ruby.svg +0 -80
  76. data/lib/bitcoin/gui/conn_view.rb +0 -38
  77. data/lib/bitcoin/gui/connection.rb +0 -70
  78. data/lib/bitcoin/gui/em_gtk.rb +0 -30
  79. data/lib/bitcoin/gui/gui.builder +0 -1643
  80. data/lib/bitcoin/gui/gui.rb +0 -292
  81. data/lib/bitcoin/gui/helpers.rb +0 -115
  82. data/lib/bitcoin/gui/tree_view.rb +0 -84
  83. data/lib/bitcoin/gui/tx_view.rb +0 -69
  84. data/lib/bitcoin/namecoin.rb +0 -280
  85. data/lib/bitcoin/network/command_client.rb +0 -104
  86. data/lib/bitcoin/network/command_handler.rb +0 -570
  87. data/lib/bitcoin/network/connection_handler.rb +0 -387
  88. data/lib/bitcoin/network/node.rb +0 -565
  89. data/lib/bitcoin/storage/dummy/dummy_store.rb +0 -179
  90. data/lib/bitcoin/storage/models.rb +0 -171
  91. data/lib/bitcoin/storage/sequel/migrations.rb +0 -99
  92. data/lib/bitcoin/storage/sequel/migrations/001_base_schema.rb +0 -52
  93. data/lib/bitcoin/storage/sequel/migrations/002_tx.rb +0 -45
  94. data/lib/bitcoin/storage/sequel/migrations/003_change_txin_script_sig_to_blob.rb +0 -18
  95. data/lib/bitcoin/storage/sequel/migrations/004_change_txin_prev_out_to_blob.rb +0 -18
  96. data/lib/bitcoin/storage/sequel/migrations/005_change_tx_hash_to_bytea.rb +0 -14
  97. data/lib/bitcoin/storage/sequel/migrations/006_add_tx_nhash.rb +0 -31
  98. data/lib/bitcoin/storage/sequel/migrations/007_add_prev_out_index_index.rb +0 -16
  99. data/lib/bitcoin/storage/sequel/migrations/008_add_txin_p2sh_type.rb +0 -31
  100. data/lib/bitcoin/storage/sequel/migrations/009_add_addrs_type.rb +0 -56
  101. data/lib/bitcoin/storage/sequel/sequel_store.rb +0 -551
  102. data/lib/bitcoin/storage/storage.rb +0 -517
  103. data/lib/bitcoin/storage/utxo/migrations/001_base_schema.rb +0 -52
  104. data/lib/bitcoin/storage/utxo/migrations/002_utxo.rb +0 -18
  105. data/lib/bitcoin/storage/utxo/migrations/003_update_indices.rb +0 -14
  106. data/lib/bitcoin/storage/utxo/migrations/004_add_addrs_type.rb +0 -14
  107. data/lib/bitcoin/storage/utxo/utxo_store.rb +0 -374
  108. data/lib/bitcoin/validation.rb +0 -400
  109. data/lib/bitcoin/wallet/coinselector.rb +0 -33
  110. data/lib/bitcoin/wallet/keygenerator.rb +0 -77
  111. data/lib/bitcoin/wallet/keystore.rb +0 -207
  112. data/lib/bitcoin/wallet/txdp.rb +0 -118
  113. data/lib/bitcoin/wallet/wallet.rb +0 -281
  114. data/spec/bitcoin/fixtures/freicoin-block-000000005d231b285e63af83edae2d8f5e50e70d396468643092b9239fd3be3c.bin +0 -0
  115. data/spec/bitcoin/fixtures/freicoin-block-000000005d231b285e63af83edae2d8f5e50e70d396468643092b9239fd3be3c.json +0 -43
  116. data/spec/bitcoin/fixtures/freicoin-genesis-block-000000005b1e3d23ecfd2dd4a6e1a35238aa0392c0a8528c40df52376d7efe2c.bin +0 -0
  117. data/spec/bitcoin/fixtures/freicoin-genesis-block-000000005b1e3d23ecfd2dd4a6e1a35238aa0392c0a8528c40df52376d7efe2c.json +0 -67
  118. data/spec/bitcoin/namecoin_spec.rb +0 -182
  119. data/spec/bitcoin/node/command_api_spec.rb +0 -663
  120. data/spec/bitcoin/storage/models_spec.rb +0 -104
  121. data/spec/bitcoin/storage/reorg_spec.rb +0 -236
  122. data/spec/bitcoin/storage/storage_spec.rb +0 -387
  123. data/spec/bitcoin/storage/validation_spec.rb +0 -300
  124. data/spec/bitcoin/wallet/coinselector_spec.rb +0 -38
  125. data/spec/bitcoin/wallet/keygenerator_spec.rb +0 -69
  126. data/spec/bitcoin/wallet/keystore_spec.rb +0 -190
  127. data/spec/bitcoin/wallet/txdp_spec.rb +0 -76
  128. data/spec/bitcoin/wallet/wallet_spec.rb +0 -238
@@ -1,292 +0,0 @@
1
- # encoding: ascii-8bit
2
-
3
- require_relative "em_gtk.rb"
4
- require_relative "helpers.rb"
5
- require_relative "tree_view.rb"
6
- require_relative "addr_view.rb"
7
- require_relative "tx_view.rb"
8
- require_relative "conn_view.rb"
9
-
10
- Gtk.init
11
-
12
- module Bitcoin::Gui
13
-
14
- class Gui
15
-
16
- include Helpers
17
-
18
- attr_reader :builder, :wallet, :storage
19
- attr_accessor :node, :addr_view, :conn_view
20
-
21
- def initialize storage, wallet_file = nil
22
- @storage = storage
23
- @node = nil
24
- build
25
- @addr_view = AddrView.new(self)
26
- @tx_view = TxView.new(self, :tx_view)
27
- @conn_view = ConnView.new(self)
28
- open_wallet(wallet_file) if wallet_file
29
- main_window.show_all
30
- # notebook.next_page
31
- statusicon.tooltip_text = "Bitcoin-Ruby GUI"
32
- GObject.signal_connect(statusicon, "activate") do
33
- main_window.visible ? main_window.hide : main_window.show
34
- end
35
- GObject.signal_connect(statusicon, "popup-menu") do
36
- popup_menu.popup_for_device(nil, nil, nil, ->(*a) {}, nil, nil, 0, 0)
37
- end
38
- end
39
-
40
- def log
41
- @log ||= Bitcoin::Logger.create(:gui)
42
- end
43
-
44
- def build
45
- @builder = Gtk::Builder.new
46
- @builder.add_from_file(File.join(File.dirname(__FILE__), "gui.builder"))
47
- @builder.connect_signals_full(->(builder, widget, signal, handler, _, _, gui) do
48
- GObject.signal_connect(widget, signal) { gui.send(handler) }
49
- end, self)
50
-
51
- {
52
- "<Control>n" => :file_new,
53
- "<Control>o" => :file_open,
54
- "<Control>q" => :file_quit,
55
- "<Control>c" => :edit_copy,
56
- "<Control>v" => :edit_paste,
57
- "<Control>p" => :edit_preferences,
58
- "<Control>h" => :help_about,
59
- }.each do |binding, action|
60
- send("menu_#{action}").add_accelerator("activate", accelgroup1,
61
- *Gtk.accelerator_parse(binding), 0)
62
- end
63
- end
64
-
65
- def update_wallet_views
66
- return unless @wallet
67
- EM.defer do
68
- @addr_view.update(@wallet.keystore.keys)#.select{|k| k[:mine] == true})
69
- @tx_view.update(@wallet.get_txouts(true))
70
- unconfirmed = check_unconfirmed.active
71
- wallet_text = "wallet: #{@wallet.keystore.config[:file]} | " +
72
- "addresses: #{@wallet.addrs.size} | " +
73
- "balance: #{"%.8f" % (@wallet.get_balance(unconfirmed) / 1e8)}"
74
- status_wallet.push 0, wallet_text
75
- end
76
- end
77
-
78
- def on_check_unconfirmed_toggled
79
- update_wallet_views
80
- end
81
-
82
- def on_preferences
83
- dialog(:preferences, :setup => ->(d) {
84
- config = Bitcoin::Config.load({}, :wallet)
85
- model = preferences_box_network.get_model
86
- row = model.append
87
- model.set_value(row, 0, "foo")
88
- preferences_box_network.set_model model
89
- # preferences_entry_network.text = config[:network]
90
- }) do |*a|
91
- p a
92
- end
93
- end
94
-
95
- def on_copy_addr
96
- addrs = []
97
- valid, i = @addr_view.model.get_iter_first
98
- while valid
99
- if @addr_view.view.selection.iter_is_selected(i)
100
- a = @addr_view.model.get_value(i, 0).get_string
101
- addrs << a
102
- end
103
- valid = @addr_view.model.iter_next(i.to_ptr)
104
- end
105
-
106
- return unless addrs.any?
107
- text = addrs.join(", ")
108
- c = Gtk::Clipboard.get(Gdk::Atom.intern("PRIMARY", false))
109
- c.set_text text, text.size
110
- c = Gtk::Clipboard.get(Gdk::Atom.intern("CLIPBOARD", false))
111
- c.set_text text, text.size
112
- end
113
-
114
- def on_paste_addr
115
- c = Gtk::Clipboard.get(Gdk::Atom.intern("PRIMARY", false))
116
- c.request_text ->(clip, text, data) {
117
- on_new_addr(text) if Bitcoin.valid_address?(text)
118
- }, self
119
- c = Gtk::Clipboard.get(Gdk::Atom.intern("CLIPBOARD", false))
120
- c.request_text ->(clip, text, data) {
121
- on_new_addr(text) if Bitcoin.valid_address?(text)
122
- }, self
123
- end
124
-
125
- def on_new_addr addr = nil
126
- dialog(:new_addr, setup: ->(d) {
127
- new_addr_check_addr.active = addr ? true : false
128
- new_addr_check_pubkey.active = false
129
- new_addr_check_mine.active = addr ? false : true
130
- new_addr_entry_label.text = ""
131
- new_addr_entry_addr.text = addr ? addr : ""
132
- new_addr_entry_pubkey.text = ""
133
- new_addr_entry_addr.hide unless addr
134
- new_addr_entry_pubkey.hide
135
- GObject.signal_connect(new_addr_check_addr, "toggled") do
136
- new_addr_check_addr.active ? new_addr_entry_addr.show :
137
- new_addr_entry_addr.hide
138
- end
139
- GObject.signal_connect(new_addr_check_pubkey, "toggled") do
140
- new_addr_check_pubkey.active ? new_addr_entry_pubkey.show :
141
- new_addr_entry_pubkey.hide
142
- end
143
- }) do |*a|
144
- begin
145
- label = new_addr_entry_label.text
146
- set_address = new_addr_check_addr.active
147
- set_pubkey = new_addr_check_pubkey.active
148
- is_mine = new_addr_check_mine.active
149
- key = {:label => label}
150
- if set_address
151
- addr = new_addr_entry_addr.text
152
- raise "Address #{addr} invalid" unless Bitcoin.valid_address?(addr)
153
- key[:addr] = addr
154
- end
155
- if set_pubkey
156
- k = Bitcoin::Key.new(nil, new_addr_entry_pubkey.text)
157
- key[:key] = k
158
- key[:addr] = k.addr
159
- end
160
- if !set_address && !set_pubkey
161
- key[:key] = Bitcoin::Key.generate
162
- key[:addr] = key[:key].addr
163
- end
164
- key[:mine] = is_mine
165
- @wallet.add_key(key)
166
- update_wallet_views
167
- rescue
168
- message(:error, "Error adding key", $!.message, [:ok]) do
169
- new_addr_dialog.show
170
- end
171
- end
172
- update_addr_store
173
- end
174
- end
175
-
176
- def on_new_tx
177
- dialog(:new_tx, :setup => ->(d) {
178
- new_tx_entry_address.text = ""
179
- new_tx_entry_amount.text = ""
180
- model = Gtk::ListStore.new([GObject::TYPE_STRING, GObject::TYPE_STRING])
181
- @wallet.keystore.keys.each do |key|
182
- row = model.append
183
- model.set_value(row, 0, key[:label] || "")
184
- model.set_value(row, 1, key[:addr])
185
- end
186
- renderer = Gtk::CellRendererText.new
187
- comp = Gtk::EntryCompletion.new_with_area(area)
188
- comp.text_column = 1
189
- comp.minimum_key_length = 1
190
- comp.set_match_func(->(comp, text, iter, _) {
191
- label = comp.get_model.value(iter, 0).get_string
192
- addr = comp.get_model.value(iter, 1).get_string
193
- !!(label =~ /#{text}/ || addr =~ /#{text}/)
194
- }, nil, nil)
195
- comp.area.pack_start renderer, false, false, false
196
- comp.area.orientation = :vertical
197
- comp.set_model model
198
- renderer.set_padding 10, 0
199
- renderer.foreground = "blue"
200
- comp.set_cell_data_func(renderer, ->(layout, renderer, model, iter, data) {
201
- renderer.text = model.get_value(iter, 0).get_string
202
- }, nil, nil)
203
- new_tx_entry_address.set_completion comp
204
- # GObject.signal_connect(comp, "match-selected") do |comp, _, iter, _|
205
- # addr = comp.get_model.get_value(iter, 1).get_string
206
- # new_tx_entry_address.text = addr
207
- # true
208
- # end
209
- }) do |dialog|
210
-
211
- address = new_tx_entry_address.text
212
- amount = new_tx_entry_amount.text
213
- unless Bitcoin.valid_address?(address)
214
- message(:error, "Invalid Address",
215
- "Address #{address} is not a valid bitcoin address.", [:ok]) do
216
- new_tx_dialog.show
217
- end
218
- next
219
- end
220
- unless amount =~ /[0-9]*\.[0-9]*/
221
- message(:error, "Invalid Amount",
222
- "Amount #{amount} can not be parsed. Please use \"0.0\" form.", [:ok]) do
223
- new_tx_dialog.show
224
- end
225
- next
226
- end
227
- value = (amount.to_f * 1e8).to_i
228
- unless value <= @wallet.get_balance
229
- message(:error, "Insufficient Balance",
230
- "Balance #{@wallet.get_balance} is not sufficient to spend #{value}.", [:ok]) do
231
- dialog.show
232
- end
233
- next
234
- end
235
- message(:question, "Really send transaction?",
236
- "Do you really want to send #{format_value value} to #{address}?", [:no, :yes]) do
237
- tx = @wallet.new_tx([[:address, *[address], value]], 0.00)
238
- # puts tx.to_json
239
- if @node.request(:relay_tx, tx)
240
- puts "Transaction #{tx} relayed."
241
- end
242
- end
243
- end
244
- end
245
-
246
- def on_new_wallet
247
- dialog(:wallet_save, :filters => :wallet, :callbacks => {
248
- "update-preview" => method(:wallet_preview)}) do
249
- file = wallet_save_dialog.filename.read_string
250
- open_wallet(file) unless File.file?(file)
251
- end
252
- end
253
-
254
- def on_open_wallet
255
- dialog(:wallet_open, :filters => :wallet, :callbacks => {
256
- "update-preview" => method(:wallet_preview)}) do
257
- open_wallet(wallet_open_dialog.filename.read_string)
258
- end
259
- end
260
-
261
- def on_about
262
- dialog(:about)
263
- end
264
-
265
- def on_exit
266
- puts "bye"
267
- Gtk.main_quit
268
- EM.stop
269
- end
270
-
271
- def open_wallet(file)
272
- keystore = Bitcoin::Wallet::SimpleKeyStore.new(:file => file)
273
- @wallet = Bitcoin::Wallet::Wallet.new(@storage, keystore,
274
- Bitcoin::Wallet::SimpleCoinSelector)
275
- @wallet.on_tx do |type, tx|
276
- puts "#{type} transaction: #{tx.hash}"
277
- update_wallet_views
278
- value = tx.out.select {|out| (@wallet.addrs & out.get_addresses).any? }
279
- .map(&:value).inject(:+)
280
- title = "#{type.to_s.capitalize} transaction"
281
- message = "#{tx.hash}\nValue: #{format_value(value)}"
282
- Notify.notify title, message
283
- end
284
- update_wallet_views
285
- rescue
286
- message(:error, "Error loading wallet", $!.message, [:ok])
287
- p $!
288
- puts *$@
289
- end
290
-
291
- end
292
- end
@@ -1,115 +0,0 @@
1
- # encoding: ascii-8bit
2
-
3
- module Bitcoin::Gui::Helpers
4
-
5
- def display_tx tx_hash
6
- tx = @storage.get_tx(tx_hash)
7
- dialog(:tx, setup: ->(d) {
8
- tx_label_hash.text = tx.hash
9
- tx_label_value.text = format_value(tx.out.map(&:value).inject(:+))
10
- tx_label_confirmations.text = tx.confirmations.to_s
11
- txin_view = Bitcoin::Gui::TxInView.new(self, :tx_txin_view)
12
- # txin_view.update(tx.in)
13
- })
14
- end
15
-
16
- def wallet_preview(dialog, *args)
17
- filename = dialog.preview_filename
18
- file = filename.read_string rescue nil
19
- if file && File.file?(file)
20
- keystore = Bitcoin::Wallet::SimpleKeyStore.new(:file => file)
21
- wallet = Bitcoin::Wallet::Wallet.new(@storage, keystore,
22
- Bitcoin::Wallet::SimpleCoinSelector)
23
- preview = Gtk::Label.new "Keys: #{wallet.addrs.size}\n" +
24
- "Balance:\n%.8f" % (wallet.get_balance / 1e8)
25
- end
26
- dialog.preview_widget = preview
27
- end
28
-
29
- def add_wallet_filters dialog
30
- filter = Gtk::FileFilter.new
31
- filter.name = "Wallet Files"
32
- filter.add_pattern("*.json")
33
- dialog.add_filter filter
34
-
35
- filter = Gtk::FileFilter.new
36
- filter.name = "All Files"
37
- filter.add_pattern("*")
38
- dialog.add_filter filter
39
- end
40
-
41
- def dialog name, opts = {}
42
- @dialog_cb_ids ||= {}
43
- ids = @dialog_cb_ids[name] || []
44
- dialog = send("#{name}_dialog")
45
- send("add_#{opts[:filters]}_filters", dialog) if opts[:filters]
46
- opts[:setup].call(dialog) if opts[:setup]
47
- while id = ids.shift
48
- GObject.signal_handler_disconnect(dialog, id)
49
- end
50
- ids << GObject.signal_connect(dialog, "response") do |dialog, response, *data|
51
- yield(dialog, *data) if response > 0
52
- dialog.hide
53
- end
54
- if dialog.is_a?(Gtk::FileChooserDialog)
55
- ids << GObject.signal_connect(dialog, "file-activated") do |dialog, *data|
56
- yield(dialog, *data)
57
- dialog.hide
58
- end
59
- end
60
- (opts[:callbacks] || {}).each do |name, block|
61
- ids << GObject.signal_connect(dialog, name) {|*a| block.call(*a) }
62
- end
63
- dialog.show
64
- @dialog_cb_ids[name] = ids
65
- rescue
66
- p $!
67
- puts *$@
68
- end
69
-
70
- def message(type, title, text, buttons)
71
- dialog(:message, :setup => ->(dialog){
72
- dialog.message_type = Gtk::MessageType.find(type.to_sym)
73
- dialog.text = title
74
- dialog.secondary_text = text
75
- [:yes, :no, :ok].each do |n|
76
- b = send("message_dialog_button_#{n}")
77
- buttons.include?(n) ? b.show : b.hide
78
- end
79
- }) do |dialog|
80
- yield(dialog) if block_given?
81
- dialog.show_all
82
- dialog.hide
83
- end
84
- rescue
85
- p $!
86
- end
87
-
88
- def method_missing name, *args
89
- @builder.get_object(name.to_s) rescue super(name, *args)
90
- end
91
-
92
- def format_value val
93
- "%.8f" % (val / 1e8)
94
- end
95
-
96
- def format_address address, label = nil
97
- "#{label} (#{address})"
98
- end
99
-
100
- def format_version ver
101
- ver.insert(-3, '.') if ver.size > 2
102
- ver.insert(-6, '.') if ver.size > 5
103
- ver.insert(0, "0.") if ver.size <= 7
104
- ver
105
- end
106
-
107
- def format_uptime started
108
- uptime = Time.now.to_i - started
109
- mm, ss = uptime.divmod(60) #=> [4515, 21]
110
- hh, mm = mm.divmod(60) #=> [75, 15]
111
- dd, hh = hh.divmod(24) #=> [3, 3]
112
- "%02d:%02d:%02d:%02d" % [dd, hh, mm, ss]
113
- end
114
-
115
- end
@@ -1,84 +0,0 @@
1
- # encoding: ascii-8bit
2
-
3
- module Bitcoin::Gui
4
- class TreeView
5
-
6
- include Helpers
7
-
8
- attr_accessor :model, :view
9
-
10
- def initialize gui, view_name, columns
11
- @gui = gui
12
- @view = @gui.builder.get_object(view_name.to_s)
13
- @model = Gtk::TreeStore.new(columns.map{|c| c[0] })
14
- @view.set_model @model
15
-
16
- columns.each_with_index do |cdef, i|
17
- type, label, cb = *cdef
18
- next unless label
19
- case type
20
- when GObject::TYPE_BOOLEAN
21
- renderer = Gtk::CellRendererToggle.new
22
- col = tree_view_col(renderer, label, "active", i) do |*args|
23
- method(cb).call(@model, i, args[1], args[3]) if cb
24
- end
25
- when GObject::TYPE_STRING, GObject::TYPE_INT
26
- renderer = Gtk::CellRendererText.new
27
- col = tree_view_col(renderer, label, "text", i) do |*args|
28
- method(cb).call(@model, i, args[1], args[3]) if cb
29
- end
30
- end
31
- @view.append_column(col)
32
- end
33
- end
34
-
35
- def embed name
36
- parent = @gui.builder.get_object(name.to_s).parent
37
- parent.remove(parent.get_child)
38
- parent.add(@view)
39
- end
40
-
41
- def tree_view_col renderer, title, key, val, &block
42
- col = Gtk::TreeViewColumn.new
43
- col.pack_start renderer, true
44
- col.add_attribute renderer, key, val
45
- col.set_title title
46
- col.set_cell_data_func(renderer, block, nil, nil)
47
- col
48
- end
49
-
50
- def format_address_col model, i, renderer, iter
51
- address = model.get_value(iter, i).get_string
52
- label = model.get_value(iter, i+1).get_string
53
- renderer.text = format_address(address, label)
54
- end
55
-
56
- def format_value_col model, i, renderer, iter
57
- val = model.get_value(iter, i).get_string.to_i
58
- renderer.text = format_value(val)
59
- if val > 0
60
- renderer.foreground = "darkgreen"
61
- elsif val < 0
62
- renderer.foreground = "red"
63
- else
64
- renderer.foreground = "black"
65
- end
66
- end
67
-
68
- def format_version_col model, i, renderer, iter
69
- ver = model.get_value(iter, i).get_int.to_s
70
- renderer.text = format_version(ver)
71
- end
72
-
73
- def format_uptime_col model, i, renderer, iter
74
- started = model.get_value(iter, i).get_int
75
- renderer.text = format_uptime(started)
76
- end
77
-
78
- def format_bool_col model, i, renderer, iter
79
- active = model.get_value(iter, i).get_boolean
80
- renderer.set_active active
81
- end
82
-
83
- end
84
- end