diff options
| author | Bitflash-sh <btf01@proton.me> | 2026-07-24 11:18:11 -0300 |
|---|---|---|
| committer | Bitflash-sh <btf01@proton.me> | 2026-07-24 11:18:11 -0300 |
| commit | 51d617e70f90a972185917ea0096c1ecef2bfa8b (patch) | |
| tree | 9fbbcd867de9de9d0776afdd02f594ba312c46eb | |
Bitflash: fair-launch release
Satoshi's bitcoin-0.1.0 reborn with RandomX CPU proof of work, anonymous .btf
addressing over Nostr with CGNAT rendezvous, automatic peer discovery, a
headless Linux node, and Windows GUI wallet. Fair launch, no premine, 21M cap.
| -rw-r--r-- | .gitignore | 30 | ||||
| -rw-r--r-- | LICENSE | 22 | ||||
| -rw-r--r-- | README.md | 223 | ||||
| -rw-r--r-- | build-linux.sh | 71 | ||||
| -rw-r--r-- | build.sh | 5 | ||||
| -rw-r--r-- | docs/logo.png | bin | 0 -> 14622 bytes | |||
| -rw-r--r-- | license.txt | 19 | ||||
| -rw-r--r-- | relay/README.md | 57 | ||||
| -rw-r--r-- | relay/bitflashd.cpp | 45 | ||||
| -rw-r--r-- | relay/btfrv.cpp | 250 | ||||
| -rw-r--r-- | relay/btfrv.h | 59 | ||||
| -rw-r--r-- | relay/build.sh | 6 | ||||
| -rw-r--r-- | relay/install-bitflash-relay.sh | 326 | ||||
| -rw-r--r-- | src/base58.h | 204 | ||||
| -rw-r--r-- | src/bignum.h | 525 | ||||
| -rw-r--r-- | src/bitflashd.cpp | 45 | ||||
| -rw-r--r-- | src/btfaddr.cpp | 248 | ||||
| -rw-r--r-- | src/btfaddr.h | 72 | ||||
| -rw-r--r-- | src/btfchan.cpp | 94 | ||||
| -rw-r--r-- | src/btfchan.h | 59 | ||||
| -rw-r--r-- | src/btfrv.cpp | 250 | ||||
| -rw-r--r-- | src/btfrv.h | 59 | ||||
| -rw-r--r-- | src/btftunnel.cpp | 161 | ||||
| -rw-r--r-- | src/btftunnel.h | 49 | ||||
| -rw-r--r-- | src/compat.h | 193 | ||||
| -rw-r--r-- | src/db.cpp | 604 | ||||
| -rw-r--r-- | src/db.h | 420 | ||||
| -rw-r--r-- | src/headers.h | 111 | ||||
| -rw-r--r-- | src/headless.cpp | 177 | ||||
| -rw-r--r-- | src/irc.cpp | 271 | ||||
| -rw-r--r-- | src/irc.h | 7 | ||||
| -rw-r--r-- | src/key.h | 156 | ||||
| -rw-r--r-- | src/license.txt | 19 | ||||
| -rw-r--r-- | src/main.cpp | 2696 | ||||
| -rw-r--r-- | src/main.h | 1361 | ||||
| -rw-r--r-- | src/makefile | 83 | ||||
| -rw-r--r-- | src/makefile.linux | 48 | ||||
| -rw-r--r-- | src/makefile.mingw | 44 | ||||
| -rw-r--r-- | src/makefile.vc | 77 | ||||
| -rw-r--r-- | src/market.cpp | 264 | ||||
| -rw-r--r-- | src/market.h | 182 | ||||
| -rw-r--r-- | src/net.cpp | 1207 | ||||
| -rw-r--r-- | src/net.h | 863 | ||||
| -rw-r--r-- | src/nostr.cpp | 838 | ||||
| -rw-r--r-- | src/nostr.h | 39 | ||||
| -rw-r--r-- | src/randomx_pow.cpp | 143 | ||||
| -rw-r--r-- | src/randomx_pow.h | 44 | ||||
| -rw-r--r-- | src/rc/addressbook16.bmp | bin | 0 -> 1334 bytes | |||
| -rw-r--r-- | src/rc/addressbook16mask.bmp | bin | 0 -> 126 bytes | |||
| -rw-r--r-- | src/rc/addressbook20.bmp | bin | 0 -> 1478 bytes | |||
| -rw-r--r-- | src/rc/addressbook20mask.bmp | bin | 0 -> 142 bytes | |||
| -rw-r--r-- | src/rc/bitcoin.ico | bin | 0 -> 372526 bytes | |||
| -rw-r--r-- | src/rc/bitcoin_bc_original.ico | bin | 0 -> 22486 bytes | |||
| -rw-r--r-- | src/rc/check.ico | bin | 0 -> 766 bytes | |||
| -rw-r--r-- | src/rc/send16.bmp | bin | 0 -> 1334 bytes | |||
| -rw-r--r-- | src/rc/send16mask.bmp | bin | 0 -> 126 bytes | |||
| -rw-r--r-- | src/rc/send16masknoshadow.bmp | bin | 0 -> 126 bytes | |||
| -rw-r--r-- | src/rc/send20.bmp | bin | 0 -> 1478 bytes | |||
| -rw-r--r-- | src/rc/send20mask.bmp | bin | 0 -> 142 bytes | |||
| -rw-r--r-- | src/readme.txt | 54 | ||||
| -rw-r--r-- | src/script.cpp | 1127 | ||||
| -rw-r--r-- | src/script.h | 597 | ||||
| -rw-r--r-- | src/serialize.h | 1151 | ||||
| -rw-r--r-- | src/sha.cpp | 554 | ||||
| -rw-r--r-- | src/sha.h | 177 | ||||
| -rw-r--r-- | src/test_btfaddr.cpp | 142 | ||||
| -rw-r--r-- | src/test_btfchan.cpp | 83 | ||||
| -rw-r--r-- | src/test_btfrv.cpp | 116 | ||||
| -rw-r--r-- | src/test_btftunnel.cpp | 97 | ||||
| -rw-r--r-- | src/test_relayproc.cpp | 68 | ||||
| -rw-r--r-- | src/ui.cpp | 3265 | ||||
| -rw-r--r-- | src/ui.h | 417 | ||||
| -rw-r--r-- | src/ui.rc | 14 | ||||
| -rw-r--r-- | src/uibase.cpp | 1808 | ||||
| -rw-r--r-- | src/uibase.h | 720 | ||||
| -rw-r--r-- | src/uint256.h | 750 | ||||
| -rw-r--r-- | src/uiproject.fbp | 11825 | ||||
| -rw-r--r-- | src/util.cpp | 393 | ||||
| -rw-r--r-- | src/util.h | 413 |
79 files changed, 36497 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..29ebcff --- /dev/null +++ b/.gitignore | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | # Build output | ||
| 2 | src/obj/ | ||
| 3 | *.o | ||
| 4 | *.exe | ||
| 5 | *.a | ||
| 6 | bitflash-node | ||
| 7 | src/bitflash-node | ||
| 8 | |||
| 9 | # Runtime data / logs | ||
| 10 | debug.log | ||
| 11 | db.log | ||
| 12 | *.dat | ||
| 13 | wallet.dat | ||
| 14 | nostr.key | ||
| 15 | btf_enc.key | ||
| 16 | |||
| 17 | # Third-party build trees (rebuilt by the build scripts) | ||
| 18 | RandomX/ | ||
| 19 | deps/ | ||
| 20 | secp256k1/ | ||
| 21 | secp256k1-build/ | ||
| 22 | |||
| 23 | # Distributable binaries (published as GitHub Releases, not committed) | ||
| 24 | dist/ | ||
| 25 | *.tar.gz | ||
| 26 | *.zip | ||
| 27 | |||
| 28 | # Editor/OS cruft | ||
| 29 | .DS_Store | ||
| 30 | Thumbs.db | ||
| @@ -0,0 +1,22 @@ | |||
| 1 | MIT License | ||
| 2 | |||
| 3 | Copyright (c) 2009 Satoshi Nakamoto (original Bitcoin) | ||
| 4 | Copyright (c) 2026 The Bitflash developers | ||
| 5 | |||
| 6 | Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| 7 | of this software and associated documentation files (the "Software"), to deal | ||
| 8 | in the Software without restriction, including without limitation the rights | ||
| 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| 10 | copies of the Software, and to permit persons to whom the Software is | ||
| 11 | furnished to do so, subject to the following conditions: | ||
| 12 | |||
| 13 | The above copyright notice and this permission notice shall be included in | ||
| 14 | all copies or substantial portions of the Software. | ||
| 15 | |||
| 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
| 22 | THE SOFTWARE. | ||
diff --git a/README.md b/README.md new file mode 100644 index 0000000..550657a --- /dev/null +++ b/README.md | |||
| @@ -0,0 +1,223 @@ | |||
| 1 | <div align="center"> | ||
| 2 | |||
| 3 | <img src="docs/logo.png" width="128" alt="Bitflash"/> | ||
| 4 | |||
| 5 | # Bitflash ⚡ `BTF` | ||
| 6 | |||
| 7 | ### Satoshi's Bitcoin, reborn — mine with your **CPU**, stay **invisible**, run **anywhere**. | ||
| 8 | |||
| 9 | A faithful revival of the original 2009 `bitcoin-0.1.0`, rebuilt for today: | ||
| 10 | **memory-hard CPU mining** that shuts out ASICs and GPUs, **anonymous addressing** | ||
| 11 | that hides your IP and punches through CGNAT, and a **fair launch** with no premine. | ||
| 12 | |||
| 13 | <br/> | ||
| 14 | |||
| 15 | -2ea44f?style=for-the-badge) | ||
| 16 |  | ||
| 17 |  | ||
| 18 | |||
| 19 |  | ||
| 20 |  | ||
| 21 |  | ||
| 22 |  | ||
| 23 |  | ||
| 24 | |||
| 25 | **[⬇️ Download for Windows](../../releases/latest)** · **[🐧 Build for Linux](#-linux-node--miner)** · **[🧠 How it works](#-how-it-works)** | ||
| 26 | |||
| 27 | </div> | ||
| 28 | |||
| 29 | --- | ||
| 30 | |||
| 31 | ## 💡 One CPU, one vote | ||
| 32 | |||
| 33 | Bitcoin promised money mined by anyone with a computer. Then ASIC farms and mining | ||
| 34 | pools took over, and "anyone" became "whoever owns a warehouse." Bitflash gives that | ||
| 35 | promise back. | ||
| 36 | |||
| 37 | - 🧩 **Memory-hard proof of work (RandomX).** The same algorithm Monero uses to keep | ||
| 38 | mining on ordinary CPUs. No ASICs. No GPU farms. Your laptop competes on equal footing. | ||
| 39 | - 🕶️ **Anonymous by default.** Your node is reachable by a self-certifying `.btf` | ||
| 40 | address instead of an IP — a Tor-style hidden service built into the coin, over | ||
| 41 | [Nostr](https://nostr.com). Peers never see your IP. | ||
| 42 | - 🌐 **Works behind any firewall.** No public IP? Stuck behind CGNAT? No port | ||
| 43 | forwarding? Doesn't matter. Nodes rendezvous through a lightweight relay and connect | ||
| 44 | anyway. | ||
| 45 | - ⚖️ **Fair launch.** No premine. No ICO. No founder's reward. The genesis block mints | ||
| 46 | the same 50 coins everyone else mines for. | ||
| 47 | - 🪙 **Sound money.** 50 BTF per block, halving on schedule, hard cap of **21,000,000** — | ||
| 48 | exactly like the original. | ||
| 49 | |||
| 50 | --- | ||
| 51 | |||
| 52 | ## ✨ Features | ||
| 53 | |||
| 54 | | | | | ||
| 55 | |---|---| | ||
| 56 | | 🧠 **RandomX PoW** | CPU-only, ASIC/GPU-resistant mining — one CPU, one vote | | ||
| 57 | | 🔐 **`.btf` hidden addresses** | Self-certifying, unforgeable node identity; your IP is never exposed | | ||
| 58 | | 🛰️ **Nostr peer discovery** | No central servers, no DNS seeds — nodes find each other over open relays | | ||
| 59 | | 🚪 **CGNAT traversal** | Rendezvous transport lets nodes behind carrier NAT reach each other | | ||
| 60 | | 🔒 **End-to-end encrypted P2P** | X25519 + XChaCha20-Poly1305 channel; the relay only ever sees ciphertext | | ||
| 61 | | 💸 **Instant transfers** | Send coins peer-to-peer in under a second | | ||
| 62 | | 🖥️ **Retro wallet** | The classic, no-nonsense Bitcoin 0.1.0 interface, one "Generate Coins" click away | | ||
| 63 | | 🐧 **Windows & Linux** | GUI wallet on Windows, headless daemon for Linux servers | | ||
| 64 | |||
| 65 | --- | ||
| 66 | |||
| 67 | ## 🚀 Quick start | ||
| 68 | |||
| 69 | ### 🪟 Windows (GUI wallet + miner) | ||
| 70 | |||
| 71 | 1. **[Download the latest release](../../releases/latest)** and unzip it anywhere. | ||
| 72 | 2. Double-click **`bitflash.exe`**. | ||
| 73 | 3. Wait ~1 minute — it finds peers on its own and starts syncing. | ||
| 74 | 4. **Options → Generate Coins** to start mining with your CPU. That's it. 🎉 | ||
| 75 | |||
| 76 | No install, no config, no command line. It connects automatically, even behind CGNAT. | ||
| 77 | |||
| 78 | ### 🐧 Linux (node + miner) | ||
| 79 | |||
| 80 | ```bash | ||
| 81 | # grab the source, then: | ||
| 82 | bash build-linux.sh # installs deps, builds secp256k1 + RandomX + the node | ||
| 83 | ./src/bitflash-node -gen # run + mine (auto-discovers peers, no config needed) | ||
| 84 | ``` | ||
| 85 | |||
| 86 | Run it 24/7 as a service — see [`docs/`](docs) and the systemd snippet below. | ||
| 87 | |||
| 88 | --- | ||
| 89 | |||
| 90 | ## 🧠 How it works | ||
| 91 | |||
| 92 | Bitflash keeps Satoshi's consensus intact and swaps two things: **the proof of work** | ||
| 93 | and **how nodes find and reach each other**. | ||
| 94 | |||
| 95 | ### Anonymous rendezvous (the `.btf` network) | ||
| 96 | |||
| 97 | Every node has a `.btf` address derived from its public key — like a Tor `.onion`, but | ||
| 98 | built into the coin. Nodes publish a signed descriptor over Nostr, and connect through a | ||
| 99 | meeting relay so **neither side ever learns the other's IP**, and **no port forwarding is | ||
| 100 | ever needed**. | ||
| 101 | |||
| 102 | ```mermaid | ||
| 103 | flowchart LR | ||
| 104 | A["🧑💻 Node A<br/>(behind CGNAT)"] -- "encrypted" --> R(("🛰️ Meeting<br/>relay")) | ||
| 105 | B["🧑💻 Node B<br/>(behind CGNAT)"] -- "encrypted" --> R | ||
| 106 | R -. "pairs by .btf key<br/>sees only ciphertext" .-> A | ||
| 107 | R -. "pairs by .btf key<br/>sees only ciphertext" .-> B | ||
| 108 | N["🛰️ Nostr relays"] -. "discover .btf peers" .-> A | ||
| 109 | N -. "discover .btf peers" .-> B | ||
| 110 | ``` | ||
| 111 | |||
| 112 | The relay is dumb on purpose: it pairs peers by their `.btf` key and forwards bytes. The | ||
| 113 | real connection is end-to-end encrypted (X25519 + XChaCha20-Poly1305) and authenticated | ||
| 114 | to each peer's static key, so a malicious relay can't read or tamper — it can only refuse. | ||
| 115 | |||
| 116 | ### RandomX proof of work | ||
| 117 | |||
| 118 | Blocks are mined with **RandomX**, a memory-hard algorithm that runs efficiently on | ||
| 119 | general-purpose CPUs and terribly on specialized hardware. This is what keeps mining | ||
| 120 | decentralized: no ASIC advantage, no GPU farms — just CPUs, one vote each. | ||
| 121 | |||
| 122 | --- | ||
| 123 | |||
| 124 | ## 🛠️ Build from source | ||
| 125 | |||
| 126 | ### Linux | ||
| 127 | |||
| 128 | ```bash | ||
| 129 | bash build-linux.sh | ||
| 130 | ``` | ||
| 131 | |||
| 132 | Installs `build-essential cmake libssl-dev libdb5.3++-dev libsodium-dev | ||
| 133 | nlohmann-json3-dev libboost-dev`, builds `libsecp256k1` (Schnorr) and `RandomX` from | ||
| 134 | source, then the `bitflash-node` binary. Debian/Ubuntu. | ||
| 135 | |||
| 136 | ### Windows | ||
| 137 | |||
| 138 | Built with **MSYS2 UCRT64** (g++ 16, wxWidgets 3.2, OpenSSL 3, Berkeley DB). See | ||
| 139 | [`build.sh`](build.sh) and `src/makefile.mingw`. | ||
| 140 | |||
| 141 | ### Run a rendezvous relay (optional, help the network) | ||
| 142 | |||
| 143 | Have a box with a public IP? Run a relay in one command and strengthen the network: | ||
| 144 | |||
| 145 | ```bash | ||
| 146 | sudo bash relay/install-bitflash-relay.sh 8434 | ||
| 147 | ``` | ||
| 148 | |||
| 149 | It builds a tiny, dependency-free daemon and installs it as a systemd service. | ||
| 150 | |||
| 151 | <details> | ||
| 152 | <summary>Run the Linux node 24/7 (systemd)</summary> | ||
| 153 | |||
| 154 | ```ini | ||
| 155 | # /etc/systemd/system/bitflash-node.service | ||
| 156 | [Unit] | ||
| 157 | Description=Bitflash node/miner | ||
| 158 | After=network.target | ||
| 159 | |||
| 160 | [Service] | ||
| 161 | WorkingDirectory=/root/bitflash/src | ||
| 162 | ExecStart=/root/bitflash/src/bitflash-node -gen | ||
| 163 | Restart=always | ||
| 164 | User=root | ||
| 165 | |||
| 166 | [Install] | ||
| 167 | WantedBy=multi-user.target | ||
| 168 | ``` | ||
| 169 | ```bash | ||
| 170 | systemctl daemon-reload && systemctl enable --now bitflash-node | ||
| 171 | ``` | ||
| 172 | </details> | ||
| 173 | |||
| 174 | --- | ||
| 175 | |||
| 176 | ## 📊 At a glance | ||
| 177 | |||
| 178 | | Parameter | Value | | ||
| 179 | |---|---| | ||
| 180 | | Ticker | **BTF** | | ||
| 181 | | Proof of work | RandomX (CPU, memory-hard) | | ||
| 182 | | Block reward | 50 BTF, halving on schedule | | ||
| 183 | | Max supply | 21,000,000 BTF | | ||
| 184 | | Target block time | ~2 minutes | | ||
| 185 | | Address privacy | `.btf` hidden-service addressing over Nostr | | ||
| 186 | | Premine / ICO | **None** | | ||
| 187 | | Platforms | Windows (GUI), Linux (headless) | | ||
| 188 | |||
| 189 | --- | ||
| 190 | |||
| 191 | ## 🗺️ Roadmap | ||
| 192 | |||
| 193 | - [x] Faithful port of `bitcoin-0.1.0` to a modern toolchain | ||
| 194 | - [x] RandomX CPU proof of work | ||
| 195 | - [x] Nostr peer discovery (replacing IRC) | ||
| 196 | - [x] `.btf` anonymous addressing + CGNAT rendezvous | ||
| 197 | - [x] Automatic peer discovery — zero config | ||
| 198 | - [x] Headless Linux node/miner | ||
| 199 | - [x] Fair-launch, stable-parameter relaunch | ||
| 200 | - [ ] Optional direct IPv6 transport (opt-in, for public backbone nodes) | ||
| 201 | - [ ] Redundant relays & bootstrap hardening | ||
| 202 | - [ ] One-click installers | ||
| 203 | |||
| 204 | --- | ||
| 205 | |||
| 206 | ## ⚠️ Disclaimer | ||
| 207 | |||
| 208 | Bitflash is **experimental software**, released in the spirit of the original Bitcoin: | ||
| 209 | *"This is a design and prototype. Use at your own risk. It comes with no warranty of any | ||
| 210 | kind."* It has real cryptography and a live network, but it is young. Don't put in more | ||
| 211 | than you're willing to lose, and don't rely on it for anything critical. | ||
| 212 | |||
| 213 | --- | ||
| 214 | |||
| 215 | ## 📜 License | ||
| 216 | |||
| 217 | MIT — see [LICENSE](LICENSE). Built on Satoshi Nakamoto's original Bitcoin (2009), | ||
| 218 | extended by the Bitflash developers (2026). | ||
| 219 | |||
| 220 | <div align="center"> | ||
| 221 | <br/> | ||
| 222 | <b>⚡ One CPU. One vote. Mining returns to the people. ⚡</b> | ||
| 223 | </div> | ||
diff --git a/build-linux.sh b/build-linux.sh new file mode 100644 index 0000000..bb11e82 --- /dev/null +++ b/build-linux.sh | |||
| @@ -0,0 +1,71 @@ | |||
| 1 | #!/usr/bin/env bash | ||
| 2 | # Bitflash headless node/miner -- one-shot Linux build (Debian/Ubuntu). | ||
| 3 | # Builds the dependencies (libsecp256k1 with schnorrsig, RandomX) and then the | ||
| 4 | # node itself. Run from the project root (the directory that contains src/): | ||
| 5 | # | ||
| 6 | # bash build-linux.sh | ||
| 7 | # | ||
| 8 | # Result: src/bitflash-node . Run it with: ./src/bitflash-node -gen | ||
| 9 | |||
| 10 | set -e | ||
| 11 | ROOT="$(cd "$(dirname "$0")" && pwd)" | ||
| 12 | cd "$ROOT" | ||
| 13 | |||
| 14 | # Use sudo only when not already root (a root login often has no sudo installed). | ||
| 15 | SUDO="" | ||
| 16 | if [ "$(id -u)" -ne 0 ]; then SUDO="sudo"; fi | ||
| 17 | |||
| 18 | echo "==> installing system packages" | ||
| 19 | if command -v apt-get >/dev/null 2>&1; then | ||
| 20 | $SUDO apt-get update | ||
| 21 | $SUDO apt-get install -y build-essential cmake git pkg-config autoconf libtool \ | ||
| 22 | libssl-dev libdb5.3++-dev libsodium-dev nlohmann-json3-dev libboost-dev | ||
| 23 | else | ||
| 24 | echo "!! non-apt system: install manually -> g++ cmake git autoconf libtool" | ||
| 25 | echo " libssl-dev libdb++-dev libsodium-dev nlohmann-json (headers)" | ||
| 26 | fi | ||
| 27 | |||
| 28 | # ---- libsecp256k1 (Schnorr/BIP340 + extrakeys), static, installed to /usr/local | ||
| 29 | if [ ! -f /usr/local/lib/libsecp256k1.a ]; then | ||
| 30 | echo "==> building libsecp256k1" | ||
| 31 | rm -rf "$ROOT/secp256k1-build" | ||
| 32 | git clone --depth 1 https://github.com/bitcoin-core/secp256k1 "$ROOT/secp256k1-build" | ||
| 33 | cd "$ROOT/secp256k1-build" | ||
| 34 | ./autogen.sh | ||
| 35 | ./configure --enable-module-schnorrsig --enable-module-extrakeys \ | ||
| 36 | --disable-shared --with-pic --disable-benchmark --disable-tests | ||
| 37 | make -j"$(nproc)" | ||
| 38 | $SUDO make install | ||
| 39 | $SUDO ldconfig | ||
| 40 | cd "$ROOT" | ||
| 41 | else | ||
| 42 | echo "==> libsecp256k1 already installed, skipping" | ||
| 43 | fi | ||
| 44 | |||
| 45 | # ---- RandomX (memory-hard CPU PoW), static lib | ||
| 46 | if [ ! -f "$HOME/RandomX/build/librandomx.a" ]; then | ||
| 47 | echo "==> building RandomX" | ||
| 48 | rm -rf "$HOME/RandomX" | ||
| 49 | git clone --depth 1 https://github.com/tevador/RandomX "$HOME/RandomX" | ||
| 50 | mkdir -p "$HOME/RandomX/build" | ||
| 51 | cd "$HOME/RandomX/build" | ||
| 52 | cmake .. -DCMAKE_BUILD_TYPE=Release | ||
| 53 | make -j"$(nproc)" randomx | ||
| 54 | cd "$ROOT" | ||
| 55 | else | ||
| 56 | echo "==> RandomX already built, skipping" | ||
| 57 | fi | ||
| 58 | |||
| 59 | # ---- the node | ||
| 60 | echo "==> building bitflash-node" | ||
| 61 | cd "$ROOT/src" | ||
| 62 | make -f makefile.linux RANDOMX_DIR="$HOME/RandomX" -j"$(nproc)" | ||
| 63 | |||
| 64 | echo | ||
| 65 | echo "===================================================================" | ||
| 66 | echo " DONE. Binary: $ROOT/src/bitflash-node" | ||
| 67 | echo | ||
| 68 | echo " Mine: ./src/bitflash-node -gen" | ||
| 69 | echo " Custom data dir: ./src/bitflash-node -gen -datadir=\$HOME/.bitflash" | ||
| 70 | echo " Run as a service: see linux-node.service note in the README" | ||
| 71 | echo "===================================================================" | ||
diff --git a/build.sh b/build.sh new file mode 100644 index 0000000..119938b --- /dev/null +++ b/build.sh | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | #!/usr/bin/env bash | ||
| 2 | # Build Bitflash on MSYS2 UCRT64. Usage: bash build.sh [target] | ||
| 3 | cd /c/Users/ti/Bitflash/src || exit 1 | ||
| 4 | mkdir -p obj | ||
| 5 | exec mingw32-make -f makefile.mingw "${@:-all}" | ||
diff --git a/docs/logo.png b/docs/logo.png new file mode 100644 index 0000000..0f5d0f5 --- /dev/null +++ b/docs/logo.png | |||
| Binary files differ | |||
diff --git a/license.txt b/license.txt new file mode 100644 index 0000000..a456302 --- /dev/null +++ b/license.txt | |||
| @@ -0,0 +1,19 @@ | |||
| 1 | Copyright (c) 2009 Satoshi Nakamoto | ||
| 2 | |||
| 3 | Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| 4 | of this software and associated documentation files (the "Software"), to deal | ||
| 5 | in the Software without restriction, including without limitation the rights | ||
| 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| 7 | copies of the Software, and to permit persons to whom the Software is | ||
| 8 | furnished to do so, subject to the following conditions: | ||
| 9 | |||
| 10 | The above copyright notice and this permission notice shall be included in | ||
| 11 | all copies or substantial portions of the Software. | ||
| 12 | |||
| 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
| 19 | THE SOFTWARE. | ||
diff --git a/relay/README.md b/relay/README.md new file mode 100644 index 0000000..abf0f8d --- /dev/null +++ b/relay/README.md | |||
| @@ -0,0 +1,57 @@ | |||
| 1 | # bitflashd — Bitflash rendezvous relay (the "meeting node") | ||
| 2 | |||
| 3 | This is the small always-on server that lets Bitflash nodes behind CGNAT reach | ||
| 4 | each other. Both sides connect **out** to this relay; it pairs them by their | ||
| 5 | `.btf` pubkey and forwards ciphertext. It holds **no keys** and reads nothing — | ||
| 6 | the two nodes are encrypted end-to-end (X25519 + ChaCha20-Poly1305) over it. | ||
| 7 | |||
| 8 | Run it on any machine with a public IP (a cheap VPS). It has **no dependencies** | ||
| 9 | beyond a C++ compiler. | ||
| 10 | |||
| 11 | ## Build (on the VPS, Linux) | ||
| 12 | |||
| 13 | ``` | ||
| 14 | sudo apt-get update && sudo apt-get install -y g++ # if needed | ||
| 15 | bash build.sh | ||
| 16 | ``` | ||
| 17 | |||
| 18 | ## Run | ||
| 19 | |||
| 20 | ``` | ||
| 21 | ./bitflashd 8434 | ||
| 22 | ``` | ||
| 23 | |||
| 24 | Open the port in the firewall (both the VPS provider's panel and the OS): | ||
| 25 | |||
| 26 | ``` | ||
| 27 | sudo ufw allow 8434/tcp # if ufw is enabled | ||
| 28 | ``` | ||
| 29 | |||
| 30 | ## Keep it running (systemd) | ||
| 31 | |||
| 32 | Create `/etc/systemd/system/bitflashd.service`: | ||
| 33 | |||
| 34 | ``` | ||
| 35 | [Unit] | ||
| 36 | Description=Bitflash rendezvous relay | ||
| 37 | After=network.target | ||
| 38 | |||
| 39 | [Service] | ||
| 40 | ExecStart=/root/bitflash/relay/bitflashd 8434 | ||
| 41 | Restart=always | ||
| 42 | User=root | ||
| 43 | |||
| 44 | [Install] | ||
| 45 | WantedBy=multi-user.target | ||
| 46 | ``` | ||
| 47 | |||
| 48 | Then: | ||
| 49 | |||
| 50 | ``` | ||
| 51 | sudo systemctl daemon-reload | ||
| 52 | sudo systemctl enable --now bitflashd | ||
| 53 | sudo systemctl status bitflashd | ||
| 54 | ``` | ||
| 55 | |||
| 56 | The relay's address for clients is then `YOUR_VPS_IP:8434` — that is what goes | ||
| 57 | into a node's descriptor as its `meeting_node`. | ||
diff --git a/relay/bitflashd.cpp b/relay/bitflashd.cpp new file mode 100644 index 0000000..d4ced77 --- /dev/null +++ b/relay/bitflashd.cpp | |||
| @@ -0,0 +1,45 @@ | |||
| 1 | // Copyright (c) 2026 Bitflash developers | ||
| 2 | // Distributed under the MIT/X11 software license. | ||
| 3 | // | ||
| 4 | // bitflashd -- the headless Bitflash rendezvous relay (the "meeting node"). | ||
| 5 | // Runs on a machine with a public IP (a cheap VPS) and lets nodes behind CGNAT | ||
| 6 | // reach each other: both sides connect OUT to this relay, which pairs them by | ||
| 7 | // `.btf` pubkey and forwards ciphertext (it holds no keys and reads nothing). | ||
| 8 | // | ||
| 9 | // Build on the VPS (Linux): | ||
| 10 | // g++ -std=gnu++14 -O2 -pthread bitflashd.cpp btfrv.cpp -o bitflashd | ||
| 11 | // Run: | ||
| 12 | // ./bitflashd 8434 # or any port you open in the firewall | ||
| 13 | // | ||
| 14 | // Cross-builds unchanged on Windows (for local testing): | ||
| 15 | // g++ -std=gnu++14 -O2 -pthread bitflashd.cpp btfrv.cpp -lws2_32 -o bitflashd.exe | ||
| 16 | |||
| 17 | #include "btfrv.h" | ||
| 18 | #include <cstdio> | ||
| 19 | #include <cstdlib> | ||
| 20 | #include <cstring> | ||
| 21 | |||
| 22 | int main(int argc, char* argv[]) | ||
| 23 | { | ||
| 24 | unsigned short port = 8434; | ||
| 25 | if (argc >= 2) | ||
| 26 | port = (unsigned short)atoi(argv[1]); | ||
| 27 | |||
| 28 | printf("bitflashd -- Bitflash rendezvous relay\n"); | ||
| 29 | printf("listening on 0.0.0.0:%u (open this port in your firewall)\n", port); | ||
| 30 | fflush(stdout); | ||
| 31 | |||
| 32 | if (!btf::RvInit()) | ||
| 33 | { | ||
| 34 | fprintf(stderr, "bitflashd: socket init failed\n"); | ||
| 35 | return 1; | ||
| 36 | } | ||
| 37 | |||
| 38 | // Blocks forever, forwarding between paired peers. | ||
| 39 | if (!btf::RvRelayRun(port)) | ||
| 40 | { | ||
| 41 | fprintf(stderr, "bitflashd: could not bind/listen on port %u\n", port); | ||
| 42 | return 1; | ||
| 43 | } | ||
| 44 | return 0; | ||
| 45 | } | ||
diff --git a/relay/btfrv.cpp b/relay/btfrv.cpp new file mode 100644 index 0000000..ffda08c --- /dev/null +++ b/relay/btfrv.cpp | |||
| @@ -0,0 +1,250 @@ | |||
| 1 | // Copyright (c) 2026 Bitflash developers | ||
| 2 | // Distributed under the MIT/X11 software license. | ||
| 3 | // | ||
| 4 | // Bitflash rendezvous transport. See btfrv.h. | ||
| 5 | // Windows/Winsock implementation (Layer 6 will #ifdef this for Linux/BSD sockets). | ||
| 6 | |||
| 7 | #include "btfrv.h" | ||
| 8 | |||
| 9 | // Portable sockets: Winsock on Windows, BSD sockets on Linux/POSIX (for the | ||
| 10 | // headless relay `bitflashd` that runs on the VPS). | ||
| 11 | #ifdef _WIN32 | ||
| 12 | #include <winsock2.h> | ||
| 13 | #include <ws2tcpip.h> | ||
| 14 | #define CLOSESOCK closesocket | ||
| 15 | #else | ||
| 16 | #include <sys/socket.h> | ||
| 17 | #include <netinet/in.h> | ||
| 18 | #include <arpa/inet.h> | ||
| 19 | #include <netdb.h> | ||
| 20 | #include <unistd.h> | ||
| 21 | #include <csignal> | ||
| 22 | typedef int SOCKET; | ||
| 23 | #define INVALID_SOCKET (-1) | ||
| 24 | #define SOCKET_ERROR (-1) | ||
| 25 | #define CLOSESOCK ::close | ||
| 26 | #ifndef SD_BOTH | ||
| 27 | #define SD_BOTH SHUT_RDWR | ||
| 28 | #endif | ||
| 29 | #endif | ||
| 30 | |||
| 31 | #include <cstring> | ||
| 32 | #include <cstdio> | ||
| 33 | #include <string> | ||
| 34 | #include <map> | ||
| 35 | #include <thread> | ||
| 36 | #include <mutex> | ||
| 37 | #include <atomic> | ||
| 38 | |||
| 39 | namespace btf | ||
| 40 | { | ||
| 41 | |||
| 42 | static std::atomic<bool> g_stop(false); | ||
| 43 | static SOCKET g_listen = INVALID_SOCKET; | ||
| 44 | |||
| 45 | // Services that have registered and are waiting for a client, keyed by pubkey. | ||
| 46 | static std::map<std::string, SOCKET> g_waiting; | ||
| 47 | static std::mutex g_mtx; | ||
| 48 | |||
| 49 | bool RvInit() | ||
| 50 | { | ||
| 51 | static bool done = false; | ||
| 52 | if (done) return true; | ||
| 53 | #ifdef _WIN32 | ||
| 54 | WSADATA wsa; | ||
| 55 | if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) return false; | ||
| 56 | #else | ||
| 57 | signal(SIGPIPE, SIG_IGN); // don't die when writing to a closed peer | ||
| 58 | #endif | ||
| 59 | done = true; | ||
| 60 | return true; | ||
| 61 | } | ||
| 62 | |||
| 63 | // ---- low-level helpers ---- | ||
| 64 | |||
| 65 | static bool ReadN(SOCKET s, void* buf, int n) | ||
| 66 | { | ||
| 67 | char* p = (char*)buf; | ||
| 68 | int off = 0; | ||
| 69 | while (off < n) | ||
| 70 | { | ||
| 71 | int r = recv(s, p + off, n - off, 0); | ||
| 72 | if (r <= 0) return false; | ||
| 73 | off += r; | ||
| 74 | } | ||
| 75 | return true; | ||
| 76 | } | ||
| 77 | |||
| 78 | static bool WriteN(SOCKET s, const void* buf, int n) | ||
| 79 | { | ||
| 80 | const char* p = (const char*)buf; | ||
| 81 | int off = 0; | ||
| 82 | while (off < n) | ||
| 83 | { | ||
| 84 | int r = send(s, p + off, n - off, 0); | ||
| 85 | if (r <= 0) return false; | ||
| 86 | off += r; | ||
| 87 | } | ||
| 88 | return true; | ||
| 89 | } | ||
| 90 | |||
| 91 | static SOCKET ConnectTo(const char* host, unsigned short port) | ||
| 92 | { | ||
| 93 | struct addrinfo hints, *res = NULL; | ||
| 94 | memset(&hints, 0, sizeof(hints)); | ||
| 95 | hints.ai_family = AF_INET; | ||
| 96 | hints.ai_socktype = SOCK_STREAM; | ||
| 97 | char portstr[16]; sprintf(portstr, "%u", (unsigned)port); | ||
| 98 | if (getaddrinfo(host, portstr, &hints, &res) != 0 || !res) return INVALID_SOCKET; | ||
| 99 | SOCKET s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); | ||
| 100 | if (s == INVALID_SOCKET) { freeaddrinfo(res); return INVALID_SOCKET; } | ||
| 101 | if (connect(s, res->ai_addr, (int)res->ai_addrlen) != 0) | ||
| 102 | { | ||
| 103 | CLOSESOCK(s); freeaddrinfo(res); return INVALID_SOCKET; | ||
| 104 | } | ||
| 105 | freeaddrinfo(res); | ||
| 106 | return s; | ||
| 107 | } | ||
| 108 | |||
| 109 | // ---- relay side ---- | ||
| 110 | |||
| 111 | // Pump bytes from `from` to `to`. Owns closing `from`; shuts down `to` on exit | ||
| 112 | // so the peer-direction thread unblocks and closes its own socket exactly once. | ||
| 113 | static void Forward(SOCKET from, SOCKET to) | ||
| 114 | { | ||
| 115 | char buf[32 * 1024]; | ||
| 116 | for (;;) | ||
| 117 | { | ||
| 118 | int r = recv(from, buf, sizeof(buf), 0); | ||
| 119 | if (r <= 0) break; | ||
| 120 | if (!WriteN(to, buf, r)) break; | ||
| 121 | } | ||
| 122 | shutdown(to, SD_BOTH); | ||
| 123 | CLOSESOCK(from); | ||
| 124 | } | ||
| 125 | |||
| 126 | static void HandleIncoming(SOCKET s) | ||
| 127 | { | ||
| 128 | unsigned char hdr[33]; | ||
| 129 | if (!ReadN(s, hdr, 33)) { CLOSESOCK(s); return; } | ||
| 130 | char role = (char)hdr[0]; | ||
| 131 | std::string pubkey((char*)hdr + 1, 32); | ||
| 132 | |||
| 133 | if (role == 'S') | ||
| 134 | { | ||
| 135 | // Register and wait; a future client will pair us. | ||
| 136 | std::lock_guard<std::mutex> lk(g_mtx); | ||
| 137 | // If a stale service for this key exists, drop it. | ||
| 138 | std::map<std::string, SOCKET>::iterator it = g_waiting.find(pubkey); | ||
| 139 | if (it != g_waiting.end()) CLOSESOCK(it->second); | ||
| 140 | g_waiting[pubkey] = s; | ||
| 141 | // leave the socket open in the map; do not close here. | ||
| 142 | } | ||
| 143 | else if (role == 'C') | ||
| 144 | { | ||
| 145 | SOCKET svc = INVALID_SOCKET; | ||
| 146 | { | ||
| 147 | std::lock_guard<std::mutex> lk(g_mtx); | ||
| 148 | std::map<std::string, SOCKET>::iterator it = g_waiting.find(pubkey); | ||
| 149 | if (it != g_waiting.end()) { svc = it->second; g_waiting.erase(it); } | ||
| 150 | } | ||
| 151 | if (svc == INVALID_SOCKET) | ||
| 152 | { | ||
| 153 | unsigned char no = 0x00; | ||
| 154 | WriteN(s, &no, 1); | ||
| 155 | CLOSESOCK(s); | ||
| 156 | return; | ||
| 157 | } | ||
| 158 | // Pair: tell both sides, then forward raw bytes bidirectionally. | ||
| 159 | unsigned char ok = 0x01; | ||
| 160 | bool a = WriteN(svc, &ok, 1); | ||
| 161 | bool b = WriteN(s, &ok, 1); | ||
| 162 | if (!a || !b) { CLOSESOCK(svc); CLOSESOCK(s); return; } | ||
| 163 | std::thread(Forward, s, svc).detach(); | ||
| 164 | std::thread(Forward, svc, s).detach(); | ||
| 165 | } | ||
| 166 | else | ||
| 167 | { | ||
| 168 | CLOSESOCK(s); | ||
| 169 | } | ||
| 170 | } | ||
| 171 | |||
| 172 | bool RvRelayRun(unsigned short port) | ||
| 173 | { | ||
| 174 | if (!RvInit()) return false; | ||
| 175 | g_stop = false; | ||
| 176 | |||
| 177 | g_listen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); | ||
| 178 | if (g_listen == INVALID_SOCKET) return false; | ||
| 179 | int yes = 1; | ||
| 180 | setsockopt(g_listen, SOL_SOCKET, SO_REUSEADDR, (char*)&yes, sizeof(yes)); | ||
| 181 | |||
| 182 | struct sockaddr_in addr; | ||
| 183 | memset(&addr, 0, sizeof(addr)); | ||
| 184 | addr.sin_family = AF_INET; | ||
| 185 | addr.sin_addr.s_addr = INADDR_ANY; | ||
| 186 | addr.sin_port = htons(port); | ||
| 187 | if (bind(g_listen, (struct sockaddr*)&addr, sizeof(addr)) != 0) { CLOSESOCK(g_listen); return false; } | ||
| 188 | if (listen(g_listen, 16) != 0) { CLOSESOCK(g_listen); return false; } | ||
| 189 | |||
| 190 | while (!g_stop) | ||
| 191 | { | ||
| 192 | struct sockaddr_in cli; | ||
| 193 | socklen_t len = sizeof(cli); | ||
| 194 | SOCKET s = accept(g_listen, (struct sockaddr*)&cli, &len); | ||
| 195 | if (s == INVALID_SOCKET) | ||
| 196 | { | ||
| 197 | if (g_stop) break; | ||
| 198 | continue; | ||
| 199 | } | ||
| 200 | std::thread(HandleIncoming, s).detach(); | ||
| 201 | } | ||
| 202 | CLOSESOCK(g_listen); | ||
| 203 | g_listen = INVALID_SOCKET; | ||
| 204 | return true; | ||
| 205 | } | ||
| 206 | |||
| 207 | void RvRelayStop() | ||
| 208 | { | ||
| 209 | g_stop = true; | ||
| 210 | if (g_listen != INVALID_SOCKET) | ||
| 211 | CLOSESOCK(g_listen); // unblock accept() | ||
| 212 | } | ||
| 213 | |||
| 214 | // ---- service / client helpers ---- | ||
| 215 | |||
| 216 | RvSocket RvServiceRegister(const char* relay_host, unsigned short port, | ||
| 217 | const unsigned char my_pubkey[32]) | ||
| 218 | { | ||
| 219 | if (!RvInit()) return RV_INVALID; | ||
| 220 | SOCKET s = ConnectTo(relay_host, port); | ||
| 221 | if (s == INVALID_SOCKET) return RV_INVALID; | ||
| 222 | unsigned char hdr[33]; | ||
| 223 | hdr[0] = (unsigned char)'S'; | ||
| 224 | memcpy(hdr + 1, my_pubkey, 32); | ||
| 225 | if (!WriteN(s, hdr, 33)) { CLOSESOCK(s); return RV_INVALID; } | ||
| 226 | unsigned char paired = 0; | ||
| 227 | if (!ReadN(s, &paired, 1) || paired != 0x01) { CLOSESOCK(s); return RV_INVALID; } | ||
| 228 | return (RvSocket)s; | ||
| 229 | } | ||
| 230 | |||
| 231 | RvSocket RvClientConnect(const char* relay_host, unsigned short port, | ||
| 232 | const unsigned char target_pubkey[32]) | ||
| 233 | { | ||
| 234 | if (!RvInit()) return RV_INVALID; | ||
| 235 | SOCKET s = ConnectTo(relay_host, port); | ||
| 236 | if (s == INVALID_SOCKET) return RV_INVALID; | ||
| 237 | unsigned char hdr[33]; | ||
| 238 | hdr[0] = (unsigned char)'C'; | ||
| 239 | memcpy(hdr + 1, target_pubkey, 32); | ||
| 240 | if (!WriteN(s, hdr, 33)) { CLOSESOCK(s); return RV_INVALID; } | ||
| 241 | unsigned char paired = 0; | ||
| 242 | if (!ReadN(s, &paired, 1) || paired != 0x01) { CLOSESOCK(s); return RV_INVALID; } | ||
| 243 | return (RvSocket)s; | ||
| 244 | } | ||
| 245 | |||
| 246 | bool RvReadN(RvSocket s, void* buf, int n) { return ReadN((SOCKET)s, buf, n); } | ||
| 247 | bool RvWriteN(RvSocket s, const void* buf, int n) { return WriteN((SOCKET)s, buf, n); } | ||
| 248 | void RvClose(RvSocket s) { if (s != RV_INVALID) CLOSESOCK((SOCKET)s); } | ||
| 249 | |||
| 250 | } // namespace btf | ||
diff --git a/relay/btfrv.h b/relay/btfrv.h new file mode 100644 index 0000000..c776201 --- /dev/null +++ b/relay/btfrv.h | |||
| @@ -0,0 +1,59 @@ | |||
| 1 | // Copyright (c) 2026 Bitflash developers | ||
| 2 | // Distributed under the MIT/X11 software license. | ||
| 3 | // | ||
| 4 | // Bitflash rendezvous transport -- the "meeting node" that lets two nodes behind | ||
| 5 | // CGNAT connect without a public IP or port forwarding. Both sides connect OUT | ||
| 6 | // to the relay (which HAS a public IP, e.g. the VPS); the relay pairs them by | ||
| 7 | // `.btf` pubkey and forwards raw bytes between them. The endpoints then run the | ||
| 8 | // echan end-to-end channel on top, so the relay sees only ciphertext and cannot | ||
| 9 | // MITM (the client boxes to the service's STATIC key from its self-certified | ||
| 10 | // descriptor -- a substituting relay just breaks the channel, never reads it). | ||
| 11 | // | ||
| 12 | // This is the server that runs on the VPS (headless, Layer 6 ports it to Linux) | ||
| 13 | // plus the client/service helpers the desktop node uses. | ||
| 14 | |||
| 15 | #ifndef BITFLASH_BTFRV_H | ||
| 16 | #define BITFLASH_BTFRV_H | ||
| 17 | |||
| 18 | #include <stdint.h> | ||
| 19 | |||
| 20 | namespace btf | ||
| 21 | { | ||
| 22 | |||
| 23 | // A connected, paired rendezvous socket (opaque). Read/write raw bytes; the | ||
| 24 | // caller layers echan on top. Close with RvClose. | ||
| 25 | typedef intptr_t RvSocket; | ||
| 26 | static const RvSocket RV_INVALID = (RvSocket)-1; | ||
| 27 | |||
| 28 | // Initialize sockets (Winsock on Windows). Idempotent. | ||
| 29 | bool RvInit(); | ||
| 30 | |||
| 31 | // ---- relay side (runs on the VPS) ---- | ||
| 32 | // Run the rendezvous relay forever on `port`, forwarding between paired peers. | ||
| 33 | // Blocks; run it in a thread. Returns false if it can't bind/listen. | ||
| 34 | bool RvRelayRun(unsigned short port); | ||
| 35 | |||
| 36 | // Stop a running relay (signals RvRelayRun to return). | ||
| 37 | void RvRelayStop(); | ||
| 38 | |||
| 39 | // ---- service side (the node being reached by its .btf address) ---- | ||
| 40 | // Register at the relay under `my_pubkey` (32 bytes) and block until a client is | ||
| 41 | // paired to us. Returns the paired socket, or RV_INVALID on error. | ||
| 42 | RvSocket RvServiceRegister(const char* relay_host, unsigned short port, | ||
| 43 | const unsigned char my_pubkey[32]); | ||
| 44 | |||
| 45 | // ---- client side (the node dialing a .btf address) ---- | ||
| 46 | // Connect through the relay to the service registered under `target_pubkey`. | ||
| 47 | // Returns the paired socket, or RV_INVALID on error. | ||
| 48 | RvSocket RvClientConnect(const char* relay_host, unsigned short port, | ||
| 49 | const unsigned char target_pubkey[32]); | ||
| 50 | |||
| 51 | // Blocking read/write of exactly n bytes over a rendezvous socket. Return false | ||
| 52 | // on error/EOF. | ||
| 53 | bool RvReadN(RvSocket s, void* buf, int n); | ||
| 54 | bool RvWriteN(RvSocket s, const void* buf, int n); | ||
| 55 | void RvClose(RvSocket s); | ||
| 56 | |||
| 57 | } // namespace btf | ||
| 58 | |||
| 59 | #endif | ||
diff --git a/relay/build.sh b/relay/build.sh new file mode 100644 index 0000000..7796523 --- /dev/null +++ b/relay/build.sh | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | #!/usr/bin/env bash | ||
| 2 | # Build the Bitflash rendezvous relay (bitflashd) on Linux. No dependencies | ||
| 3 | # beyond a C++ compiler -- the relay only forwards bytes, it holds no keys. | ||
| 4 | set -e | ||
| 5 | g++ -std=gnu++14 -O2 -pthread bitflashd.cpp btfrv.cpp -o bitflashd | ||
| 6 | echo "built ./bitflashd -- run it with: ./bitflashd <port> (e.g. ./bitflashd 8434)" | ||
diff --git a/relay/install-bitflash-relay.sh b/relay/install-bitflash-relay.sh new file mode 100644 index 0000000..77a46b2 --- /dev/null +++ b/relay/install-bitflash-relay.sh | |||
| @@ -0,0 +1,326 @@ | |||
| 1 | #!/usr/bin/env bash | ||
| 2 | # Bitflash rendezvous relay -- one-shot installer for Linux. | ||
| 3 | # Anyone can run this on a machine with a PUBLIC IP (a cheap VPS) to become a | ||
| 4 | # meeting node that lets Bitflash users behind CGNAT reach each other. | ||
| 5 | # The relay holds NO keys and reads NOTHING -- it only forwards ciphertext. | ||
| 6 | # | ||
| 7 | # Usage: | ||
| 8 | # sudo bash install-bitflash-relay.sh [PORT] | ||
| 9 | # PORT defaults to 8434. Remember to open that port in your firewall/panel. | ||
| 10 | |||
| 11 | set -e | ||
| 12 | PORT="${1:-8434}" | ||
| 13 | DIR="$HOME/bitflash-relay" | ||
| 14 | mkdir -p "$DIR" && cd "$DIR" | ||
| 15 | |||
| 16 | echo ">> writing sources to $DIR" | ||
| 17 | |||
| 18 | cat > btfrv.h <<'BTFRV_H_EOF' | ||
| 19 | // Copyright (c) 2026 Bitflash developers | ||
| 20 | // Distributed under the MIT/X11 software license. | ||
| 21 | #ifndef BITFLASH_BTFRV_H | ||
| 22 | #define BITFLASH_BTFRV_H | ||
| 23 | #include <stdint.h> | ||
| 24 | namespace btf | ||
| 25 | { | ||
| 26 | typedef intptr_t RvSocket; | ||
| 27 | static const RvSocket RV_INVALID = (RvSocket)-1; | ||
| 28 | bool RvInit(); | ||
| 29 | bool RvRelayRun(unsigned short port); | ||
| 30 | void RvRelayStop(); | ||
| 31 | RvSocket RvServiceRegister(const char* relay_host, unsigned short port, | ||
| 32 | const unsigned char my_pubkey[32]); | ||
| 33 | RvSocket RvClientConnect(const char* relay_host, unsigned short port, | ||
| 34 | const unsigned char target_pubkey[32]); | ||
| 35 | bool RvReadN(RvSocket s, void* buf, int n); | ||
| 36 | bool RvWriteN(RvSocket s, const void* buf, int n); | ||
| 37 | void RvClose(RvSocket s); | ||
| 38 | } // namespace btf | ||
| 39 | #endif | ||
| 40 | BTFRV_H_EOF | ||
| 41 | |||
| 42 | cat > btfrv.cpp <<'BTFRV_CPP_EOF' | ||
| 43 | // Copyright (c) 2026 Bitflash developers | ||
| 44 | // Distributed under the MIT/X11 software license. | ||
| 45 | #include "btfrv.h" | ||
| 46 | #ifdef _WIN32 | ||
| 47 | #include <winsock2.h> | ||
| 48 | #include <ws2tcpip.h> | ||
| 49 | #define CLOSESOCK closesocket | ||
| 50 | #else | ||
| 51 | #include <sys/socket.h> | ||
| 52 | #include <netinet/in.h> | ||
| 53 | #include <arpa/inet.h> | ||
| 54 | #include <netdb.h> | ||
| 55 | #include <unistd.h> | ||
| 56 | #include <csignal> | ||
| 57 | typedef int SOCKET; | ||
| 58 | #define INVALID_SOCKET (-1) | ||
| 59 | #define SOCKET_ERROR (-1) | ||
| 60 | #define CLOSESOCK ::close | ||
| 61 | #ifndef SD_BOTH | ||
| 62 | #define SD_BOTH SHUT_RDWR | ||
| 63 | #endif | ||
| 64 | #endif | ||
| 65 | #include <cstring> | ||
| 66 | #include <cstdio> | ||
| 67 | #include <string> | ||
| 68 | #include <map> | ||
| 69 | #include <thread> | ||
| 70 | #include <mutex> | ||
| 71 | #include <atomic> | ||
| 72 | namespace btf | ||
| 73 | { | ||
| 74 | static std::atomic<bool> g_stop(false); | ||
| 75 | static SOCKET g_listen = INVALID_SOCKET; | ||
| 76 | static std::map<std::string, SOCKET> g_waiting; | ||
| 77 | static std::mutex g_mtx; | ||
| 78 | bool RvInit() | ||
| 79 | { | ||
| 80 | static bool done = false; | ||
| 81 | if (done) return true; | ||
| 82 | #ifdef _WIN32 | ||
| 83 | WSADATA wsa; | ||
| 84 | if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) return false; | ||
| 85 | #else | ||
| 86 | signal(SIGPIPE, SIG_IGN); | ||
| 87 | #endif | ||
| 88 | done = true; | ||
| 89 | return true; | ||
| 90 | } | ||
| 91 | static bool ReadN(SOCKET s, void* buf, int n) | ||
| 92 | { | ||
| 93 | char* p = (char*)buf; | ||
| 94 | int off = 0; | ||
| 95 | while (off < n) | ||
| 96 | { | ||
| 97 | int r = recv(s, p + off, n - off, 0); | ||
| 98 | if (r <= 0) return false; | ||
| 99 | off += r; | ||
| 100 | } | ||
| 101 | return true; | ||
| 102 | } | ||
| 103 | static bool WriteN(SOCKET s, const void* buf, int n) | ||
| 104 | { | ||
| 105 | const char* p = (const char*)buf; | ||
| 106 | int off = 0; | ||
| 107 | while (off < n) | ||
| 108 | { | ||
| 109 | int r = send(s, p + off, n - off, 0); | ||
| 110 | if (r <= 0) return false; | ||
| 111 | off += r; | ||
| 112 | } | ||
| 113 | return true; | ||
| 114 | } | ||
| 115 | static SOCKET ConnectTo(const char* host, unsigned short port) | ||
| 116 | { | ||
| 117 | struct addrinfo hints, *res = NULL; | ||
| 118 | memset(&hints, 0, sizeof(hints)); | ||
| 119 | hints.ai_family = AF_INET; | ||
| 120 | hints.ai_socktype = SOCK_STREAM; | ||
| 121 | char portstr[16]; sprintf(portstr, "%u", (unsigned)port); | ||
| 122 | if (getaddrinfo(host, portstr, &hints, &res) != 0 || !res) return INVALID_SOCKET; | ||
| 123 | SOCKET s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); | ||
| 124 | if (s == INVALID_SOCKET) { freeaddrinfo(res); return INVALID_SOCKET; } | ||
| 125 | if (connect(s, res->ai_addr, (int)res->ai_addrlen) != 0) | ||
| 126 | { | ||
| 127 | CLOSESOCK(s); freeaddrinfo(res); return INVALID_SOCKET; | ||
| 128 | } | ||
| 129 | freeaddrinfo(res); | ||
| 130 | return s; | ||
| 131 | } | ||
| 132 | static void Forward(SOCKET from, SOCKET to) | ||
| 133 | { | ||
| 134 | char buf[32 * 1024]; | ||
| 135 | for (;;) | ||
| 136 | { | ||
| 137 | int r = recv(from, buf, sizeof(buf), 0); | ||
| 138 | if (r <= 0) break; | ||
| 139 | if (!WriteN(to, buf, r)) break; | ||
| 140 | } | ||
| 141 | shutdown(to, SD_BOTH); | ||
| 142 | CLOSESOCK(from); | ||
| 143 | } | ||
| 144 | static void HandleIncoming(SOCKET s) | ||
| 145 | { | ||
| 146 | unsigned char hdr[33]; | ||
| 147 | if (!ReadN(s, hdr, 33)) { CLOSESOCK(s); return; } | ||
| 148 | char role = (char)hdr[0]; | ||
| 149 | std::string pubkey((char*)hdr + 1, 32); | ||
| 150 | if (role == 'S') | ||
| 151 | { | ||
| 152 | std::lock_guard<std::mutex> lk(g_mtx); | ||
| 153 | std::map<std::string, SOCKET>::iterator it = g_waiting.find(pubkey); | ||
| 154 | if (it != g_waiting.end()) CLOSESOCK(it->second); | ||
| 155 | g_waiting[pubkey] = s; | ||
| 156 | } | ||
| 157 | else if (role == 'C') | ||
| 158 | { | ||
| 159 | SOCKET svc = INVALID_SOCKET; | ||
| 160 | { | ||
| 161 | std::lock_guard<std::mutex> lk(g_mtx); | ||
| 162 | std::map<std::string, SOCKET>::iterator it = g_waiting.find(pubkey); | ||
| 163 | if (it != g_waiting.end()) { svc = it->second; g_waiting.erase(it); } | ||
| 164 | } | ||
| 165 | if (svc == INVALID_SOCKET) | ||
| 166 | { | ||
| 167 | unsigned char no = 0x00; | ||
| 168 | WriteN(s, &no, 1); | ||
| 169 | CLOSESOCK(s); | ||
| 170 | return; | ||
| 171 | } | ||
| 172 | unsigned char ok = 0x01; | ||
| 173 | bool a = WriteN(svc, &ok, 1); | ||
| 174 | bool b = WriteN(s, &ok, 1); | ||
| 175 | if (!a || !b) { CLOSESOCK(svc); CLOSESOCK(s); return; } | ||
| 176 | std::thread(Forward, s, svc).detach(); | ||
| 177 | std::thread(Forward, svc, s).detach(); | ||
| 178 | } | ||
| 179 | else | ||
| 180 | { | ||
| 181 | CLOSESOCK(s); | ||
| 182 | } | ||
| 183 | } | ||
| 184 | bool RvRelayRun(unsigned short port) | ||
| 185 | { | ||
| 186 | if (!RvInit()) return false; | ||
| 187 | g_stop = false; | ||
| 188 | g_listen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); | ||
| 189 | if (g_listen == INVALID_SOCKET) return false; | ||
| 190 | int yes = 1; | ||
| 191 | setsockopt(g_listen, SOL_SOCKET, SO_REUSEADDR, (char*)&yes, sizeof(yes)); | ||
| 192 | struct sockaddr_in addr; | ||
| 193 | memset(&addr, 0, sizeof(addr)); | ||
| 194 | addr.sin_family = AF_INET; | ||
| 195 | addr.sin_addr.s_addr = INADDR_ANY; | ||
| 196 | addr.sin_port = htons(port); | ||
| 197 | if (bind(g_listen, (struct sockaddr*)&addr, sizeof(addr)) != 0) { CLOSESOCK(g_listen); return false; } | ||
| 198 | if (listen(g_listen, 16) != 0) { CLOSESOCK(g_listen); return false; } | ||
| 199 | while (!g_stop) | ||
| 200 | { | ||
| 201 | struct sockaddr_in cli; | ||
| 202 | socklen_t len = sizeof(cli); | ||
| 203 | SOCKET s = accept(g_listen, (struct sockaddr*)&cli, &len); | ||
| 204 | if (s == INVALID_SOCKET) | ||
| 205 | { | ||
| 206 | if (g_stop) break; | ||
| 207 | continue; | ||
| 208 | } | ||
| 209 | std::thread(HandleIncoming, s).detach(); | ||
| 210 | } | ||
| 211 | CLOSESOCK(g_listen); | ||
| 212 | g_listen = INVALID_SOCKET; | ||
| 213 | return true; | ||
| 214 | } | ||
| 215 | void RvRelayStop() | ||
| 216 | { | ||
| 217 | g_stop = true; | ||
| 218 | if (g_listen != INVALID_SOCKET) | ||
| 219 | CLOSESOCK(g_listen); | ||
| 220 | } | ||
| 221 | RvSocket RvServiceRegister(const char* relay_host, unsigned short port, | ||
| 222 | const unsigned char my_pubkey[32]) | ||
| 223 | { | ||
| 224 | if (!RvInit()) return RV_INVALID; | ||
| 225 | SOCKET s = ConnectTo(relay_host, port); | ||
| 226 | if (s == INVALID_SOCKET) return RV_INVALID; | ||
| 227 | unsigned char hdr[33]; | ||
| 228 | hdr[0] = (unsigned char)'S'; | ||
| 229 | memcpy(hdr + 1, my_pubkey, 32); | ||
| 230 | if (!WriteN(s, hdr, 33)) { CLOSESOCK(s); return RV_INVALID; } | ||
| 231 | unsigned char paired = 0; | ||
| 232 | if (!ReadN(s, &paired, 1) || paired != 0x01) { CLOSESOCK(s); return RV_INVALID; } | ||
| 233 | return (RvSocket)s; | ||
| 234 | } | ||
| 235 | RvSocket RvClientConnect(const char* relay_host, unsigned short port, | ||
| 236 | const unsigned char target_pubkey[32]) | ||
| 237 | { | ||
| 238 | if (!RvInit()) return RV_INVALID; | ||
| 239 | SOCKET s = ConnectTo(relay_host, port); | ||
| 240 | if (s == INVALID_SOCKET) return RV_INVALID; | ||
| 241 | unsigned char hdr[33]; | ||
| 242 | hdr[0] = (unsigned char)'C'; | ||
| 243 | memcpy(hdr + 1, target_pubkey, 32); | ||
| 244 | if (!WriteN(s, hdr, 33)) { CLOSESOCK(s); return RV_INVALID; } | ||
| 245 | unsigned char paired = 0; | ||
| 246 | if (!ReadN(s, &paired, 1) || paired != 0x01) { CLOSESOCK(s); return RV_INVALID; } | ||
| 247 | return (RvSocket)s; | ||
| 248 | } | ||
| 249 | bool RvReadN(RvSocket s, void* buf, int n) { return ReadN((SOCKET)s, buf, n); } | ||
| 250 | bool RvWriteN(RvSocket s, const void* buf, int n) { return WriteN((SOCKET)s, buf, n); } | ||
| 251 | void RvClose(RvSocket s) { if (s != RV_INVALID) CLOSESOCK((SOCKET)s); } | ||
| 252 | } // namespace btf | ||
| 253 | BTFRV_CPP_EOF | ||
| 254 | |||
| 255 | cat > bitflashd.cpp <<'BITFLASHD_EOF' | ||
| 256 | // Copyright (c) 2026 Bitflash developers | ||
| 257 | // Distributed under the MIT/X11 software license. | ||
| 258 | #include "btfrv.h" | ||
| 259 | #include <cstdio> | ||
| 260 | #include <cstdlib> | ||
| 261 | #include <cstring> | ||
| 262 | int main(int argc, char* argv[]) | ||
| 263 | { | ||
| 264 | unsigned short port = 8434; | ||
| 265 | if (argc >= 2) | ||
| 266 | port = (unsigned short)atoi(argv[1]); | ||
| 267 | printf("bitflashd -- Bitflash rendezvous relay\n"); | ||
| 268 | printf("listening on 0.0.0.0:%u (open this port in your firewall)\n", port); | ||
| 269 | fflush(stdout); | ||
| 270 | if (!btf::RvInit()) | ||
| 271 | { | ||
| 272 | fprintf(stderr, "bitflashd: socket init failed\n"); | ||
| 273 | return 1; | ||
| 274 | } | ||
| 275 | if (!btf::RvRelayRun(port)) | ||
| 276 | { | ||
| 277 | fprintf(stderr, "bitflashd: could not bind/listen on port %u\n", port); | ||
| 278 | return 1; | ||
| 279 | } | ||
| 280 | return 0; | ||
| 281 | } | ||
| 282 | BITFLASHD_EOF | ||
| 283 | |||
| 284 | # g++ (Debian/Ubuntu: build-essential; RHEL/Alma: gcc-c++) | ||
| 285 | if ! command -v g++ >/dev/null 2>&1; then | ||
| 286 | echo ">> installing g++" | ||
| 287 | if command -v apt-get >/dev/null 2>&1; then apt-get update && apt-get install -y g++ | ||
| 288 | elif command -v dnf >/dev/null 2>&1; then dnf install -y gcc-c++ | ||
| 289 | elif command -v yum >/dev/null 2>&1; then yum install -y gcc-c++ | ||
| 290 | else echo "!! install a C++ compiler (g++) manually and re-run"; exit 1 | ||
| 291 | fi | ||
| 292 | fi | ||
| 293 | |||
| 294 | echo ">> building bitflashd" | ||
| 295 | g++ -std=gnu++14 -O2 -pthread bitflashd.cpp btfrv.cpp -o bitflashd | ||
| 296 | echo ">> build OK: $DIR/bitflashd" | ||
| 297 | |||
| 298 | # systemd service so it survives reboots (skipped if systemd is absent) | ||
| 299 | if command -v systemctl >/dev/null 2>&1 && [ -d /etc/systemd/system ]; then | ||
| 300 | cat > /etc/systemd/system/bitflashd.service <<EOF | ||
| 301 | [Unit] | ||
| 302 | Description=Bitflash rendezvous relay | ||
| 303 | After=network.target | ||
| 304 | |||
| 305 | [Service] | ||
| 306 | ExecStart=$DIR/bitflashd $PORT | ||
| 307 | Restart=always | ||
| 308 | User=$(id -un) | ||
| 309 | |||
| 310 | [Install] | ||
| 311 | WantedBy=multi-user.target | ||
| 312 | EOF | ||
| 313 | systemctl daemon-reload | ||
| 314 | systemctl enable --now bitflashd | ||
| 315 | sleep 1 | ||
| 316 | systemctl status bitflashd --no-pager || true | ||
| 317 | echo ">> relay running as a service on port $PORT" | ||
| 318 | else | ||
| 319 | echo ">> systemd not found; run it manually: $DIR/bitflashd $PORT" | ||
| 320 | fi | ||
| 321 | |||
| 322 | echo | ||
| 323 | echo "===================================================================" | ||
| 324 | echo " DONE. Open TCP port $PORT in your firewall / cloud panel." | ||
| 325 | echo " Your relay address for Bitflash users: <YOUR_PUBLIC_IP>:$PORT" | ||
| 326 | echo "===================================================================" | ||
diff --git a/src/base58.h b/src/base58.h new file mode 100644 index 0000000..c4f4526 --- /dev/null +++ b/src/base58.h | |||
| @@ -0,0 +1,204 @@ | |||
| 1 | // Copyright (c) 2009 Satoshi Nakamoto | ||
| 2 | // Distributed under the MIT/X11 software license, see the accompanying | ||
| 3 | // file license.txt or http://www.opensource.org/licenses/mit-license.php. | ||
| 4 | |||
| 5 | |||
| 6 | // | ||
| 7 | // Why base-58 instead of standard base-64 encoding? | ||
| 8 | // - Don't want 0OIl characters that look the same in some fonts and | ||
| 9 | // could be used to create visually identical looking account numbers. | ||
| 10 | // - A string with non-alphanumeric characters is not as easily accepted as an account number. | ||
| 11 | // - E-mail usually won't line-break if there's no punctuation to break at. | ||
| 12 | // - Doubleclicking selects the whole number as one word if it's all alphanumeric. | ||
| 13 | // | ||
| 14 | |||
| 15 | |||
| 16 | static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; | ||
| 17 | |||
| 18 | |||
| 19 | inline string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend) | ||
| 20 | { | ||
| 21 | CAutoBN_CTX pctx; | ||
| 22 | CBigNum bn58 = 58; | ||
| 23 | CBigNum bn0 = 0; | ||
| 24 | |||
| 25 | // Convert big endian data to little endian | ||
| 26 | // Extra zero at the end make sure bignum will interpret as a positive number | ||
| 27 | vector<unsigned char> vchTmp(pend-pbegin+1, 0); | ||
| 28 | reverse_copy(pbegin, pend, vchTmp.begin()); | ||
| 29 | |||
| 30 | // Convert little endian data to bignum | ||
| 31 | CBigNum bn; | ||
| 32 | bn.setvch(vchTmp); | ||
| 33 | |||
| 34 | // Convert bignum to string | ||
| 35 | string str; | ||
| 36 | str.reserve((pend - pbegin) * 138 / 100 + 1); | ||
| 37 | CBigNum dv; | ||
| 38 | CBigNum rem; | ||
| 39 | while (bn > bn0) | ||
| 40 | { | ||
| 41 | if (!BN_div(dv.get(), rem.get(), bn.get(), bn58.get(), pctx)) | ||
| 42 | throw bignum_error("EncodeBase58 : BN_div failed"); | ||
| 43 | bn = dv; | ||
| 44 | unsigned int c = rem.getulong(); | ||
| 45 | str += pszBase58[c]; | ||
| 46 | } | ||
| 47 | |||
| 48 | // Leading zeroes encoded as base58 zeros | ||
| 49 | for (const unsigned char* p = pbegin; p < pend && *p == 0; p++) | ||
| 50 | str += pszBase58[0]; | ||
| 51 | |||
| 52 | // Convert little endian string to big endian | ||
| 53 | reverse(str.begin(), str.end()); | ||
| 54 | return str; | ||
| 55 | } | ||
| 56 | |||
| 57 | inline string EncodeBase58(const vector<unsigned char>& vch) | ||
| 58 | { | ||
| 59 | return EncodeBase58(&vch[0], &vch[0] + vch.size()); | ||
| 60 | } | ||
| 61 | |||
| 62 | inline bool DecodeBase58(const char* psz, vector<unsigned char>& vchRet) | ||
| 63 | { | ||
| 64 | CAutoBN_CTX pctx; | ||
| 65 | vchRet.clear(); | ||
| 66 | CBigNum bn58 = 58; | ||
| 67 | CBigNum bn = 0; | ||
| 68 | CBigNum bnChar; | ||
| 69 | while (isspace(*psz)) | ||
| 70 | psz++; | ||
| 71 | |||
| 72 | // Convert big endian string to bignum | ||
| 73 | for (const char* p = psz; *p; p++) | ||
| 74 | { | ||
| 75 | const char* p1 = strchr(pszBase58, *p); | ||
| 76 | if (p1 == NULL) | ||
| 77 | { | ||
| 78 | while (isspace(*p)) | ||
| 79 | p++; | ||
| 80 | if (*p != '\0') | ||
| 81 | return false; | ||
| 82 | break; | ||
| 83 | } | ||
| 84 | bnChar.setulong(p1 - pszBase58); | ||
| 85 | if (!BN_mul(bn.get(), bn.get(), bn58.get(), pctx)) | ||
| 86 | throw bignum_error("DecodeBase58 : BN_mul failed"); | ||
| 87 | bn += bnChar; | ||
| 88 | } | ||
| 89 | |||
| 90 | // Get bignum as little endian data | ||
| 91 | vector<unsigned char> vchTmp = bn.getvch(); | ||
| 92 | |||
| 93 | // Trim off sign byte if present | ||
| 94 | if (vchTmp.size() >= 2 && vchTmp.end()[-1] == 0 && vchTmp.end()[-2] >= 0x80) | ||
| 95 | vchTmp.erase(vchTmp.end()-1); | ||
| 96 | |||
| 97 | // Restore leading zeros | ||
| 98 | int nLeadingZeros = 0; | ||
| 99 | for (const char* p = psz; *p == pszBase58[0]; p++) | ||
| 100 | nLeadingZeros++; | ||
| 101 | vchRet.assign(nLeadingZeros + vchTmp.size(), 0); | ||
| 102 | |||
| 103 | // Convert little endian data to big endian | ||
| 104 | reverse_copy(vchTmp.begin(), vchTmp.end(), vchRet.end() - vchTmp.size()); | ||
| 105 | return true; | ||
| 106 | } | ||
| 107 | |||
| 108 | inline bool DecodeBase58(const string& str, vector<unsigned char>& vchRet) | ||
| 109 | { | ||
| 110 | return DecodeBase58(str.c_str(), vchRet); | ||
| 111 | } | ||
| 112 | |||
| 113 | |||
| 114 | |||
| 115 | |||
| 116 | |||
| 117 | inline string EncodeBase58Check(const vector<unsigned char>& vchIn) | ||
| 118 | { | ||
| 119 | // add 4-byte hash check to the end | ||
| 120 | vector<unsigned char> vch(vchIn); | ||
| 121 | uint256 hash = Hash(vch.begin(), vch.end()); | ||
| 122 | vch.insert(vch.end(), (unsigned char*)&hash, (unsigned char*)&hash + 4); | ||
| 123 | return EncodeBase58(vch); | ||
| 124 | } | ||
| 125 | |||
| 126 | inline bool DecodeBase58Check(const char* psz, vector<unsigned char>& vchRet) | ||
| 127 | { | ||
| 128 | if (!DecodeBase58(psz, vchRet)) | ||
| 129 | return false; | ||
| 130 | if (vchRet.size() < 4) | ||
| 131 | { | ||
| 132 | vchRet.clear(); | ||
| 133 | return false; | ||
| 134 | } | ||
| 135 | uint256 hash = Hash(vchRet.begin(), vchRet.end()-4); | ||
| 136 | if (memcmp(&hash, &vchRet.end()[-4], 4) != 0) | ||
| 137 | { | ||
| 138 | vchRet.clear(); | ||
| 139 | return false; | ||
| 140 | } | ||
| 141 | vchRet.resize(vchRet.size()-4); | ||
| 142 | return true; | ||
| 143 | } | ||
| 144 | |||
| 145 | inline bool DecodeBase58Check(const string& str, vector<unsigned char>& vchRet) | ||
| 146 | { | ||
| 147 | return DecodeBase58Check(str.c_str(), vchRet); | ||
| 148 | } | ||
| 149 | |||
| 150 | |||
| 151 | |||
| 152 | |||
| 153 | |||
| 154 | |||
| 155 | // Version 25 (0x19): Bitflash addresses start with "B" | ||
| 156 | static const unsigned char ADDRESSVERSION = 25; | ||
| 157 | |||
| 158 | inline string Hash160ToAddress(uint160 hash160) | ||
| 159 | { | ||
| 160 | // add 1-byte version number to the front | ||
| 161 | vector<unsigned char> vch(1, ADDRESSVERSION); | ||
| 162 | vch.insert(vch.end(), UBEGIN(hash160), UEND(hash160)); | ||
| 163 | return EncodeBase58Check(vch); | ||
| 164 | } | ||
| 165 | |||
| 166 | inline bool AddressToHash160(const char* psz, uint160& hash160Ret) | ||
| 167 | { | ||
| 168 | vector<unsigned char> vch; | ||
| 169 | if (!DecodeBase58Check(psz, vch)) | ||
| 170 | return false; | ||
| 171 | if (vch.empty()) | ||
| 172 | return false; | ||
| 173 | unsigned char nVersion = vch[0]; | ||
| 174 | if (vch.size() != sizeof(hash160Ret) + 1) | ||
| 175 | return false; | ||
| 176 | memcpy(&hash160Ret, &vch[1], sizeof(hash160Ret)); | ||
| 177 | // security fix: accept only the exact network version | ||
| 178 | // (the original "<=" would accept addresses of any lower version) | ||
| 179 | return (nVersion == ADDRESSVERSION); | ||
| 180 | } | ||
| 181 | |||
| 182 | inline bool AddressToHash160(const string& str, uint160& hash160Ret) | ||
| 183 | { | ||
| 184 | return AddressToHash160(str.c_str(), hash160Ret); | ||
| 185 | } | ||
| 186 | |||
| 187 | inline bool IsValidBitcoinAddress(const char* psz) | ||
| 188 | { | ||
| 189 | uint160 hash160; | ||
| 190 | return AddressToHash160(psz, hash160); | ||
| 191 | } | ||
| 192 | |||
| 193 | inline bool IsValidBitcoinAddress(const string& str) | ||
| 194 | { | ||
| 195 | return IsValidBitcoinAddress(str.c_str()); | ||
| 196 | } | ||
| 197 | |||
| 198 | |||
| 199 | |||
| 200 | |||
| 201 | inline string PubKeyToAddress(const vector<unsigned char>& vchPubKey) | ||
| 202 | { | ||
| 203 | return Hash160ToAddress(Hash160(vchPubKey)); | ||
| 204 | } | ||
diff --git a/src/bignum.h b/src/bignum.h new file mode 100644 index 0000000..9da104b --- /dev/null +++ b/src/bignum.h | |||
| @@ -0,0 +1,525 @@ | |||
| 1 | // Copyright (c) 2009 Satoshi Nakamoto | ||
| 2 | // Distributed under the MIT/X11 software license, see the accompanying | ||
| 3 | // file license.txt or http://www.opensource.org/licenses/mit-license.php. | ||
| 4 | // | ||
| 5 | // Ported to OpenSSL 1.1+/3.x: BIGNUM became an opaque type, so CBigNum now | ||
| 6 | // wraps a BIGNUM* instead of inheriting from BIGNUM. Identical semantics. | ||
| 7 | |||
| 8 | #include <stdexcept> | ||
| 9 | #include <vector> | ||
| 10 | #include <openssl/bn.h> | ||
| 11 | |||
| 12 | |||
| 13 | |||
| 14 | |||
| 15 | |||
| 16 | class bignum_error : public std::runtime_error | ||
| 17 | { | ||
| 18 | public: | ||
| 19 | explicit bignum_error(const std::string& str) : std::runtime_error(str) {} | ||
| 20 | }; | ||
| 21 | |||
| 22 | |||
| 23 | |||
| 24 | class CAutoBN_CTX | ||
| 25 | { | ||
| 26 | protected: | ||
| 27 | BN_CTX* pctx; | ||
| 28 | BN_CTX* operator=(BN_CTX* pnew) { return pctx = pnew; } | ||
| 29 | |||
| 30 | public: | ||
| 31 | CAutoBN_CTX() | ||
| 32 | { | ||
| 33 | pctx = BN_CTX_new(); | ||
| 34 | if (pctx == NULL) | ||
| 35 | throw bignum_error("CAutoBN_CTX : BN_CTX_new() returned NULL"); | ||
| 36 | } | ||
| 37 | |||
| 38 | ~CAutoBN_CTX() | ||
| 39 | { | ||
| 40 | if (pctx != NULL) | ||
| 41 | BN_CTX_free(pctx); | ||
| 42 | } | ||
| 43 | |||
| 44 | operator BN_CTX*() { return pctx; } | ||
| 45 | BN_CTX& operator*() { return *pctx; } | ||
| 46 | BN_CTX** operator&() { return &pctx; } | ||
| 47 | bool operator!() { return (pctx == NULL); } | ||
| 48 | }; | ||
| 49 | |||
| 50 | |||
| 51 | |||
| 52 | class CBigNum | ||
| 53 | { | ||
| 54 | protected: | ||
| 55 | BIGNUM* bn; | ||
| 56 | |||
| 57 | void init() | ||
| 58 | { | ||
| 59 | bn = BN_new(); | ||
| 60 | if (bn == NULL) | ||
| 61 | throw bignum_error("CBigNum : BN_new failed"); | ||
| 62 | } | ||
| 63 | |||
| 64 | public: | ||
| 65 | BIGNUM* get() { return bn; } | ||
| 66 | const BIGNUM* get() const { return bn; } | ||
| 67 | |||
| 68 | CBigNum() | ||
| 69 | { | ||
| 70 | init(); | ||
| 71 | } | ||
| 72 | |||
| 73 | CBigNum(const CBigNum& b) | ||
| 74 | { | ||
| 75 | init(); | ||
| 76 | if (!BN_copy(bn, b.bn)) | ||
| 77 | { | ||
| 78 | BN_clear_free(bn); | ||
| 79 | throw bignum_error("CBigNum::CBigNum(const CBigNum&) : BN_copy failed"); | ||
| 80 | } | ||
| 81 | } | ||
| 82 | |||
| 83 | explicit CBigNum(const std::string& str) | ||
| 84 | { | ||
| 85 | init(); | ||
| 86 | SetHex(str); | ||
| 87 | } | ||
| 88 | |||
| 89 | CBigNum& operator=(const CBigNum& b) | ||
| 90 | { | ||
| 91 | if (!BN_copy(bn, b.bn)) | ||
| 92 | throw bignum_error("CBigNum::operator= : BN_copy failed"); | ||
| 93 | return (*this); | ||
| 94 | } | ||
| 95 | |||
| 96 | ~CBigNum() | ||
| 97 | { | ||
| 98 | BN_clear_free(bn); | ||
| 99 | } | ||
| 100 | |||
| 101 | CBigNum(char n) { init(); if (n >= 0) setulong(n); else setint64(n); } | ||
| 102 | CBigNum(short n) { init(); if (n >= 0) setulong(n); else setint64(n); } | ||
| 103 | CBigNum(int n) { init(); if (n >= 0) setulong(n); else setint64(n); } | ||
| 104 | CBigNum(long n) { init(); if (n >= 0) setulong(n); else setint64(n); } | ||
| 105 | CBigNum(int64 n) { init(); setint64(n); } | ||
| 106 | CBigNum(unsigned char n) { init(); setulong(n); } | ||
| 107 | CBigNum(unsigned short n) { init(); setulong(n); } | ||
| 108 | CBigNum(unsigned int n) { init(); setulong(n); } | ||
| 109 | CBigNum(unsigned long n) { init(); setulong(n); } | ||
| 110 | CBigNum(uint64 n) { init(); setuint64(n); } | ||
| 111 | explicit CBigNum(uint256 n) { init(); setuint256(n); } | ||
| 112 | |||
| 113 | explicit CBigNum(const std::vector<unsigned char>& vch) | ||
| 114 | { | ||
| 115 | init(); | ||
| 116 | setvch(vch); | ||
| 117 | } | ||
| 118 | |||
| 119 | void setulong(unsigned long n) | ||
| 120 | { | ||
| 121 | if (!BN_set_word(bn, n)) | ||
| 122 | throw bignum_error("CBigNum conversion from unsigned long : BN_set_word failed"); | ||
| 123 | } | ||
| 124 | |||
| 125 | unsigned long getulong() const | ||
| 126 | { | ||
| 127 | return BN_get_word(bn); | ||
| 128 | } | ||
| 129 | |||
| 130 | unsigned int getuint() const | ||
| 131 | { | ||
| 132 | return BN_get_word(bn); | ||
| 133 | } | ||
| 134 | |||
| 135 | int getint() const | ||
| 136 | { | ||
| 137 | unsigned long n = BN_get_word(bn); | ||
| 138 | if (!BN_is_negative(bn)) | ||
| 139 | return (n > INT_MAX ? INT_MAX : n); | ||
| 140 | else | ||
| 141 | return (n > INT_MAX ? INT_MIN : -(int)n); | ||
| 142 | } | ||
| 143 | |||
| 144 | void setint64(int64 n) | ||
| 145 | { | ||
| 146 | unsigned char pch[sizeof(n) + 6]; | ||
| 147 | unsigned char* p = pch + 4; | ||
| 148 | bool fNegative = false; | ||
| 149 | if (n < (int64)0) | ||
| 150 | { | ||
| 151 | n = -n; | ||
| 152 | fNegative = true; | ||
| 153 | } | ||
| 154 | bool fLeadingZeroes = true; | ||
| 155 | for (int i = 0; i < 8; i++) | ||
| 156 | { | ||
| 157 | unsigned char c = (n >> 56) & 0xff; | ||
| 158 | n <<= 8; | ||
| 159 | if (fLeadingZeroes) | ||
| 160 | { | ||
| 161 | if (c == 0) | ||
| 162 | continue; | ||
| 163 | if (c & 0x80) | ||
| 164 | *p++ = (fNegative ? 0x80 : 0); | ||
| 165 | else if (fNegative) | ||
| 166 | c |= 0x80; | ||
| 167 | fLeadingZeroes = false; | ||
| 168 | } | ||
| 169 | *p++ = c; | ||
| 170 | } | ||
| 171 | unsigned int nSize = p - (pch + 4); | ||
| 172 | pch[0] = (nSize >> 24) & 0xff; | ||
| 173 | pch[1] = (nSize >> 16) & 0xff; | ||
| 174 | pch[2] = (nSize >> 8) & 0xff; | ||
| 175 | pch[3] = (nSize) & 0xff; | ||
| 176 | BN_mpi2bn(pch, p - pch, bn); | ||
| 177 | } | ||
| 178 | |||
| 179 | void setuint64(uint64 n) | ||
| 180 | { | ||
| 181 | unsigned char pch[sizeof(n) + 6]; | ||
| 182 | unsigned char* p = pch + 4; | ||
| 183 | bool fLeadingZeroes = true; | ||
| 184 | for (int i = 0; i < 8; i++) | ||
| 185 | { | ||
| 186 | unsigned char c = (n >> 56) & 0xff; | ||
| 187 | n <<= 8; | ||
| 188 | if (fLeadingZeroes) | ||
| 189 | { | ||
| 190 | if (c == 0) | ||
| 191 | continue; | ||
| 192 | if (c & 0x80) | ||
| 193 | *p++ = 0; | ||
| 194 | fLeadingZeroes = false; | ||
| 195 | } | ||
| 196 | *p++ = c; | ||
| 197 | } | ||
| 198 | unsigned int nSize = p - (pch + 4); | ||
| 199 | pch[0] = (nSize >> 24) & 0xff; | ||
| 200 | pch[1] = (nSize >> 16) & 0xff; | ||
| 201 | pch[2] = (nSize >> 8) & 0xff; | ||
| 202 | pch[3] = (nSize) & 0xff; | ||
| 203 | BN_mpi2bn(pch, p - pch, bn); | ||
| 204 | } | ||
| 205 | |||
| 206 | void setuint256(uint256 n) | ||
| 207 | { | ||
| 208 | unsigned char pch[sizeof(n) + 6]; | ||
| 209 | unsigned char* p = pch + 4; | ||
| 210 | bool fLeadingZeroes = true; | ||
| 211 | unsigned char* pbegin = (unsigned char*)&n; | ||
| 212 | unsigned char* psrc = pbegin + sizeof(n); | ||
| 213 | while (psrc != pbegin) | ||
| 214 | { | ||
| 215 | unsigned char c = *(--psrc); | ||
| 216 | if (fLeadingZeroes) | ||
| 217 | { | ||
| 218 | if (c == 0) | ||
| 219 | continue; | ||
| 220 | if (c & 0x80) | ||
| 221 | *p++ = 0; | ||
| 222 | fLeadingZeroes = false; | ||
| 223 | } | ||
| 224 | *p++ = c; | ||
| 225 | } | ||
| 226 | unsigned int nSize = p - (pch + 4); | ||
| 227 | pch[0] = (nSize >> 24) & 0xff; | ||
| 228 | pch[1] = (nSize >> 16) & 0xff; | ||
| 229 | pch[2] = (nSize >> 8) & 0xff; | ||
| 230 | pch[3] = (nSize >> 0) & 0xff; | ||
| 231 | BN_mpi2bn(pch, p - pch, bn); | ||
| 232 | } | ||
| 233 | |||
| 234 | uint256 getuint256() | ||
| 235 | { | ||
| 236 | unsigned int nSize = BN_bn2mpi(bn, NULL); | ||
| 237 | if (nSize < 4) | ||
| 238 | return 0; | ||
| 239 | std::vector<unsigned char> vch(nSize); | ||
| 240 | BN_bn2mpi(bn, &vch[0]); | ||
| 241 | if (vch.size() > 4) | ||
| 242 | vch[4] &= 0x7f; | ||
| 243 | uint256 n = 0; | ||
| 244 | for (int i = 0, j = vch.size()-1; i < sizeof(n) && j >= 4; i++, j--) | ||
| 245 | ((unsigned char*)&n)[i] = vch[j]; | ||
| 246 | return n; | ||
| 247 | } | ||
| 248 | |||
| 249 | void setvch(const std::vector<unsigned char>& vch) | ||
| 250 | { | ||
| 251 | std::vector<unsigned char> vch2(vch.size() + 4); | ||
| 252 | unsigned int nSize = vch.size(); | ||
| 253 | vch2[0] = (nSize >> 24) & 0xff; | ||
| 254 | vch2[1] = (nSize >> 16) & 0xff; | ||
| 255 | vch2[2] = (nSize >> 8) & 0xff; | ||
| 256 | vch2[3] = (nSize >> 0) & 0xff; | ||
| 257 | reverse_copy(vch.begin(), vch.end(), vch2.begin() + 4); | ||
| 258 | BN_mpi2bn(&vch2[0], vch2.size(), bn); | ||
| 259 | } | ||
| 260 | |||
| 261 | std::vector<unsigned char> getvch() const | ||
| 262 | { | ||
| 263 | unsigned int nSize = BN_bn2mpi(bn, NULL); | ||
| 264 | if (nSize < 4) | ||
| 265 | return std::vector<unsigned char>(); | ||
| 266 | std::vector<unsigned char> vch(nSize); | ||
| 267 | BN_bn2mpi(bn, &vch[0]); | ||
| 268 | vch.erase(vch.begin(), vch.begin() + 4); | ||
| 269 | reverse(vch.begin(), vch.end()); | ||
| 270 | return vch; | ||
| 271 | } | ||
| 272 | |||
| 273 | CBigNum& SetCompact(unsigned int nCompact) | ||
| 274 | { | ||
| 275 | unsigned int nSize = nCompact >> 24; | ||
| 276 | std::vector<unsigned char> vch(4 + nSize); | ||
| 277 | vch[3] = nSize; | ||
| 278 | if (nSize >= 1) vch[4] = (nCompact >> 16) & 0xff; | ||
| 279 | if (nSize >= 2) vch[5] = (nCompact >> 8) & 0xff; | ||
| 280 | if (nSize >= 3) vch[6] = (nCompact >> 0) & 0xff; | ||
| 281 | BN_mpi2bn(&vch[0], vch.size(), bn); | ||
| 282 | return *this; | ||
| 283 | } | ||
| 284 | |||
| 285 | unsigned int GetCompact() const | ||
| 286 | { | ||
| 287 | unsigned int nSize = BN_bn2mpi(bn, NULL); | ||
| 288 | std::vector<unsigned char> vch(nSize); | ||
| 289 | nSize -= 4; | ||
| 290 | BN_bn2mpi(bn, &vch[0]); | ||
| 291 | unsigned int nCompact = nSize << 24; | ||
| 292 | if (nSize >= 1) nCompact |= (vch[4] << 16); | ||
| 293 | if (nSize >= 2) nCompact |= (vch[5] << 8); | ||
| 294 | if (nSize >= 3) nCompact |= (vch[6] << 0); | ||
| 295 | return nCompact; | ||
| 296 | } | ||
| 297 | |||
| 298 | void SetHex(const std::string& str) | ||
| 299 | { | ||
| 300 | // skip 0x | ||
| 301 | const char* psz = str.c_str(); | ||
| 302 | while (isspace(*psz)) | ||
| 303 | psz++; | ||
| 304 | bool fNegative = false; | ||
| 305 | if (*psz == '-') | ||
| 306 | { | ||
| 307 | fNegative = true; | ||
| 308 | psz++; | ||
| 309 | } | ||
| 310 | if (psz[0] == '0' && tolower(psz[1]) == 'x') | ||
| 311 | psz += 2; | ||
| 312 | while (isspace(*psz)) | ||
| 313 | psz++; | ||
| 314 | |||
| 315 | // hex string to bignum | ||
| 316 | static char phexdigit[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0 }; | ||
| 317 | *this = 0; | ||
| 318 | while (isxdigit(*psz)) | ||
| 319 | { | ||
| 320 | *this <<= 4; | ||
| 321 | int n = phexdigit[(unsigned char)*psz++]; | ||
| 322 | *this += n; | ||
| 323 | } | ||
| 324 | if (fNegative) | ||
| 325 | *this = 0 - *this; | ||
| 326 | } | ||
| 327 | |||
| 328 | unsigned int GetSerializeSize(int nType=0, int nVersion=VERSION) const | ||
| 329 | { | ||
| 330 | return ::GetSerializeSize(getvch(), nType, nVersion); | ||
| 331 | } | ||
| 332 | |||
| 333 | template<typename Stream> | ||
| 334 | void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const | ||
| 335 | { | ||
| 336 | ::Serialize(s, getvch(), nType, nVersion); | ||
| 337 | } | ||
| 338 | |||
| 339 | template<typename Stream> | ||
| 340 | void Unserialize(Stream& s, int nType=0, int nVersion=VERSION) | ||
| 341 | { | ||
| 342 | vector<unsigned char> vch; | ||
| 343 | ::Unserialize(s, vch, nType, nVersion); | ||
| 344 | setvch(vch); | ||
| 345 | } | ||
| 346 | |||
| 347 | |||
| 348 | bool operator!() const | ||
| 349 | { | ||
| 350 | return BN_is_zero(bn); | ||
| 351 | } | ||
| 352 | |||
| 353 | CBigNum& operator+=(const CBigNum& b) | ||
| 354 | { | ||
| 355 | if (!BN_add(bn, bn, b.bn)) | ||
| 356 | throw bignum_error("CBigNum::operator+= : BN_add failed"); | ||
| 357 | return *this; | ||
| 358 | } | ||
| 359 | |||
| 360 | CBigNum& operator-=(const CBigNum& b) | ||
| 361 | { | ||
| 362 | *this = *this - b; | ||
| 363 | return *this; | ||
| 364 | } | ||
| 365 | |||
| 366 | CBigNum& operator*=(const CBigNum& b) | ||
| 367 | { | ||
| 368 | CAutoBN_CTX pctx; | ||
| 369 | if (!BN_mul(bn, bn, b.bn, pctx)) | ||
| 370 | throw bignum_error("CBigNum::operator*= : BN_mul failed"); | ||
| 371 | return *this; | ||
| 372 | } | ||
| 373 | |||
| 374 | CBigNum& operator/=(const CBigNum& b) | ||
| 375 | { | ||
| 376 | *this = *this / b; | ||
| 377 | return *this; | ||
| 378 | } | ||
| 379 | |||
| 380 | CBigNum& operator%=(const CBigNum& b) | ||
| 381 | { | ||
| 382 | *this = *this % b; | ||
| 383 | return *this; | ||
| 384 | } | ||
| 385 | |||
| 386 | CBigNum& operator<<=(unsigned int shift) | ||
| 387 | { | ||
| 388 | if (!BN_lshift(bn, bn, shift)) | ||
| 389 | throw bignum_error("CBigNum:operator<<= : BN_lshift failed"); | ||
| 390 | return *this; | ||
| 391 | } | ||
| 392 | |||
| 393 | CBigNum& operator>>=(unsigned int shift) | ||
| 394 | { | ||
| 395 | if (!BN_rshift(bn, bn, shift)) | ||
| 396 | throw bignum_error("CBigNum:operator>>= : BN_rshift failed"); | ||
| 397 | return *this; | ||
| 398 | } | ||
| 399 | |||
| 400 | |||
| 401 | CBigNum& operator++() | ||
| 402 | { | ||
| 403 | // prefix operator | ||
| 404 | if (!BN_add(bn, bn, BN_value_one())) | ||
| 405 | throw bignum_error("CBigNum::operator++ : BN_add failed"); | ||
| 406 | return *this; | ||
| 407 | } | ||
| 408 | |||
| 409 | const CBigNum operator++(int) | ||
| 410 | { | ||
| 411 | // postfix operator | ||
| 412 | const CBigNum ret = *this; | ||
| 413 | ++(*this); | ||
| 414 | return ret; | ||
| 415 | } | ||
| 416 | |||
| 417 | CBigNum& operator--() | ||
| 418 | { | ||
| 419 | // prefix operator | ||
| 420 | CBigNum r; | ||
| 421 | if (!BN_sub(r.bn, bn, BN_value_one())) | ||
| 422 | throw bignum_error("CBigNum::operator-- : BN_sub failed"); | ||
| 423 | *this = r; | ||
| 424 | return *this; | ||
| 425 | } | ||
| 426 | |||
| 427 | const CBigNum operator--(int) | ||
| 428 | { | ||
| 429 | // postfix operator | ||
| 430 | const CBigNum ret = *this; | ||
| 431 | --(*this); | ||
| 432 | return ret; | ||
| 433 | } | ||
| 434 | |||
| 435 | |||
| 436 | friend inline const CBigNum operator+(const CBigNum& a, const CBigNum& b); | ||
| 437 | friend inline const CBigNum operator-(const CBigNum& a, const CBigNum& b); | ||
| 438 | friend inline const CBigNum operator-(const CBigNum& a); | ||
| 439 | friend inline const CBigNum operator*(const CBigNum& a, const CBigNum& b); | ||
| 440 | friend inline const CBigNum operator/(const CBigNum& a, const CBigNum& b); | ||
| 441 | friend inline const CBigNum operator%(const CBigNum& a, const CBigNum& b); | ||
| 442 | friend inline const CBigNum operator<<(const CBigNum& a, unsigned int shift); | ||
| 443 | friend inline const CBigNum operator>>(const CBigNum& a, unsigned int shift); | ||
| 444 | friend inline bool operator==(const CBigNum& a, const CBigNum& b); | ||
| 445 | friend inline bool operator!=(const CBigNum& a, const CBigNum& b); | ||
| 446 | friend inline bool operator<=(const CBigNum& a, const CBigNum& b); | ||
| 447 | friend inline bool operator>=(const CBigNum& a, const CBigNum& b); | ||
| 448 | friend inline bool operator<(const CBigNum& a, const CBigNum& b); | ||
| 449 | friend inline bool operator>(const CBigNum& a, const CBigNum& b); | ||
| 450 | }; | ||
| 451 | |||
| 452 | |||
| 453 | |||
| 454 | inline const CBigNum operator+(const CBigNum& a, const CBigNum& b) | ||
| 455 | { | ||
| 456 | CBigNum r; | ||
| 457 | if (!BN_add(r.bn, a.bn, b.bn)) | ||
| 458 | throw bignum_error("CBigNum::operator+ : BN_add failed"); | ||
| 459 | return r; | ||
| 460 | } | ||
| 461 | |||
| 462 | inline const CBigNum operator-(const CBigNum& a, const CBigNum& b) | ||
| 463 | { | ||
| 464 | CBigNum r; | ||
| 465 | if (!BN_sub(r.bn, a.bn, b.bn)) | ||
| 466 | throw bignum_error("CBigNum::operator- : BN_sub failed"); | ||
| 467 | return r; | ||
| 468 | } | ||
| 469 | |||
| 470 | inline const CBigNum operator-(const CBigNum& a) | ||
| 471 | { | ||
| 472 | CBigNum r(a); | ||
| 473 | BN_set_negative(r.bn, !BN_is_negative(r.bn)); | ||
| 474 | return r; | ||
| 475 | } | ||
| 476 | |||
| 477 | inline const CBigNum operator*(const CBigNum& a, const CBigNum& b) | ||
| 478 | { | ||
| 479 | CAutoBN_CTX pctx; | ||
| 480 | CBigNum r; | ||
| 481 | if (!BN_mul(r.bn, a.bn, b.bn, pctx)) | ||
| 482 | throw bignum_error("CBigNum::operator* : BN_mul failed"); | ||
| 483 | return r; | ||
| 484 | } | ||
| 485 | |||
| 486 | inline const CBigNum operator/(const CBigNum& a, const CBigNum& b) | ||
| 487 | { | ||
| 488 | CAutoBN_CTX pctx; | ||
| 489 | CBigNum r; | ||
| 490 | if (!BN_div(r.bn, NULL, a.bn, b.bn, pctx)) | ||
| 491 | throw bignum_error("CBigNum::operator/ : BN_div failed"); | ||
| 492 | return r; | ||
| 493 | } | ||
| 494 | |||
| 495 | inline const CBigNum operator%(const CBigNum& a, const CBigNum& b) | ||
| 496 | { | ||
| 497 | CAutoBN_CTX pctx; | ||
| 498 | CBigNum r; | ||
| 499 | if (!BN_mod(r.bn, a.bn, b.bn, pctx)) | ||
| 500 | throw bignum_error("CBigNum::operator% : BN_div failed"); | ||
| 501 | return r; | ||
| 502 | } | ||
| 503 | |||
| 504 | inline const CBigNum operator<<(const CBigNum& a, unsigned int shift) | ||
| 505 | { | ||
| 506 | CBigNum r; | ||
| 507 | if (!BN_lshift(r.bn, a.bn, shift)) | ||
| 508 | throw bignum_error("CBigNum:operator<< : BN_lshift failed"); | ||
| 509 | return r; | ||
| 510 | } | ||
| 511 | |||
| 512 | inline const CBigNum operator>>(const CBigNum& a, unsigned int shift) | ||
| 513 | { | ||
| 514 | CBigNum r; | ||
| 515 | if (!BN_rshift(r.bn, a.bn, shift)) | ||
| 516 | throw bignum_error("CBigNum:operator>> : BN_rshift failed"); | ||
| 517 | return r; | ||
| 518 | } | ||
| 519 | |||
| 520 | inline bool operator==(const CBigNum& a, const CBigNum& b) { return (BN_cmp(a.bn, b.bn) == 0); } | ||
| 521 | inline bool operator!=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(a.bn, b.bn) != 0); } | ||
| 522 | inline bool operator<=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(a.bn, b.bn) <= 0); } | ||
| 523 | inline bool operator>=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(a.bn, b.bn) >= 0); } | ||
| 524 | inline bool operator<(const CBigNum& a, const CBigNum& b) { return (BN_cmp(a.bn, b.bn) < 0); } | ||
| 525 | inline bool operator>(const CBigNum& a, const CBigNum& b) { return (BN_cmp(a.bn, b.bn) > 0); } | ||
diff --git a/src/bitflashd.cpp b/src/bitflashd.cpp new file mode 100644 index 0000000..d4ced77 --- /dev/null +++ b/src/bitflashd.cpp | |||
| @@ -0,0 +1,45 @@ | |||
| 1 | // Copyright (c) 2026 Bitflash developers | ||
| 2 | // Distributed under the MIT/X11 software license. | ||
| 3 | // | ||
| 4 | // bitflashd -- the headless Bitflash rendezvous relay (the "meeting node"). | ||
| 5 | // Runs on a machine with a public IP (a cheap VPS) and lets nodes behind CGNAT | ||
| 6 | // reach each other: both sides connect OUT to this relay, which pairs them by | ||
| 7 | // `.btf` pubkey and forwards ciphertext (it holds no keys and reads nothing). | ||
| 8 | // | ||
| 9 | // Build on the VPS (Linux): | ||
| 10 | // g++ -std=gnu++14 -O2 -pthread bitflashd.cpp btfrv.cpp -o bitflashd | ||
| 11 | // Run: | ||
| 12 | // ./bitflashd 8434 # or any port you open in the firewall | ||
| 13 | // | ||
| 14 | // Cross-builds unchanged on Windows (for local testing): | ||
| 15 | // g++ -std=gnu++14 -O2 -pthread bitflashd.cpp btfrv.cpp -lws2_32 -o bitflashd.exe | ||
| 16 | |||
| 17 | #include "btfrv.h" | ||
| 18 | #include <cstdio> | ||
| 19 | #include <cstdlib> | ||
| 20 | #include <cstring> | ||
| 21 | |||
| 22 | int main(int argc, char* argv[]) | ||
| 23 | { | ||
| 24 | unsigned short port = 8434; | ||
| 25 | if (argc >= 2) | ||
| 26 | port = (unsigned short)atoi(argv[1]); | ||
| 27 | |||
| 28 | printf("bitflashd -- Bitflash rendezvous relay\n"); | ||
| 29 | printf("listening on 0.0.0.0:%u (open this port in your firewall)\n", port); | ||
| 30 | fflush(stdout); | ||
| 31 | |||
| 32 | if (!btf::RvInit()) | ||
| 33 | { | ||
| 34 | fprintf(stderr, "bitflashd: socket init failed\n"); | ||
| 35 | return 1; | ||
| 36 | } | ||
| 37 | |||
| 38 | // Blocks forever, forwarding between paired peers. | ||
| 39 | if (!btf::RvRelayRun(port)) | ||
| 40 | { | ||
| 41 | fprintf(stderr, "bitflashd: could not bind/listen on port %u\n", port); | ||
| 42 | return 1; | ||
| 43 | } | ||
| 44 | return 0; | ||
| 45 | } | ||
diff --git a/src/btfaddr.cpp b/src/btfaddr.cpp new file mode 100644 index 0000000..5f983bc --- /dev/null +++ b/src/btfaddr.cpp | |||
| @@ -0,0 +1,248 @@ | |||
| 1 | // Copyright (c) 2026 Bitflash developers | ||
| 2 | // Distributed under the MIT/X11 software license. | ||
| 3 | // | ||
| 4 | // Bitflash `.btf` self-certifying addresses + service descriptors. | ||
| 5 | // Ported from the Itzal hidden.rs design. See btfaddr.h. | ||
| 6 | |||
| 7 | #include "btfaddr.h" | ||
| 8 | |||
| 9 | #include <openssl/sha.h> | ||
| 10 | #define SECP256K1_STATIC | ||
| 11 | #include <secp256k1.h> | ||
| 12 | #include <secp256k1_schnorrsig.h> | ||
| 13 | #include <secp256k1_extrakeys.h> | ||
| 14 | #include <nlohmann/json.hpp> | ||
| 15 | |||
| 16 | #include <cstring> | ||
| 17 | #include <algorithm> | ||
| 18 | #include <cctype> | ||
| 19 | |||
| 20 | using json = nlohmann::json; | ||
| 21 | |||
| 22 | namespace btf | ||
| 23 | { | ||
| 24 | |||
| 25 | const char* TLD = ".btf"; | ||
| 26 | |||
| 27 | static const char* B32 = "abcdefghijklmnopqrstuvwxyz234567"; | ||
| 28 | |||
| 29 | std::string Base32Encode(const unsigned char* data, size_t n) | ||
| 30 | { | ||
| 31 | std::string out; | ||
| 32 | out.reserve(n * 8 / 5 + 1); | ||
| 33 | uint64_t buf = 0; | ||
| 34 | uint32_t bits = 0; | ||
| 35 | for (size_t i = 0; i < n; i++) | ||
| 36 | { | ||
| 37 | buf = (buf << 8) | data[i]; | ||
| 38 | bits += 8; | ||
| 39 | while (bits >= 5) | ||
| 40 | { | ||
| 41 | bits -= 5; | ||
| 42 | out.push_back(B32[(buf >> bits) & 0x1f]); | ||
| 43 | } | ||
| 44 | buf &= (bits == 0) ? 0 : ((1ULL << bits) - 1); | ||
| 45 | } | ||
| 46 | if (bits > 0) | ||
| 47 | out.push_back(B32[(buf << (5 - bits)) & 0x1f]); | ||
| 48 | return out; | ||
| 49 | } | ||
| 50 | |||
| 51 | bool Base32Decode(const std::string& s, std::vector<unsigned char>& out) | ||
| 52 | { | ||
| 53 | out.clear(); | ||
| 54 | out.reserve(s.size() * 5 / 8); | ||
| 55 | uint64_t buf = 0; | ||
| 56 | uint32_t bits = 0; | ||
| 57 | for (unsigned char c : s) | ||
| 58 | { | ||
| 59 | uint64_t val; | ||
| 60 | if (c >= 'a' && c <= 'z') val = c - 'a'; | ||
| 61 | else if (c >= 'A' && c <= 'Z') val = c - 'A'; | ||
| 62 | else if (c >= '2' && c <= '7') val = c - '2' + 26; | ||
| 63 | else return false; | ||
| 64 | buf = (buf << 5) | val; | ||
| 65 | bits += 5; | ||
| 66 | if (bits >= 8) | ||
| 67 | { | ||
| 68 | bits -= 8; | ||
| 69 | out.push_back((unsigned char)((buf >> bits) & 0xff)); | ||
| 70 | } | ||
| 71 | buf &= (bits == 0) ? 0 : ((1ULL << bits) - 1); | ||
| 72 | } | ||
| 73 | return true; | ||
| 74 | } | ||
| 75 | |||
| 76 | static std::string ToLowerTrim(const std::string& in) | ||
| 77 | { | ||
| 78 | std::string s = in; | ||
| 79 | // trim whitespace | ||
| 80 | size_t a = s.find_first_not_of(" \t\r\n"); | ||
| 81 | size_t b = s.find_last_not_of(" \t\r\n"); | ||
| 82 | if (a == std::string::npos) return std::string(); | ||
| 83 | s = s.substr(a, b - a + 1); | ||
| 84 | // strip trailing dots (fully-qualified hostname form) | ||
| 85 | while (!s.empty() && s.back() == '.') s.pop_back(); | ||
| 86 | for (char& c : s) c = (char)std::tolower((unsigned char)c); | ||
| 87 | return s; | ||
| 88 | } | ||
| 89 | |||
| 90 | // Two-byte checksum, domain-separated so it can't collide with any other hash use. | ||
| 91 | static void Checksum(const unsigned char pubkey[32], unsigned char out[2]) | ||
| 92 | { | ||
| 93 | static const char* DS = ".btf-checksum-v1"; | ||
| 94 | SHA256_CTX ctx; | ||
| 95 | SHA256_Init(&ctx); | ||
| 96 | SHA256_Update(&ctx, (const unsigned char*)DS, strlen(DS)); | ||
| 97 | SHA256_Update(&ctx, pubkey, 32); | ||
| 98 | unsigned char d[32]; | ||
| 99 | SHA256_Final(d, &ctx); | ||
| 100 | out[0] = d[0]; | ||
| 101 | out[1] = d[1]; | ||
| 102 | } | ||
| 103 | |||
| 104 | std::string Address(const unsigned char pubkey[32]) | ||
| 105 | { | ||
| 106 | unsigned char raw[34]; | ||
| 107 | memcpy(raw, pubkey, 32); | ||
| 108 | Checksum(pubkey, raw + 32); | ||
| 109 | return Base32Encode(raw, 34) + TLD; | ||
| 110 | } | ||
| 111 | |||
| 112 | bool IsBtf(const std::string& host) | ||
| 113 | { | ||
| 114 | std::string s = ToLowerTrim(host); | ||
| 115 | std::string tld = TLD; | ||
| 116 | if (s.size() < tld.size()) return false; | ||
| 117 | return s.compare(s.size() - tld.size(), tld.size(), tld) == 0; | ||
| 118 | } | ||
| 119 | |||
| 120 | bool ParseAddress(const std::string& addr, unsigned char pubkeyOut[32]) | ||
| 121 | { | ||
| 122 | std::string s = ToLowerTrim(addr); | ||
| 123 | std::string tld = TLD; | ||
| 124 | if (s.size() < tld.size()) return false; | ||
| 125 | if (s.compare(s.size() - tld.size(), tld.size(), tld) != 0) return false; | ||
| 126 | std::string label = s.substr(0, s.size() - tld.size()); | ||
| 127 | |||
| 128 | std::vector<unsigned char> raw; | ||
| 129 | if (!Base32Decode(label, raw)) return false; | ||
| 130 | if (raw.size() < 34) return false; | ||
| 131 | |||
| 132 | unsigned char pk[32]; | ||
| 133 | memcpy(pk, &raw[0], 32); | ||
| 134 | unsigned char sum[2]; | ||
| 135 | Checksum(pk, sum); | ||
| 136 | if (raw[32] != sum[0] || raw[33] != sum[1]) return false; | ||
| 137 | |||
| 138 | memcpy(pubkeyOut, pk, 32); | ||
| 139 | return true; | ||
| 140 | } | ||
| 141 | |||
| 142 | |||
| 143 | // ---- descriptor ------------------------------------------------------------ | ||
| 144 | |||
| 145 | static std::string HexEncode(const unsigned char* p, size_t n) | ||
| 146 | { | ||
| 147 | static const char* h = "0123456789abcdef"; | ||
| 148 | std::string s; | ||
| 149 | s.reserve(n * 2); | ||
| 150 | for (size_t i = 0; i < n; i++) { s += h[p[i] >> 4]; s += h[p[i] & 0xf]; } | ||
| 151 | return s; | ||
| 152 | } | ||
| 153 | |||
| 154 | static bool HexDecode(const std::string& s, unsigned char* out, size_t n) | ||
| 155 | { | ||
| 156 | if (s.size() != n * 2) return false; | ||
| 157 | for (size_t i = 0; i < n; i++) | ||
| 158 | { | ||
| 159 | unsigned int b; | ||
| 160 | if (sscanf(s.c_str() + i * 2, "%2x", &b) != 1) return false; | ||
| 161 | out[i] = (unsigned char)b; | ||
| 162 | } | ||
| 163 | return true; | ||
| 164 | } | ||
| 165 | |||
| 166 | // Digest signed over the descriptor fields (domain-separated). | ||
| 167 | static void DescriptorDigest(const unsigned char pubkey[32], const std::string& enc, | ||
| 168 | const std::string& meeting_node, uint64_t created, | ||
| 169 | unsigned char out[32]) | ||
| 170 | { | ||
| 171 | static const char* DS = ".btf-descriptor-v2"; | ||
| 172 | SHA256_CTX ctx; | ||
| 173 | SHA256_Init(&ctx); | ||
| 174 | SHA256_Update(&ctx, (const unsigned char*)DS, strlen(DS)); | ||
| 175 | SHA256_Update(&ctx, pubkey, 32); | ||
| 176 | SHA256_Update(&ctx, (const unsigned char*)enc.data(), enc.size()); | ||
| 177 | SHA256_Update(&ctx, (const unsigned char*)meeting_node.data(), meeting_node.size()); | ||
| 178 | unsigned char be[8]; | ||
| 179 | for (int i = 0; i < 8; i++) be[i] = (unsigned char)((created >> (8 * (7 - i))) & 0xff); | ||
| 180 | SHA256_Update(&ctx, be, 8); | ||
| 181 | SHA256_Final(out, &ctx); | ||
| 182 | } | ||
| 183 | |||
| 184 | std::string SignDescriptor(void* ctxv, const unsigned char seckey[32], | ||
| 185 | const std::string& enc, const std::string& meeting_node, | ||
| 186 | uint64_t created) | ||
| 187 | { | ||
| 188 | secp256k1_context* ctx = (secp256k1_context*)ctxv; | ||
| 189 | secp256k1_keypair kp; | ||
| 190 | if (!secp256k1_keypair_create(ctx, &kp, seckey)) return std::string(); | ||
| 191 | secp256k1_xonly_pubkey xpub; | ||
| 192 | if (!secp256k1_keypair_xonly_pub(ctx, &xpub, NULL, &kp)) return std::string(); | ||
| 193 | unsigned char pubkey[32]; | ||
| 194 | secp256k1_xonly_pubkey_serialize(ctx, pubkey, &xpub); | ||
| 195 | |||
| 196 | unsigned char digest[32]; | ||
| 197 | DescriptorDigest(pubkey, enc, meeting_node, created, digest); | ||
| 198 | |||
| 199 | unsigned char sig[64]; | ||
| 200 | // Deterministic signature (NULL aux_rand), matching Itzal's no-aux-rand signing. | ||
| 201 | if (!secp256k1_schnorrsig_sign32(ctx, sig, digest, &kp, NULL)) return std::string(); | ||
| 202 | |||
| 203 | json v = json::object(); | ||
| 204 | v["v"] = 2; | ||
| 205 | v["pubkey"] = HexEncode(pubkey, 32); | ||
| 206 | v["enc"] = enc; | ||
| 207 | v["meeting_node"] = meeting_node; | ||
| 208 | v["created"] = created; | ||
| 209 | v["sig"] = HexEncode(sig, 64); | ||
| 210 | return v.dump(); | ||
| 211 | } | ||
| 212 | |||
| 213 | bool VerifyDescriptor(void* ctxv, const std::string& jsonStr, | ||
| 214 | const unsigned char expect_pubkey[32], Descriptor& out) | ||
| 215 | { | ||
| 216 | secp256k1_context* ctx = (secp256k1_context*)ctxv; | ||
| 217 | json v; | ||
| 218 | try { v = json::parse(jsonStr); } catch (...) { return false; } | ||
| 219 | if (!v.is_object()) return false; | ||
| 220 | if (!v.contains("pubkey") || !v.contains("enc") || !v.contains("meeting_node") | ||
| 221 | || !v.contains("created") || !v.contains("sig")) return false; | ||
| 222 | |||
| 223 | unsigned char pubkey[32]; | ||
| 224 | if (!HexDecode(v["pubkey"].get<std::string>(), pubkey, 32)) return false; | ||
| 225 | if (memcmp(pubkey, expect_pubkey, 32) != 0) return false; // descriptor is for a different key | ||
| 226 | |||
| 227 | std::string enc = v["enc"].get<std::string>(); | ||
| 228 | std::string meeting_node = v["meeting_node"].get<std::string>(); | ||
| 229 | uint64_t created = v["created"].get<uint64_t>(); | ||
| 230 | |||
| 231 | unsigned char sig[64]; | ||
| 232 | if (!HexDecode(v["sig"].get<std::string>(), sig, 64)) return false; | ||
| 233 | |||
| 234 | unsigned char digest[32]; | ||
| 235 | DescriptorDigest(expect_pubkey, enc, meeting_node, created, digest); | ||
| 236 | |||
| 237 | secp256k1_xonly_pubkey xpub; | ||
| 238 | if (!secp256k1_xonly_pubkey_parse(ctx, &xpub, expect_pubkey)) return false; | ||
| 239 | if (!secp256k1_schnorrsig_verify(ctx, sig, digest, 32, &xpub)) return false; | ||
| 240 | |||
| 241 | memcpy(out.pubkey, expect_pubkey, 32); | ||
| 242 | out.enc = enc; | ||
| 243 | out.meeting_node = meeting_node; | ||
| 244 | out.created = created; | ||
| 245 | return true; | ||
| 246 | } | ||
| 247 | |||
| 248 | } // namespace btf | ||
diff --git a/src/btfaddr.h b/src/btfaddr.h new file mode 100644 index 0000000..1addf8f --- /dev/null +++ b/src/btfaddr.h | |||
| @@ -0,0 +1,72 @@ | |||
| 1 | // Copyright (c) 2026 Bitflash developers | ||
| 2 | // Distributed under the MIT/X11 software license. | ||
| 3 | // | ||
| 4 | // Bitflash hidden services -- self-certifying `.btf` addresses (a Tor `.onion` | ||
| 5 | // analogue, ported from the Itzal design). An address IS the service's public | ||
| 6 | // key: base32(pubkey[32] || checksum[2]).btf, derived from the owner's | ||
| 7 | // secp256k1 x-only key, so it cannot be forged (no CA, no DNS). Resolving it | ||
| 8 | // means proving a descriptor is signed by exactly this key. | ||
| 9 | // | ||
| 10 | // This is the ADDRESS + DESCRIPTOR layer. Reachability (rendezvous over the | ||
| 11 | // embedded Nostr relays so the origin IP is never exposed) builds on top. | ||
| 12 | |||
| 13 | #ifndef BITFLASH_BTFADDR_H | ||
| 14 | #define BITFLASH_BTFADDR_H | ||
| 15 | |||
| 16 | #include <string> | ||
| 17 | #include <vector> | ||
| 18 | #include <stdint.h> | ||
| 19 | |||
| 20 | namespace btf | ||
| 21 | { | ||
| 22 | |||
| 23 | // Pseudo-TLD, resolved inside the Bitflash client, never by real DNS. | ||
| 24 | extern const char* TLD; // ".btf" | ||
| 25 | |||
| 26 | // RFC 4648 base32, lowercase, no padding (case-insensitive hostname label). | ||
| 27 | std::string Base32Encode(const unsigned char* data, size_t n); | ||
| 28 | bool Base32Decode(const std::string& s, std::vector<unsigned char>& out); | ||
| 29 | |||
| 30 | // Derive the `.btf` address for a 32-byte x-only public key. | ||
| 31 | std::string Address(const unsigned char pubkey[32]); | ||
| 32 | |||
| 33 | // True if a hostname is a `.btf` address (case-insensitive, optional trailing dot). | ||
| 34 | bool IsBtf(const std::string& host); | ||
| 35 | |||
| 36 | // Parse a `.btf` address back to its 32-byte public key, verifying the checksum. | ||
| 37 | // Returns false if the label isn't valid base32, is too short, or checksum fails. | ||
| 38 | bool ParseAddress(const std::string& addr, unsigned char pubkeyOut[32]); | ||
| 39 | |||
| 40 | |||
| 41 | // ---- Service descriptor (published later on Nostr) ------------------------- | ||
| 42 | // | ||
| 43 | // A descriptor tells a client how to REACH a service after resolving its | ||
| 44 | // address: "service <pubkey> is reachable via <meeting_node>, encrypt end-to-end | ||
| 45 | // to my x25519 key <enc>". It is signed by the service key and self-certifying: | ||
| 46 | // the client requires the signature to verify under the exact pubkey the | ||
| 47 | // address decodes to, so nobody can publish a descriptor for an address they | ||
| 48 | // don't own (no hijacking, even via a malicious relay). | ||
| 49 | |||
| 50 | struct Descriptor | ||
| 51 | { | ||
| 52 | unsigned char pubkey[32]; | ||
| 53 | std::string enc; // service x25519 public key (hex) for the E2E channel | ||
| 54 | std::string meeting_node; // rendezvous node the service is registered at | ||
| 55 | uint64_t created; | ||
| 56 | }; | ||
| 57 | |||
| 58 | // Sign a descriptor. `ctx` is a secp256k1_context* (passed as void* to keep this | ||
| 59 | // header free of secp headers); `seckey` is the 32-byte service secret key. | ||
| 60 | // Returns the descriptor JSON as a string, or "" on failure. | ||
| 61 | std::string SignDescriptor(void* ctx, const unsigned char seckey[32], | ||
| 62 | const std::string& enc, const std::string& meeting_node, | ||
| 63 | uint64_t created); | ||
| 64 | |||
| 65 | // Verify a descriptor is validly signed by `expect_pubkey` (the key the resolved | ||
| 66 | // `.btf` address encodes). Returns true and fills `out` on success. | ||
| 67 | bool VerifyDescriptor(void* ctx, const std::string& jsonStr, | ||
| 68 | const unsigned char expect_pubkey[32], Descriptor& out); | ||
| 69 | |||
| 70 | } // namespace btf | ||
| 71 | |||
| 72 | #endif | ||
diff --git a/src/btfchan.cpp b/src/btfchan.cpp new file mode 100644 index 0000000..09aaaad --- /dev/null +++ b/src/btfchan.cpp | |||
| @@ -0,0 +1,94 @@ | |||
| 1 | // Copyright (c) 2026 Bitflash developers | ||
| 2 | // Distributed under the MIT/X11 software license. | ||
| 3 | // | ||
| 4 | // Bitflash end-to-end encrypted channel. Ported from Itzal echan.rs. | ||
| 5 | // Uses libsodium crypto_box_curve25519xchacha20poly1305 (X25519 + XChaCha20-Poly1305), | ||
| 6 | // the same primitive as Rust's crypto_box ChaChaBox. | ||
| 7 | |||
| 8 | #include "btfchan.h" | ||
| 9 | #include <sodium.h> | ||
| 10 | #include <cstring> | ||
| 11 | |||
| 12 | namespace btf | ||
| 13 | { | ||
| 14 | |||
| 15 | // Compile-time sanity: our constants match libsodium's. | ||
| 16 | static_assert(CHAN_NONCEBYTES == crypto_box_curve25519xchacha20poly1305_NONCEBYTES, "nonce"); | ||
| 17 | static_assert(CHAN_MACBYTES == crypto_box_curve25519xchacha20poly1305_MACBYTES, "mac"); | ||
| 18 | static_assert(CHAN_KEYBYTES == crypto_box_curve25519xchacha20poly1305_BEFORENMBYTES, "key"); | ||
| 19 | |||
| 20 | bool ChanInit() | ||
| 21 | { | ||
| 22 | return sodium_init() >= 0; | ||
| 23 | } | ||
| 24 | |||
| 25 | void ChanKeypair(unsigned char pk[32], unsigned char sk[32]) | ||
| 26 | { | ||
| 27 | crypto_box_curve25519xchacha20poly1305_keypair(pk, sk); | ||
| 28 | } | ||
| 29 | |||
| 30 | void ChanPublicFromSecret(unsigned char pk[32], const unsigned char sk[32]) | ||
| 31 | { | ||
| 32 | // X25519 public = scalarmult of the secret with the curve25519 base point. | ||
| 33 | crypto_scalarmult_base(pk, sk); | ||
| 34 | } | ||
| 35 | |||
| 36 | bool ChanClientHandshake(const unsigned char endpoint_static_pub[32], | ||
| 37 | unsigned char eph_pub_out[32], unsigned char shared_out[32]) | ||
| 38 | { | ||
| 39 | unsigned char eph_sk[32]; | ||
| 40 | crypto_box_curve25519xchacha20poly1305_keypair(eph_pub_out, eph_sk); | ||
| 41 | // shared = X25519(eph_sk, endpoint_static_pub) -> hashed to a box key | ||
| 42 | int r = crypto_box_curve25519xchacha20poly1305_beforenm(shared_out, endpoint_static_pub, eph_sk); | ||
| 43 | sodium_memzero(eph_sk, sizeof(eph_sk)); | ||
| 44 | return r == 0; | ||
| 45 | } | ||
| 46 | |||
| 47 | bool ChanEndpointHandshake(const unsigned char client_eph_pub[32], | ||
| 48 | const unsigned char my_static_sk[32], unsigned char shared_out[32]) | ||
| 49 | { | ||
| 50 | // shared = X25519(my_static_sk, client_eph_pub) -> same box key as the client computed | ||
| 51 | return crypto_box_curve25519xchacha20poly1305_beforenm(shared_out, client_eph_pub, my_static_sk) == 0; | ||
| 52 | } | ||
| 53 | |||
| 54 | std::vector<unsigned char> ChanEncryptFrame(const unsigned char shared[32], | ||
| 55 | const unsigned char* pt, size_t n) | ||
| 56 | { | ||
| 57 | unsigned char nonce[CHAN_NONCEBYTES]; | ||
| 58 | randombytes_buf(nonce, sizeof(nonce)); | ||
| 59 | |||
| 60 | size_t ctlen = n + CHAN_MACBYTES; | ||
| 61 | size_t bodylen = CHAN_NONCEBYTES + ctlen; | ||
| 62 | |||
| 63 | std::vector<unsigned char> out(4 + bodylen); | ||
| 64 | out[0] = (unsigned char)((bodylen >> 24) & 0xff); | ||
| 65 | out[1] = (unsigned char)((bodylen >> 16) & 0xff); | ||
| 66 | out[2] = (unsigned char)((bodylen >> 8) & 0xff); | ||
| 67 | out[3] = (unsigned char)(bodylen & 0xff); | ||
| 68 | memcpy(&out[4], nonce, CHAN_NONCEBYTES); | ||
| 69 | |||
| 70 | crypto_box_curve25519xchacha20poly1305_easy_afternm( | ||
| 71 | &out[4 + CHAN_NONCEBYTES], pt, n, nonce, shared); | ||
| 72 | return out; | ||
| 73 | } | ||
| 74 | |||
| 75 | bool ChanDecryptBody(const unsigned char shared[32], | ||
| 76 | const unsigned char* body, size_t n, std::vector<unsigned char>& out) | ||
| 77 | { | ||
| 78 | if (n < (size_t)(CHAN_NONCEBYTES + CHAN_MACBYTES)) | ||
| 79 | return false; | ||
| 80 | const unsigned char* nonce = body; | ||
| 81 | const unsigned char* ct = body + CHAN_NONCEBYTES; | ||
| 82 | size_t ctlen = n - CHAN_NONCEBYTES; | ||
| 83 | out.resize(ctlen - CHAN_MACBYTES); | ||
| 84 | int r = crypto_box_curve25519xchacha20poly1305_open_easy_afternm( | ||
| 85 | out.empty() ? NULL : &out[0], ct, ctlen, nonce, shared); | ||
| 86 | if (r != 0) | ||
| 87 | { | ||
| 88 | out.clear(); | ||
| 89 | return false; | ||
| 90 | } | ||
| 91 | return true; | ||
| 92 | } | ||
| 93 | |||
| 94 | } // namespace btf | ||
diff --git a/src/btfchan.h b/src/btfchan.h new file mode 100644 index 0000000..7963f9d --- /dev/null +++ b/src/btfchan.h | |||
| @@ -0,0 +1,59 @@ | |||
| 1 | // Copyright (c) 2026 Bitflash developers | ||
| 2 | // Distributed under the MIT/X11 software license. | ||
| 3 | // | ||
| 4 | // End-to-end encrypted channel for Bitflash (ported from the Itzal echan.rs). | ||
| 5 | // Wraps a raw pipe in an authenticated stream so relays/rendezvous nodes see | ||
| 6 | // only ciphertext and cannot MITM: only the endpoint holding the static secret | ||
| 7 | // can derive the key. | ||
| 8 | // | ||
| 9 | // Handshake: the client makes an ephemeral X25519 key and sends its public half | ||
| 10 | // to the endpoint. Both sides compute the same box (X25519 ECDH -> shared key | ||
| 11 | // for XChaCha20-Poly1305, i.e. libsodium crypto_box). Wire frame: | ||
| 12 | // [len:4 BE][nonce:24][ciphertext || 16-byte tag] | ||
| 13 | // with a fresh random 24-byte nonce per frame (safe to pick at random). | ||
| 14 | |||
| 15 | #ifndef BITFLASH_BTFCHAN_H | ||
| 16 | #define BITFLASH_BTFCHAN_H | ||
| 17 | |||
| 18 | #include <vector> | ||
| 19 | #include <stdint.h> | ||
| 20 | #include <stddef.h> | ||
| 21 | |||
| 22 | namespace btf | ||
| 23 | { | ||
| 24 | |||
| 25 | static const int CHAN_KEYBYTES = 32; // X25519 public/secret and shared key | ||
| 26 | static const int CHAN_NONCEBYTES = 24; // XChaCha20-Poly1305 nonce | ||
| 27 | static const int CHAN_MACBYTES = 16; // Poly1305 tag | ||
| 28 | |||
| 29 | // Must be called once before any channel use (initializes libsodium). Idempotent. | ||
| 30 | bool ChanInit(); | ||
| 31 | |||
| 32 | // Generate a static X25519 keypair (e.g. the endpoint's long-term key). | ||
| 33 | void ChanKeypair(unsigned char pk[32], unsigned char sk[32]); | ||
| 34 | |||
| 35 | // Derive the X25519 public key from a stored secret key (X25519 base mult). | ||
| 36 | void ChanPublicFromSecret(unsigned char pk[32], const unsigned char sk[32]); | ||
| 37 | |||
| 38 | // Client side: given the endpoint's static public key, produce an ephemeral | ||
| 39 | // public key (to hand the endpoint) and the shared key. Returns false on error. | ||
| 40 | bool ChanClientHandshake(const unsigned char endpoint_static_pub[32], | ||
| 41 | unsigned char eph_pub_out[32], unsigned char shared_out[32]); | ||
| 42 | |||
| 43 | // Endpoint side: rebuild the same shared key from the client's ephemeral public | ||
| 44 | // key and my static secret. Only the static-secret holder can do this. | ||
| 45 | bool ChanEndpointHandshake(const unsigned char client_eph_pub[32], | ||
| 46 | const unsigned char my_static_sk[32], unsigned char shared_out[32]); | ||
| 47 | |||
| 48 | // Encrypt a plaintext chunk into a full wire frame ([len][nonce][ct||tag]). | ||
| 49 | std::vector<unsigned char> ChanEncryptFrame(const unsigned char shared[32], | ||
| 50 | const unsigned char* pt, size_t n); | ||
| 51 | |||
| 52 | // Decrypt a frame BODY (nonce||ciphertext||tag, i.e. without the 4-byte length | ||
| 53 | // prefix). Returns true and fills `out` on success; false on auth failure. | ||
| 54 | bool ChanDecryptBody(const unsigned char shared[32], | ||
| 55 | const unsigned char* body, size_t n, std::vector<unsigned char>& out); | ||
| 56 | |||
| 57 | } // namespace btf | ||
| 58 | |||
| 59 | #endif | ||
diff --git a/src/btfrv.cpp b/src/btfrv.cpp new file mode 100644 index 0000000..ffda08c --- /dev/null +++ b/src/btfrv.cpp | |||
| @@ -0,0 +1,250 @@ | |||
| 1 | // Copyright (c) 2026 Bitflash developers | ||
| 2 | // Distributed under the MIT/X11 software license. | ||
| 3 | // | ||
| 4 | // Bitflash rendezvous transport. See btfrv.h. | ||
| 5 | // Windows/Winsock implementation (Layer 6 will #ifdef this for Linux/BSD sockets). | ||
| 6 | |||
| 7 | #include "btfrv.h" | ||
| 8 | |||
| 9 | // Portable sockets: Winsock on Windows, BSD sockets on Linux/POSIX (for the | ||
| 10 | // headless relay `bitflashd` that runs on the VPS). | ||
| 11 | #ifdef _WIN32 | ||
| 12 | #include <winsock2.h> | ||
| 13 | #include <ws2tcpip.h> | ||
| 14 | #define CLOSESOCK closesocket | ||
| 15 | #else | ||
| 16 | #include <sys/socket.h> | ||
| 17 | #include <netinet/in.h> | ||
| 18 | #include <arpa/inet.h> | ||
| 19 | #include <netdb.h> | ||
| 20 | #include <unistd.h> | ||
| 21 | #include <csignal> | ||
| 22 | typedef int SOCKET; | ||
| 23 | #define INVALID_SOCKET (-1) | ||
| 24 | #define SOCKET_ERROR (-1) | ||
| 25 | #define CLOSESOCK ::close | ||
| 26 | #ifndef SD_BOTH | ||
| 27 | #define SD_BOTH SHUT_RDWR | ||
| 28 | #endif | ||
| 29 | #endif | ||
| 30 | |||
| 31 | #include <cstring> | ||
| 32 | #include <cstdio> | ||
| 33 | #include <string> | ||
| 34 | #include <map> | ||
| 35 | #include <thread> | ||
| 36 | #include <mutex> | ||
| 37 | #include <atomic> | ||
| 38 | |||
| 39 | namespace btf | ||
| 40 | { | ||
| 41 | |||
| 42 | static std::atomic<bool> g_stop(false); | ||
| 43 | static SOCKET g_listen = INVALID_SOCKET; | ||
| 44 | |||
| 45 | // Services that have registered and are waiting for a client, keyed by pubkey. | ||
| 46 | static std::map<std::string, SOCKET> g_waiting; | ||
| 47 | static std::mutex g_mtx; | ||
| 48 | |||
| 49 | bool RvInit() | ||
| 50 | { | ||
| 51 | static bool done = false; | ||
| 52 | if (done) return true; | ||
| 53 | #ifdef _WIN32 | ||
| 54 | WSADATA wsa; | ||
| 55 | if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) return false; | ||
| 56 | #else | ||
| 57 | signal(SIGPIPE, SIG_IGN); // don't die when writing to a closed peer | ||
| 58 | #endif | ||
| 59 | done = true; | ||
| 60 | return true; | ||
| 61 | } | ||
| 62 | |||
| 63 | // ---- low-level helpers ---- | ||
| 64 | |||
| 65 | static bool ReadN(SOCKET s, void* buf, int n) | ||
| 66 | { | ||
| 67 | char* p = (char*)buf; | ||
| 68 | int off = 0; | ||
| 69 | while (off < n) | ||
| 70 | { | ||
| 71 | int r = recv(s, p + off, n - off, 0); | ||
| 72 | if (r <= 0) return false; | ||
| 73 | off += r; | ||
| 74 | } | ||
| 75 | return true; | ||
| 76 | } | ||
| 77 | |||
| 78 | static bool WriteN(SOCKET s, const void* buf, int n) | ||
| 79 | { | ||
| 80 | const char* p = (const char*)buf; | ||
| 81 | int off = 0; | ||
| 82 | while (off < n) | ||
| 83 | { | ||
| 84 | int r = send(s, p + off, n - off, 0); | ||
| 85 | if (r <= 0) return false; | ||
| 86 | off += r; | ||
| 87 | } | ||
| 88 | return true; | ||
| 89 | } | ||
| 90 | |||
| 91 | static SOCKET ConnectTo(const char* host, unsigned short port) | ||
| 92 | { | ||
| 93 | struct addrinfo hints, *res = NULL; | ||
| 94 | memset(&hints, 0, sizeof(hints)); | ||
| 95 | hints.ai_family = AF_INET; | ||
| 96 | hints.ai_socktype = SOCK_STREAM; | ||
| 97 | char portstr[16]; sprintf(portstr, "%u", (unsigned)port); | ||
| 98 | if (getaddrinfo(host, portstr, &hints, &res) != 0 || !res) return INVALID_SOCKET; | ||
| 99 | SOCKET s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); | ||
| 100 | if (s == INVALID_SOCKET) { freeaddrinfo(res); return INVALID_SOCKET; } | ||
| 101 | if (connect(s, res->ai_addr, (int)res->ai_addrlen) != 0) | ||
| 102 | { | ||
| 103 | CLOSESOCK(s); freeaddrinfo(res); return INVALID_SOCKET; | ||
| 104 | } | ||
| 105 | freeaddrinfo(res); | ||
| 106 | return s; | ||
| 107 | } | ||
| 108 | |||
| 109 | // ---- relay side ---- | ||
| 110 | |||
| 111 | // Pump bytes from `from` to `to`. Owns closing `from`; shuts down `to` on exit | ||
| 112 | // so the peer-direction thread unblocks and closes its own socket exactly once. | ||
| 113 | static void Forward(SOCKET from, SOCKET to) | ||
| 114 | { | ||
| 115 | char buf[32 * 1024]; | ||
| 116 | for (;;) | ||
| 117 | { | ||
| 118 | int r = recv(from, buf, sizeof(buf), 0); | ||
| 119 | if (r <= 0) break; | ||
| 120 | if (!WriteN(to, buf, r)) break; | ||
| 121 | } | ||
| 122 | shutdown(to, SD_BOTH); | ||
| 123 | CLOSESOCK(from); | ||
| 124 | } | ||
| 125 | |||
| 126 | static void HandleIncoming(SOCKET s) | ||
| 127 | { | ||
| 128 | unsigned char hdr[33]; | ||
| 129 | if (!ReadN(s, hdr, 33)) { CLOSESOCK(s); return; } | ||
| 130 | char role = (char)hdr[0]; | ||
| 131 | std::string pubkey((char*)hdr + 1, 32); | ||
| 132 | |||
| 133 | if (role == 'S') | ||
| 134 | { | ||
| 135 | // Register and wait; a future client will pair us. | ||
| 136 | std::lock_guard<std::mutex> lk(g_mtx); | ||
| 137 | // If a stale service for this key exists, drop it. | ||
| 138 | std::map<std::string, SOCKET>::iterator it = g_waiting.find(pubkey); | ||
| 139 | if (it != g_waiting.end()) CLOSESOCK(it->second); | ||
| 140 | g_waiting[pubkey] = s; | ||
| 141 | // leave the socket open in the map; do not close here. | ||
| 142 | } | ||
| 143 | else if (role == 'C') | ||
| 144 | { | ||
| 145 | SOCKET svc = INVALID_SOCKET; | ||
| 146 | { | ||
| 147 | std::lock_guard<std::mutex> lk(g_mtx); | ||
| 148 | std::map<std::string, SOCKET>::iterator it = g_waiting.find(pubkey); | ||
| 149 | if (it != g_waiting.end()) { svc = it->second; g_waiting.erase(it); } | ||
| 150 | } | ||
| 151 | if (svc == INVALID_SOCKET) | ||
| 152 | { | ||
| 153 | unsigned char no = 0x00; | ||
| 154 | WriteN(s, &no, 1); | ||
| 155 | CLOSESOCK(s); | ||
| 156 | return; | ||
| 157 | } | ||
| 158 | // Pair: tell both sides, then forward raw bytes bidirectionally. | ||
| 159 | unsigned char ok = 0x01; | ||
| 160 | bool a = WriteN(svc, &ok, 1); | ||
| 161 | bool b = WriteN(s, &ok, 1); | ||
| 162 | if (!a || !b) { CLOSESOCK(svc); CLOSESOCK(s); return; } | ||
| 163 | std::thread(Forward, s, svc).detach(); | ||
| 164 | std::thread(Forward, svc, s).detach(); | ||
| 165 | } | ||
| 166 | else | ||
| 167 | { | ||
| 168 | CLOSESOCK(s); | ||
| 169 | } | ||
| 170 | } | ||
| 171 | |||
| 172 | bool RvRelayRun(unsigned short port) | ||
| 173 | { | ||
| 174 | if (!RvInit()) return false; | ||
| 175 | g_stop = false; | ||
| 176 | |||
| 177 | g_listen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); | ||
| 178 | if (g_listen == INVALID_SOCKET) return false; | ||
| 179 | int yes = 1; | ||
| 180 | setsockopt(g_listen, SOL_SOCKET, SO_REUSEADDR, (char*)&yes, sizeof(yes)); | ||
| 181 | |||
| 182 | struct sockaddr_in addr; | ||
| 183 | memset(&addr, 0, sizeof(addr)); | ||
| 184 | addr.sin_family = AF_INET; | ||
| 185 | addr.sin_addr.s_addr = INADDR_ANY; | ||
| 186 | addr.sin_port = htons(port); | ||
| 187 | if (bind(g_listen, (struct sockaddr*)&addr, sizeof(addr)) != 0) { CLOSESOCK(g_listen); return false; } | ||
| 188 | if (listen(g_listen, 16) != 0) { CLOSESOCK(g_listen); return false; } | ||
| 189 | |||
| 190 | while (!g_stop) | ||
| 191 | { | ||
| 192 | struct sockaddr_in cli; | ||
| 193 | socklen_t len = sizeof(cli); | ||
| 194 | SOCKET s = accept(g_listen, (struct sockaddr*)&cli, &len); | ||
| 195 | if (s == INVALID_SOCKET) | ||
| 196 | { | ||
| 197 | if (g_stop) break; | ||
| 198 | continue; | ||
| 199 | } | ||
| 200 | std::thread(HandleIncoming, s).detach(); | ||
| 201 | } | ||
| 202 | CLOSESOCK(g_listen); | ||
| 203 | g_listen = INVALID_SOCKET; | ||
| 204 | return true; | ||
| 205 | } | ||
| 206 | |||
| 207 | void RvRelayStop() | ||
| 208 | { | ||
| 209 | g_stop = true; | ||
| 210 | if (g_listen != INVALID_SOCKET) | ||
| 211 | CLOSESOCK(g_listen); // unblock accept() | ||
| 212 | } | ||
| 213 | |||
| 214 | // ---- service / client helpers ---- | ||
| 215 | |||
| 216 | RvSocket RvServiceRegister(const char* relay_host, unsigned short port, | ||
| 217 | const unsigned char my_pubkey[32]) | ||
| 218 | { | ||
| 219 | if (!RvInit()) return RV_INVALID; | ||
| 220 | SOCKET s = ConnectTo(relay_host, port); | ||
| 221 | if (s == INVALID_SOCKET) return RV_INVALID; | ||
| 222 | unsigned char hdr[33]; | ||
| 223 | hdr[0] = (unsigned char)'S'; | ||
| 224 | memcpy(hdr + 1, my_pubkey, 32); | ||
| 225 | if (!WriteN(s, hdr, 33)) { CLOSESOCK(s); return RV_INVALID; } | ||
| 226 | unsigned char paired = 0; | ||
| 227 | if (!ReadN(s, &paired, 1) || paired != 0x01) { CLOSESOCK(s); return RV_INVALID; } | ||
| 228 | return (RvSocket)s; | ||
| 229 | } | ||
| 230 | |||
| 231 | RvSocket RvClientConnect(const char* relay_host, unsigned short port, | ||
| 232 | const unsigned char target_pubkey[32]) | ||
| 233 | { | ||
| 234 | if (!RvInit()) return RV_INVALID; | ||
| 235 | SOCKET s = ConnectTo(relay_host, port); | ||
| 236 | if (s == INVALID_SOCKET) return RV_INVALID; | ||
| 237 | unsigned char hdr[33]; | ||
| 238 | hdr[0] = (unsigned char)'C'; | ||
| 239 | memcpy(hdr + 1, target_pubkey, 32); | ||
| 240 | if (!WriteN(s, hdr, 33)) { CLOSESOCK(s); return RV_INVALID; } | ||
| 241 | unsigned char paired = 0; | ||
| 242 | if (!ReadN(s, &paired, 1) || paired != 0x01) { CLOSESOCK(s); return RV_INVALID; } | ||
| 243 | return (RvSocket)s; | ||
| 244 | } | ||
| 245 | |||
| 246 | bool RvReadN(RvSocket s, void* buf, int n) { return ReadN((SOCKET)s, buf, n); } | ||
| 247 | bool RvWriteN(RvSocket s, const void* buf, int n) { return WriteN((SOCKET)s, buf, n); } | ||
| 248 | void RvClose(RvSocket s) { if (s != RV_INVALID) CLOSESOCK((SOCKET)s); } | ||
| 249 | |||
| 250 | } // namespace btf | ||
diff --git a/src/btfrv.h b/src/btfrv.h new file mode 100644 index 0000000..c776201 --- /dev/null +++ b/src/btfrv.h | |||
| @@ -0,0 +1,59 @@ | |||
| 1 | // Copyright (c) 2026 Bitflash developers | ||
| 2 | // Distributed under the MIT/X11 software license. | ||
| 3 | // | ||
| 4 | // Bitflash rendezvous transport -- the "meeting node" that lets two nodes behind | ||
| 5 | // CGNAT connect without a public IP or port forwarding. Both sides connect OUT | ||
| 6 | // to the relay (which HAS a public IP, e.g. the VPS); the relay pairs them by | ||
| 7 | // `.btf` pubkey and forwards raw bytes between them. The endpoints then run the | ||
| 8 | // echan end-to-end channel on top, so the relay sees only ciphertext and cannot | ||
| 9 | // MITM (the client boxes to the service's STATIC key from its self-certified | ||
| 10 | // descriptor -- a substituting relay just breaks the channel, never reads it). | ||
| 11 | // | ||
| 12 | // This is the server that runs on the VPS (headless, Layer 6 ports it to Linux) | ||
| 13 | // plus the client/service helpers the desktop node uses. | ||
| 14 | |||
| 15 | #ifndef BITFLASH_BTFRV_H | ||
| 16 | #define BITFLASH_BTFRV_H | ||
| 17 | |||
| 18 | #include <stdint.h> | ||
| 19 | |||
| 20 | namespace btf | ||
| 21 | { | ||
| 22 | |||
| 23 | // A connected, paired rendezvous socket (opaque). Read/write raw bytes; the | ||
| 24 | // caller layers echan on top. Close with RvClose. | ||
| 25 | typedef intptr_t RvSocket; | ||
| 26 | static const RvSocket RV_INVALID = (RvSocket)-1; | ||
| 27 | |||
| 28 | // Initialize sockets (Winsock on Windows). Idempotent. | ||
| 29 | bool RvInit(); | ||
| 30 | |||
| 31 | // ---- relay side (runs on the VPS) ---- | ||
| 32 | // Run the rendezvous relay forever on `port`, forwarding between paired peers. | ||
| 33 | // Blocks; run it in a thread. Returns false if it can't bind/listen. | ||
| 34 | bool RvRelayRun(unsigned short port); | ||
| 35 | |||
| 36 | // Stop a running relay (signals RvRelayRun to return). | ||
| 37 | void RvRelayStop(); | ||
| 38 | |||
| 39 | // ---- service side (the node being reached by its .btf address) ---- | ||
| 40 | // Register at the relay under `my_pubkey` (32 bytes) and block until a client is | ||
| 41 | // paired to us. Returns the paired socket, or RV_INVALID on error. | ||
| 42 | RvSocket RvServiceRegister(const char* relay_host, unsigned short port, | ||
| 43 | const unsigned char my_pubkey[32]); | ||
| 44 | |||
| 45 | // ---- client side (the node dialing a .btf address) ---- | ||
| 46 | // Connect through the relay to the service registered under `target_pubkey`. | ||
| 47 | // Returns the paired socket, or RV_INVALID on error. | ||
| 48 | RvSocket RvClientConnect(const char* relay_host, unsigned short port, | ||
| 49 | const unsigned char target_pubkey[32]); | ||
| 50 | |||
| 51 | // Blocking read/write of exactly n bytes over a rendezvous socket. Return false | ||
| 52 | // on error/EOF. | ||
| 53 | bool RvReadN(RvSocket s, void* buf, int n); | ||
| 54 | bool RvWriteN(RvSocket s, const void* buf, int n); | ||
| 55 | void RvClose(RvSocket s); | ||
| 56 | |||
| 57 | } // namespace btf | ||
| 58 | |||
| 59 | #endif | ||
diff --git a/src/btftunnel.cpp b/src/btftunnel.cpp new file mode 100644 index 0000000..65c4b89 --- /dev/null +++ b/src/btftunnel.cpp | |||
| @@ -0,0 +1,161 @@ | |||
| 1 | // Copyright (c) 2026 Bitflash developers | ||
| 2 | // Distributed under the MIT/X11 software license. | ||
| 3 | // | ||
| 4 | // Transparent anonymous tunnel. See btftunnel.h. | ||
| 5 | |||
| 6 | #include "btftunnel.h" | ||
| 7 | #include "btfchan.h" | ||
| 8 | |||
| 9 | #ifdef _WIN32 | ||
| 10 | #include <winsock2.h> | ||
| 11 | #include <ws2tcpip.h> | ||
| 12 | #else | ||
| 13 | #include <sys/socket.h> | ||
| 14 | #include <netinet/in.h> | ||
| 15 | #include <arpa/inet.h> | ||
| 16 | #include <unistd.h> | ||
| 17 | typedef int SOCKET; | ||
| 18 | #ifndef INVALID_SOCKET | ||
| 19 | #define INVALID_SOCKET (-1) | ||
| 20 | #endif | ||
| 21 | #define closesocket(s) ::close(s) | ||
| 22 | #ifndef SD_BOTH | ||
| 23 | #define SD_BOTH SHUT_RDWR | ||
| 24 | #endif | ||
| 25 | #endif | ||
| 26 | #include <cstring> | ||
| 27 | #include <vector> | ||
| 28 | #include <thread> | ||
| 29 | |||
| 30 | namespace btf | ||
| 31 | { | ||
| 32 | |||
| 33 | bool TunnelInit() | ||
| 34 | { | ||
| 35 | return RvInit() && ChanInit(); | ||
| 36 | } | ||
| 37 | |||
| 38 | // Create a connected loopback socket pair (no socketpair() on Windows). | ||
| 39 | // Returns app end and pump end; both are ordinary full-duplex TCP sockets. | ||
| 40 | static bool MakeLocalPair(btf_socket_t& appEnd, btf_socket_t& pumpEnd) | ||
| 41 | { | ||
| 42 | SOCKET listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); | ||
| 43 | if (listener == INVALID_SOCKET) return false; | ||
| 44 | |||
| 45 | struct sockaddr_in addr; | ||
| 46 | memset(&addr, 0, sizeof(addr)); | ||
| 47 | addr.sin_family = AF_INET; | ||
| 48 | addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); | ||
| 49 | addr.sin_port = 0; // ephemeral | ||
| 50 | if (bind(listener, (struct sockaddr*)&addr, sizeof(addr)) != 0) { closesocket(listener); return false; } | ||
| 51 | if (listen(listener, 1) != 0) { closesocket(listener); return false; } | ||
| 52 | |||
| 53 | #ifdef _WIN32 | ||
| 54 | int len = sizeof(addr); | ||
| 55 | #else | ||
| 56 | socklen_t len = sizeof(addr); | ||
| 57 | #endif | ||
| 58 | if (getsockname(listener, (struct sockaddr*)&addr, &len) != 0) { closesocket(listener); return false; } | ||
| 59 | |||
| 60 | SOCKET a = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); | ||
| 61 | if (a == INVALID_SOCKET) { closesocket(listener); return false; } | ||
| 62 | if (connect(a, (struct sockaddr*)&addr, sizeof(addr)) != 0) { closesocket(a); closesocket(listener); return false; } | ||
| 63 | |||
| 64 | SOCKET b = accept(listener, NULL, NULL); | ||
| 65 | closesocket(listener); | ||
| 66 | if (b == INVALID_SOCKET) { closesocket(a); return false; } | ||
| 67 | |||
| 68 | appEnd = a; | ||
| 69 | pumpEnd = b; | ||
| 70 | return true; | ||
| 71 | } | ||
| 72 | |||
| 73 | static bool SockReadN(SOCKET s, void* buf, int n) | ||
| 74 | { | ||
| 75 | char* p = (char*)buf; int off = 0; | ||
| 76 | while (off < n) { int r = recv(s, p + off, n - off, 0); if (r <= 0) return false; off += r; } | ||
| 77 | return true; | ||
| 78 | } | ||
| 79 | static bool SockWriteN(SOCKET s, const void* buf, int n) | ||
| 80 | { | ||
| 81 | const char* p = (const char*)buf; int off = 0; | ||
| 82 | while (off < n) { int r = send(s, p + off, n - off, 0); if (r <= 0) return false; off += r; } | ||
| 83 | return true; | ||
| 84 | } | ||
| 85 | |||
| 86 | // Outbound pump: plaintext from the app -> echan frame -> rendezvous socket. | ||
| 87 | static void PumpOut(SOCKET pumpEnd, RvSocket rv, std::vector<unsigned char> key) | ||
| 88 | { | ||
| 89 | char buf[16 * 1024]; | ||
| 90 | for (;;) | ||
| 91 | { | ||
| 92 | int r = recv(pumpEnd, buf, sizeof(buf), 0); | ||
| 93 | if (r <= 0) break; | ||
| 94 | std::vector<unsigned char> frame = ChanEncryptFrame(key.data(), (const unsigned char*)buf, r); | ||
| 95 | if (!RvWriteN(rv, frame.data(), (int)frame.size())) break; | ||
| 96 | } | ||
| 97 | // Tear down: unblock the inbound pump and the app. | ||
| 98 | shutdown((SOCKET)rv, SD_BOTH); | ||
| 99 | shutdown(pumpEnd, SD_BOTH); | ||
| 100 | } | ||
| 101 | |||
| 102 | // Inbound pump: echan frames from the rendezvous socket -> plaintext to the app. | ||
| 103 | static void PumpIn(SOCKET pumpEnd, RvSocket rv, std::vector<unsigned char> key) | ||
| 104 | { | ||
| 105 | for (;;) | ||
| 106 | { | ||
| 107 | unsigned char len[4]; | ||
| 108 | if (!RvReadN(rv, len, 4)) break; | ||
| 109 | size_t n = ((size_t)len[0]<<24)|((size_t)len[1]<<16)|((size_t)len[2]<<8)|len[3]; | ||
| 110 | if (n < (size_t)(CHAN_NONCEBYTES + CHAN_MACBYTES) || n > (1u<<20)) break; | ||
| 111 | std::vector<unsigned char> body(n); | ||
| 112 | if (!RvReadN(rv, body.data(), (int)n)) break; | ||
| 113 | std::vector<unsigned char> pt; | ||
| 114 | if (!ChanDecryptBody(key.data(), body.data(), (int)n, pt)) break; // auth fail -> drop | ||
| 115 | if (!pt.empty() && !SockWriteN(pumpEnd, pt.data(), (int)pt.size())) break; | ||
| 116 | } | ||
| 117 | shutdown(pumpEnd, SD_BOTH); | ||
| 118 | shutdown((SOCKET)rv, SD_BOTH); | ||
| 119 | } | ||
| 120 | |||
| 121 | // Start the two pumps and hand back the app-facing socket. When both pumps | ||
| 122 | // finish, close the pump end and the rendezvous socket. | ||
| 123 | static btf_socket_t StartTunnel(RvSocket rv, const unsigned char shared[32]) | ||
| 124 | { | ||
| 125 | btf_socket_t appEnd, pumpEnd; | ||
| 126 | if (!MakeLocalPair(appEnd, pumpEnd)) { RvClose(rv); return INVALID_SOCKET; } | ||
| 127 | |||
| 128 | std::vector<unsigned char> key(shared, shared + 32); | ||
| 129 | std::thread(PumpOut, pumpEnd, rv, key).detach(); | ||
| 130 | std::thread([pumpEnd, rv, key]() { | ||
| 131 | PumpIn(pumpEnd, rv, key); | ||
| 132 | closesocket(pumpEnd); | ||
| 133 | RvClose(rv); | ||
| 134 | }).detach(); | ||
| 135 | return appEnd; | ||
| 136 | } | ||
| 137 | |||
| 138 | btf_socket_t BtfClientTunnel(const char* meeting_host, unsigned short port, | ||
| 139 | const unsigned char target_pubkey[32], | ||
| 140 | const unsigned char service_enc_pub[32]) | ||
| 141 | { | ||
| 142 | if (!TunnelInit()) return INVALID_SOCKET; | ||
| 143 | RvSocket rv = RvClientConnect(meeting_host, port, target_pubkey); | ||
| 144 | if (rv == RV_INVALID) return INVALID_SOCKET; | ||
| 145 | |||
| 146 | unsigned char eph_pub[32], shared[32]; | ||
| 147 | if (!ChanClientHandshake(service_enc_pub, eph_pub, shared)) { RvClose(rv); return INVALID_SOCKET; } | ||
| 148 | if (!RvWriteN(rv, eph_pub, 32)) { RvClose(rv); return INVALID_SOCKET; } | ||
| 149 | return StartTunnel(rv, shared); | ||
| 150 | } | ||
| 151 | |||
| 152 | btf_socket_t BtfServiceWrap(RvSocket rv, const unsigned char my_enc_sk[32]) | ||
| 153 | { | ||
| 154 | if (!TunnelInit()) { RvClose(rv); return INVALID_SOCKET; } | ||
| 155 | unsigned char eph_pub[32], shared[32]; | ||
| 156 | if (!RvReadN(rv, eph_pub, 32)) { RvClose(rv); return INVALID_SOCKET; } | ||
| 157 | if (!ChanEndpointHandshake(eph_pub, my_enc_sk, shared)) { RvClose(rv); return INVALID_SOCKET; } | ||
| 158 | return StartTunnel(rv, shared); | ||
| 159 | } | ||
| 160 | |||
| 161 | } // namespace btf | ||
diff --git a/src/btftunnel.h b/src/btftunnel.h new file mode 100644 index 0000000..1fa4f01 --- /dev/null +++ b/src/btftunnel.h | |||
| @@ -0,0 +1,49 @@ | |||
| 1 | // Copyright (c) 2026 Bitflash developers | ||
| 2 | // Distributed under the MIT/X11 software license. | ||
| 3 | // | ||
| 4 | // Transparent anonymous tunnel. Gives the existing CNode a plain local socket | ||
| 5 | // while, behind it, a pair of pump threads bridge plaintext <-> echan <-> | ||
| 6 | // rendezvous. CNode reads/writes normally and never knows its bytes travel | ||
| 7 | // end-to-end encrypted through a meeting node (the Itzal `wrap()` pattern). | ||
| 8 | // | ||
| 9 | // Client side: resolve a `.btf` -> meeting node + service enc key (done by the | ||
| 10 | // caller), then BtfClientTunnel connects through the relay, runs the echan | ||
| 11 | // handshake, and returns a local SOCKET to hand a new outbound CNode. | ||
| 12 | // | ||
| 13 | // Service side: after RvServiceRegister pairs us with a client, BtfServiceWrap | ||
| 14 | // completes the echan handshake and returns a local SOCKET for an inbound CNode. | ||
| 15 | |||
| 16 | #ifndef BITFLASH_BTFTUNNEL_H | ||
| 17 | #define BITFLASH_BTFTUNNEL_H | ||
| 18 | |||
| 19 | #include "btfrv.h" | ||
| 20 | |||
| 21 | #ifdef _WIN32 | ||
| 22 | #include <winsock2.h> | ||
| 23 | typedef SOCKET btf_socket_t; | ||
| 24 | #else | ||
| 25 | typedef int btf_socket_t; | ||
| 26 | #define INVALID_SOCKET (-1) | ||
| 27 | #endif | ||
| 28 | |||
| 29 | namespace btf | ||
| 30 | { | ||
| 31 | |||
| 32 | // Initialize (sockets + libsodium). Idempotent. | ||
| 33 | bool TunnelInit(); | ||
| 34 | |||
| 35 | // Client: dial the service registered under `target_pubkey` at the meeting node | ||
| 36 | // (host:port), box to its static x25519 `service_enc_pub`, and return a local | ||
| 37 | // plaintext SOCKET tunneled end-to-end to the service. INVALID_SOCKET on error. | ||
| 38 | btf_socket_t BtfClientTunnel(const char* meeting_host, unsigned short port, | ||
| 39 | const unsigned char target_pubkey[32], | ||
| 40 | const unsigned char service_enc_pub[32]); | ||
| 41 | |||
| 42 | // Service: wrap an already-paired rendezvous socket (from RvServiceRegister) | ||
| 43 | // with echan using my static x25519 secret, returning a local plaintext SOCKET | ||
| 44 | // for an inbound CNode. Consumes `rv` (closed when the tunnel tears down). | ||
| 45 | btf_socket_t BtfServiceWrap(RvSocket rv, const unsigned char my_enc_sk[32]); | ||
| 46 | |||
| 47 | } // namespace btf | ||
| 48 | |||
| 49 | #endif | ||
diff --git a/src/compat.h b/src/compat.h new file mode 100644 index 0000000..e3f76a1 --- /dev/null +++ b/src/compat.h | |||
| @@ -0,0 +1,193 @@ | |||
| 1 | // Copyright (c) 2026 Bitflash developers | ||
| 2 | // Distributed under the MIT/X11 software license. | ||
| 3 | // | ||
| 4 | // POSIX/Linux compatibility shim. Lets the Windows-flavored core (Winsock, | ||
| 5 | // _beginthread, CRITICAL_SECTION, Sleep, ...) compile largely unchanged on | ||
| 6 | // Linux for the headless node/miner `bitflash-node`. Included by headers.h on | ||
| 7 | // non-Windows platforms only; the Windows build never sees this file. | ||
| 8 | |||
| 9 | #ifndef BITFLASH_COMPAT_H | ||
| 10 | #define BITFLASH_COMPAT_H | ||
| 11 | #ifndef _WIN32 | ||
| 12 | |||
| 13 | #include <sys/types.h> | ||
| 14 | #include <sys/socket.h> | ||
| 15 | #include <sys/select.h> | ||
| 16 | #include <sys/ioctl.h> | ||
| 17 | #include <sys/stat.h> | ||
| 18 | #include <sys/time.h> | ||
| 19 | #include <netinet/in.h> | ||
| 20 | #include <netinet/tcp.h> | ||
| 21 | #include <arpa/inet.h> | ||
| 22 | #include <netdb.h> | ||
| 23 | #include <unistd.h> | ||
| 24 | #include <fcntl.h> | ||
| 25 | #include <errno.h> | ||
| 26 | #include <pthread.h> | ||
| 27 | #include <time.h> | ||
| 28 | #include <stdint.h> | ||
| 29 | #include <stdarg.h> | ||
| 30 | #include <cctype> | ||
| 31 | #include <cstring> | ||
| 32 | #include <cstdio> | ||
| 33 | #include <cstdlib> | ||
| 34 | #include <string> | ||
| 35 | |||
| 36 | // ---- Windows integer/type aliases used across the core ---- | ||
| 37 | typedef unsigned int DWORD; | ||
| 38 | typedef void* HANDLE; | ||
| 39 | typedef int64_t LARGE_INTEGER; | ||
| 40 | #ifndef TRUE | ||
| 41 | #define TRUE 1 | ||
| 42 | #define FALSE 0 | ||
| 43 | #endif | ||
| 44 | #ifndef _I64_MAX | ||
| 45 | #define _I64_MAX 0x7fffffffffffffffLL | ||
| 46 | #define _I64_MIN (-0x7fffffffffffffffLL - 1) | ||
| 47 | #endif | ||
| 48 | #ifndef _UI64_MAX | ||
| 49 | #define _UI64_MAX 0xffffffffffffffffULL | ||
| 50 | #endif | ||
| 51 | |||
| 52 | // High-resolution counter (used only for optional timing in the core). | ||
| 53 | inline void QueryPerformanceCounter(LARGE_INTEGER* p) | ||
| 54 | { | ||
| 55 | struct timespec ts; | ||
| 56 | clock_gettime(CLOCK_MONOTONIC, &ts); | ||
| 57 | *p = (int64_t)ts.tv_sec * 1000000000LL + ts.tv_nsec; | ||
| 58 | } | ||
| 59 | |||
| 60 | // ---- socket layer (Winsock -> BSD sockets) ---- | ||
| 61 | typedef int SOCKET; | ||
| 62 | #ifndef INVALID_SOCKET | ||
| 63 | #define INVALID_SOCKET (-1) | ||
| 64 | #endif | ||
| 65 | #ifndef SOCKET_ERROR | ||
| 66 | #define SOCKET_ERROR (-1) | ||
| 67 | #endif | ||
| 68 | #ifndef NO_ERROR | ||
| 69 | #define NO_ERROR 0 | ||
| 70 | #endif | ||
| 71 | #define closesocket(s) ::close(s) | ||
| 72 | inline int WSAGetLastError() { return errno; } | ||
| 73 | |||
| 74 | // Winsock error codes mapped to POSIX errno values | ||
| 75 | #define WSAEWOULDBLOCK EWOULDBLOCK | ||
| 76 | #define WSAEMSGSIZE EMSGSIZE | ||
| 77 | #define WSAEINTR EINTR | ||
| 78 | #define WSAEINPROGRESS EINPROGRESS | ||
| 79 | #define WSAEADDRINUSE EADDRINUSE | ||
| 80 | #define WSAEALREADY EALREADY | ||
| 81 | #define WSAECONNREFUSED ECONNREFUSED | ||
| 82 | #define WSAENOTSOCK EBADF | ||
| 83 | |||
| 84 | // Only FIONBIO (non-blocking toggle) is used; implement it robustly via fcntl. | ||
| 85 | inline int ioctlsocket(SOCKET s, long cmd, u_long* argp) | ||
| 86 | { | ||
| 87 | if (cmd == (long)FIONBIO) | ||
| 88 | { | ||
| 89 | int flags = fcntl(s, F_GETFL, 0); | ||
| 90 | if (flags < 0) return -1; | ||
| 91 | if (*argp) flags |= O_NONBLOCK; else flags &= ~O_NONBLOCK; | ||
| 92 | return fcntl(s, F_SETFL, flags); | ||
| 93 | } | ||
| 94 | return ioctl(s, cmd, argp); | ||
| 95 | } | ||
| 96 | |||
| 97 | // WSAStartup/WSACleanup are no-ops outside Windows. | ||
| 98 | typedef int WSADATA; | ||
| 99 | inline int WSAStartup(unsigned short, WSADATA*) { return 0; } | ||
| 100 | inline int WSACleanup() { return 0; } | ||
| 101 | #ifndef MAKEWORD | ||
| 102 | #define MAKEWORD(a, b) 0 | ||
| 103 | #endif | ||
| 104 | |||
| 105 | // ---- Sleep(ms) ---- | ||
| 106 | inline void Sleep(unsigned int ms) | ||
| 107 | { | ||
| 108 | struct timespec ts; | ||
| 109 | ts.tv_sec = ms / 1000; | ||
| 110 | ts.tv_nsec = (long)(ms % 1000) * 1000000L; | ||
| 111 | nanosleep(&ts, NULL); | ||
| 112 | } | ||
| 113 | |||
| 114 | // ---- threads: _beginthread / _endthread over pthreads ---- | ||
| 115 | struct _bf_thread_ctx { void (*fn)(void*); void* arg; }; | ||
| 116 | inline void* _bf_thread_trampoline(void* p) | ||
| 117 | { | ||
| 118 | _bf_thread_ctx* c = (_bf_thread_ctx*)p; | ||
| 119 | void (*fn)(void*) = c->fn; | ||
| 120 | void* arg = c->arg; | ||
| 121 | delete c; | ||
| 122 | fn(arg); | ||
| 123 | return NULL; | ||
| 124 | } | ||
| 125 | inline uintptr_t _beginthread(void (*start)(void*), unsigned, void* arg) | ||
| 126 | { | ||
| 127 | _bf_thread_ctx* c = new _bf_thread_ctx; | ||
| 128 | c->fn = start; c->arg = arg; | ||
| 129 | pthread_t th; | ||
| 130 | if (pthread_create(&th, NULL, _bf_thread_trampoline, c) != 0) | ||
| 131 | { | ||
| 132 | delete c; | ||
| 133 | return (uintptr_t)-1; | ||
| 134 | } | ||
| 135 | pthread_detach(th); | ||
| 136 | return (uintptr_t)th; | ||
| 137 | } | ||
| 138 | inline void _endthread() { pthread_exit(NULL); } | ||
| 139 | |||
| 140 | // ---- CRITICAL_SECTION over a recursive mutex (util.h's CCriticalSection | ||
| 141 | // compiles unchanged on top of these) ---- | ||
| 142 | typedef pthread_mutex_t CRITICAL_SECTION; | ||
| 143 | inline void InitializeCriticalSection(CRITICAL_SECTION* cs) | ||
| 144 | { | ||
| 145 | pthread_mutexattr_t a; | ||
| 146 | pthread_mutexattr_init(&a); | ||
| 147 | pthread_mutexattr_settype(&a, PTHREAD_MUTEX_RECURSIVE); | ||
| 148 | pthread_mutex_init(cs, &a); | ||
| 149 | pthread_mutexattr_destroy(&a); | ||
| 150 | } | ||
| 151 | inline void DeleteCriticalSection(CRITICAL_SECTION* cs) { pthread_mutex_destroy(cs); } | ||
| 152 | inline void EnterCriticalSection(CRITICAL_SECTION* cs) { pthread_mutex_lock(cs); } | ||
| 153 | inline void LeaveCriticalSection(CRITICAL_SECTION* cs) { pthread_mutex_unlock(cs); } | ||
| 154 | inline bool TryEnterCriticalSection(CRITICAL_SECTION* cs) { return pthread_mutex_trylock(cs) == 0; } | ||
| 155 | |||
| 156 | // ---- misc Windows CRT/debug helpers ---- | ||
| 157 | inline void OutputDebugStringA(const char*) {} | ||
| 158 | inline void DebugBreak() {} | ||
| 159 | #ifndef _HEAPOK | ||
| 160 | #define _HEAPOK 0 | ||
| 161 | #endif | ||
| 162 | inline int _heapchk() { return _HEAPOK; } | ||
| 163 | #define _vsnprintf vsnprintf | ||
| 164 | inline char* strlwr(char* s) { for (char* p = s; *p; ++p) *p = (char)tolower((unsigned char)*p); return s; } | ||
| 165 | #define _strlwr strlwr | ||
| 166 | inline int _mkdir(const char* p) { return ::mkdir(p, 0755); } | ||
| 167 | |||
| 168 | // Thread priority is a Windows nicety; on Linux the message-handler thread just | ||
| 169 | // runs at normal priority (harmless no-op). | ||
| 170 | inline void* GetCurrentThread() { return (void*)0; } | ||
| 171 | inline void SetThreadPriority(void*, int) {} | ||
| 172 | #ifndef THREAD_PRIORITY_BELOW_NORMAL | ||
| 173 | #define THREAD_PRIORITY_BELOW_NORMAL 0 | ||
| 174 | #define THREAD_PRIORITY_LOWEST 0 | ||
| 175 | #define THREAD_PRIORITY_NORMAL 0 | ||
| 176 | #endif | ||
| 177 | |||
| 178 | // ---- wxWidgets shims (the headless build has no GUI; the few core call sites | ||
| 179 | // degrade to console/no-op) ---- | ||
| 180 | #define wxTheApp ((void*)0) | ||
| 181 | #ifndef wxOK | ||
| 182 | #define wxOK 0 | ||
| 183 | #define wxICON_ERROR 0 | ||
| 184 | #define wxICON_EXCLAMATION 0 | ||
| 185 | #define wxICON_INFORMATION 0 | ||
| 186 | #endif | ||
| 187 | inline void wxMessageBox(const std::string& msg, const std::string& caption = "", long = 0) | ||
| 188 | { | ||
| 189 | fprintf(stderr, "%s%s%s\n", caption.c_str(), caption.empty() ? "" : ": ", msg.c_str()); | ||
| 190 | } | ||
| 191 | |||
| 192 | #endif // !_WIN32 | ||
| 193 | #endif // BITFLASH_COMPAT_H | ||
diff --git a/src/db.cpp b/src/db.cpp new file mode 100644 index 0000000..0df68fc --- /dev/null +++ b/src/db.cpp | |||
| @@ -0,0 +1,604 @@ | |||
| 1 | // Copyright (c) 2009 Satoshi Nakamoto | ||
| 2 | // Distributed under the MIT/X11 software license, see the accompanying | ||
| 3 | // file license.txt or http://www.opensource.org/licenses/mit-license.php. | ||
| 4 | |||
| 5 | #include "headers.h" | ||
| 6 | |||
| 7 | |||
| 8 | |||
| 9 | |||
| 10 | |||
| 11 | |||
| 12 | // | ||
| 13 | // CDB | ||
| 14 | // | ||
| 15 | |||
| 16 | static CCriticalSection cs_db; | ||
| 17 | static bool fDbEnvInit = false; | ||
| 18 | DbEnv dbenv(0u); | ||
| 19 | static map<string, int> mapFileUseCount; | ||
| 20 | |||
| 21 | class CDBInit | ||
| 22 | { | ||
| 23 | public: | ||
| 24 | CDBInit() | ||
| 25 | { | ||
| 26 | } | ||
| 27 | ~CDBInit() | ||
| 28 | { | ||
| 29 | if (fDbEnvInit) | ||
| 30 | { | ||
| 31 | dbenv.close(0); | ||
| 32 | fDbEnvInit = false; | ||
| 33 | } | ||
| 34 | } | ||
| 35 | } | ||
| 36 | instance_of_cdbinit; | ||
| 37 | |||
| 38 | |||
| 39 | CDB::CDB(const char* pszFile, const char* pszMode, bool fTxn) : pdb(NULL) | ||
| 40 | { | ||
| 41 | int ret; | ||
| 42 | if (pszFile == NULL) | ||
| 43 | return; | ||
| 44 | |||
| 45 | bool fCreate = strchr(pszMode, 'c'); | ||
| 46 | bool fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w')); | ||
| 47 | unsigned int nFlags = DB_THREAD; | ||
| 48 | if (fCreate) | ||
| 49 | nFlags |= DB_CREATE; | ||
| 50 | else if (fReadOnly) | ||
| 51 | nFlags |= DB_RDONLY; | ||
| 52 | if (!fReadOnly || fTxn) | ||
| 53 | nFlags |= DB_AUTO_COMMIT; | ||
| 54 | |||
| 55 | CRITICAL_BLOCK(cs_db) | ||
| 56 | { | ||
| 57 | if (!fDbEnvInit) | ||
| 58 | { | ||
| 59 | string strAppDir = GetAppDir(); | ||
| 60 | string strLogDir = strAppDir + "/database"; | ||
| 61 | _mkdir(strLogDir.c_str()); | ||
| 62 | printf("dbenv.open strAppDir=%s\n", strAppDir.c_str()); | ||
| 63 | |||
| 64 | dbenv.set_lg_dir(strLogDir.c_str()); | ||
| 65 | dbenv.set_lg_max(10000000); | ||
| 66 | dbenv.set_lk_max_locks(10000); | ||
| 67 | dbenv.set_lk_max_objects(10000); | ||
| 68 | dbenv.set_errfile(fopen("db.log", "a")); /// debug | ||
| 69 | ///dbenv.log_set_config(DB_LOG_AUTO_REMOVE, 1); /// causes corruption | ||
| 70 | ret = dbenv.open(strAppDir.c_str(), | ||
| 71 | DB_CREATE | | ||
| 72 | DB_INIT_LOCK | | ||
| 73 | DB_INIT_LOG | | ||
| 74 | DB_INIT_MPOOL | | ||
| 75 | DB_INIT_TXN | | ||
| 76 | DB_THREAD | | ||
| 77 | DB_PRIVATE | | ||
| 78 | DB_RECOVER, | ||
| 79 | 0); | ||
| 80 | if (ret > 0) | ||
| 81 | throw runtime_error(strprintf("CDB() : error %d opening database environment\n", ret)); | ||
| 82 | fDbEnvInit = true; | ||
| 83 | } | ||
| 84 | |||
| 85 | strFile = pszFile; | ||
| 86 | ++mapFileUseCount[strFile]; | ||
| 87 | } | ||
| 88 | |||
| 89 | pdb = new Db(&dbenv, 0); | ||
| 90 | |||
| 91 | ret = pdb->open(NULL, // Txn pointer | ||
| 92 | pszFile, // Filename | ||
| 93 | "main", // Logical db name | ||
| 94 | DB_BTREE, // Database type | ||
| 95 | nFlags, // Flags | ||
| 96 | 0); | ||
| 97 | |||
| 98 | if (ret > 0) | ||
| 99 | { | ||
| 100 | delete pdb; | ||
| 101 | pdb = NULL; | ||
| 102 | CRITICAL_BLOCK(cs_db) | ||
| 103 | --mapFileUseCount[strFile]; | ||
| 104 | strFile = ""; | ||
| 105 | throw runtime_error(strprintf("CDB() : can't open database file %s, error %d\n", pszFile, ret)); | ||
| 106 | } | ||
| 107 | |||
| 108 | if (fCreate && !Exists(string("version"))) | ||
| 109 | WriteVersion(VERSION); | ||
| 110 | |||
| 111 | RandAddSeed(); | ||
| 112 | } | ||
| 113 | |||
| 114 | void CDB::Close() | ||
| 115 | { | ||
| 116 | if (!pdb) | ||
| 117 | return; | ||
| 118 | if (!vTxn.empty()) | ||
| 119 | vTxn.front()->abort(); | ||
| 120 | vTxn.clear(); | ||
| 121 | pdb->close(0); | ||
| 122 | delete pdb; | ||
| 123 | pdb = NULL; | ||
| 124 | dbenv.txn_checkpoint(0, 0, 0); | ||
| 125 | |||
| 126 | CRITICAL_BLOCK(cs_db) | ||
| 127 | --mapFileUseCount[strFile]; | ||
| 128 | |||
| 129 | RandAddSeed(); | ||
| 130 | } | ||
| 131 | |||
| 132 | void DBFlush(bool fShutdown) | ||
| 133 | { | ||
| 134 | // Flush log data to the actual data file | ||
| 135 | // on all files that are not in use | ||
| 136 | printf("DBFlush(%s)\n", fShutdown ? "true" : "false"); | ||
| 137 | CRITICAL_BLOCK(cs_db) | ||
| 138 | { | ||
| 139 | dbenv.txn_checkpoint(0, 0, 0); | ||
| 140 | map<string, int>::iterator mi = mapFileUseCount.begin(); | ||
| 141 | while (mi != mapFileUseCount.end()) | ||
| 142 | { | ||
| 143 | string strFile = (*mi).first; | ||
| 144 | int nRefCount = (*mi).second; | ||
| 145 | if (nRefCount == 0) | ||
| 146 | { | ||
| 147 | dbenv.lsn_reset(strFile.c_str(), 0); | ||
| 148 | mapFileUseCount.erase(mi++); | ||
| 149 | } | ||
| 150 | else | ||
| 151 | mi++; | ||
| 152 | } | ||
| 153 | if (fShutdown) | ||
| 154 | { | ||
| 155 | char** listp; | ||
| 156 | if (mapFileUseCount.empty()) | ||
| 157 | dbenv.log_archive(&listp, DB_ARCH_REMOVE); | ||
| 158 | dbenv.close(0); | ||
| 159 | fDbEnvInit = false; | ||
| 160 | } | ||
| 161 | } | ||
| 162 | } | ||
| 163 | |||
| 164 | |||
| 165 | |||
| 166 | |||
| 167 | |||
| 168 | |||
| 169 | // | ||
| 170 | // CTxDB | ||
| 171 | // | ||
| 172 | |||
| 173 | bool CTxDB::ReadTxIndex(uint256 hash, CTxIndex& txindex) | ||
| 174 | { | ||
| 175 | assert(!fClient); | ||
| 176 | txindex.SetNull(); | ||
| 177 | return Read(make_pair(string("tx"), hash), txindex); | ||
| 178 | } | ||
| 179 | |||
| 180 | bool CTxDB::UpdateTxIndex(uint256 hash, const CTxIndex& txindex) | ||
| 181 | { | ||
| 182 | assert(!fClient); | ||
| 183 | return Write(make_pair(string("tx"), hash), txindex); | ||
| 184 | } | ||
| 185 | |||
| 186 | bool CTxDB::AddTxIndex(const CTransaction& tx, const CDiskTxPos& pos, int nHeight) | ||
| 187 | { | ||
| 188 | assert(!fClient); | ||
| 189 | |||
| 190 | // Add to tx index | ||
| 191 | uint256 hash = tx.GetHash(); | ||
| 192 | CTxIndex txindex(pos, tx.vout.size()); | ||
| 193 | return Write(make_pair(string("tx"), hash), txindex); | ||
| 194 | } | ||
| 195 | |||
| 196 | bool CTxDB::EraseTxIndex(const CTransaction& tx) | ||
| 197 | { | ||
| 198 | assert(!fClient); | ||
| 199 | uint256 hash = tx.GetHash(); | ||
| 200 | |||
| 201 | return Erase(make_pair(string("tx"), hash)); | ||
| 202 | } | ||
| 203 | |||
| 204 | bool CTxDB::ContainsTx(uint256 hash) | ||
| 205 | { | ||
| 206 | assert(!fClient); | ||
| 207 | return Exists(make_pair(string("tx"), hash)); | ||
| 208 | } | ||
| 209 | |||
| 210 | bool CTxDB::ReadOwnerTxes(uint160 hash160, int nMinHeight, vector<CTransaction>& vtx) | ||
| 211 | { | ||
| 212 | assert(!fClient); | ||
| 213 | vtx.clear(); | ||
| 214 | |||
| 215 | // Get cursor | ||
| 216 | Dbc* pcursor = GetCursor(); | ||
| 217 | if (!pcursor) | ||
| 218 | return false; | ||
| 219 | |||
| 220 | unsigned int fFlags = DB_SET_RANGE; | ||
| 221 | loop | ||
| 222 | { | ||
| 223 | // Read next record | ||
| 224 | CDataStream ssKey; | ||
| 225 | if (fFlags == DB_SET_RANGE) | ||
| 226 | ssKey << string("owner") << hash160 << CDiskTxPos(0, 0, 0); | ||
| 227 | CDataStream ssValue; | ||
| 228 | int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags); | ||
| 229 | fFlags = DB_NEXT; | ||
| 230 | if (ret == DB_NOTFOUND) | ||
| 231 | break; | ||
| 232 | else if (ret != 0) | ||
| 233 | return false; | ||
| 234 | |||
| 235 | // Unserialize | ||
| 236 | string strType; | ||
| 237 | uint160 hashItem; | ||
| 238 | CDiskTxPos pos; | ||
| 239 | ssKey >> strType >> hashItem >> pos; | ||
| 240 | int nItemHeight; | ||
| 241 | ssValue >> nItemHeight; | ||
| 242 | |||
| 243 | // Read transaction | ||
| 244 | if (strType != "owner" || hashItem != hash160) | ||
| 245 | break; | ||
| 246 | if (nItemHeight >= nMinHeight) | ||
| 247 | { | ||
| 248 | vtx.resize(vtx.size()+1); | ||
| 249 | if (!vtx.back().ReadFromDisk(pos)) | ||
| 250 | return false; | ||
| 251 | } | ||
| 252 | } | ||
| 253 | return true; | ||
| 254 | } | ||
| 255 | |||
| 256 | bool CTxDB::ReadDiskTx(uint256 hash, CTransaction& tx, CTxIndex& txindex) | ||
| 257 | { | ||
| 258 | assert(!fClient); | ||
| 259 | tx.SetNull(); | ||
| 260 | if (!ReadTxIndex(hash, txindex)) | ||
| 261 | return false; | ||
| 262 | return (tx.ReadFromDisk(txindex.pos)); | ||
| 263 | } | ||
| 264 | |||
| 265 | bool CTxDB::ReadDiskTx(uint256 hash, CTransaction& tx) | ||
| 266 | { | ||
| 267 | CTxIndex txindex; | ||
| 268 | return ReadDiskTx(hash, tx, txindex); | ||
| 269 | } | ||
| 270 | |||
| 271 | bool CTxDB::ReadDiskTx(COutPoint outpoint, CTransaction& tx, CTxIndex& txindex) | ||
| 272 | { | ||
| 273 | return ReadDiskTx(outpoint.hash, tx, txindex); | ||
| 274 | } | ||
| 275 | |||
| 276 | bool CTxDB::ReadDiskTx(COutPoint outpoint, CTransaction& tx) | ||
| 277 | { | ||
| 278 | CTxIndex txindex; | ||
| 279 | return ReadDiskTx(outpoint.hash, tx, txindex); | ||
| 280 | } | ||
| 281 | |||
| 282 | bool CTxDB::WriteBlockIndex(const CDiskBlockIndex& blockindex) | ||
| 283 | { | ||
| 284 | return Write(make_pair(string("blockindex"), blockindex.GetBlockHash()), blockindex); | ||
| 285 | } | ||
| 286 | |||
| 287 | bool CTxDB::EraseBlockIndex(uint256 hash) | ||
| 288 | { | ||
| 289 | return Erase(make_pair(string("blockindex"), hash)); | ||
| 290 | } | ||
| 291 | |||
| 292 | bool CTxDB::ReadHashBestChain(uint256& hashBestChain) | ||
| 293 | { | ||
| 294 | return Read(string("hashBestChain"), hashBestChain); | ||
| 295 | } | ||
| 296 | |||
| 297 | bool CTxDB::WriteHashBestChain(uint256 hashBestChain) | ||
| 298 | { | ||
| 299 | return Write(string("hashBestChain"), hashBestChain); | ||
| 300 | } | ||
| 301 | |||
| 302 | CBlockIndex* InsertBlockIndex(uint256 hash) | ||
| 303 | { | ||
| 304 | if (hash == 0) | ||
| 305 | return NULL; | ||
| 306 | |||
| 307 | // Return existing | ||
| 308 | map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash); | ||
| 309 | if (mi != mapBlockIndex.end()) | ||
| 310 | return (*mi).second; | ||
| 311 | |||
| 312 | // Create new | ||
| 313 | CBlockIndex* pindexNew = new CBlockIndex(); | ||
| 314 | if (!pindexNew) | ||
| 315 | throw runtime_error("LoadBlockIndex() : new CBlockIndex failed"); | ||
| 316 | mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first; | ||
| 317 | pindexNew->phashBlock = &((*mi).first); | ||
| 318 | |||
| 319 | return pindexNew; | ||
| 320 | } | ||
| 321 | |||
| 322 | bool CTxDB::LoadBlockIndex() | ||
| 323 | { | ||
| 324 | // Get cursor | ||
| 325 | Dbc* pcursor = GetCursor(); | ||
| 326 | if (!pcursor) | ||
| 327 | return false; | ||
| 328 | |||
| 329 | unsigned int fFlags = DB_SET_RANGE; | ||
| 330 | loop | ||
| 331 | { | ||
| 332 | // Read next record | ||
| 333 | CDataStream ssKey; | ||
| 334 | if (fFlags == DB_SET_RANGE) | ||
| 335 | ssKey << make_pair(string("blockindex"), uint256(0)); | ||
| 336 | CDataStream ssValue; | ||
| 337 | int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags); | ||
| 338 | fFlags = DB_NEXT; | ||
| 339 | if (ret == DB_NOTFOUND) | ||
| 340 | break; | ||
| 341 | else if (ret != 0) | ||
| 342 | return false; | ||
| 343 | |||
| 344 | // Unserialize | ||
| 345 | string strType; | ||
| 346 | ssKey >> strType; | ||
| 347 | if (strType == "blockindex") | ||
| 348 | { | ||
| 349 | CDiskBlockIndex diskindex; | ||
| 350 | ssValue >> diskindex; | ||
| 351 | |||
| 352 | // Construct block index object | ||
| 353 | CBlockIndex* pindexNew = InsertBlockIndex(diskindex.GetBlockHash()); | ||
| 354 | pindexNew->pprev = InsertBlockIndex(diskindex.hashPrev); | ||
| 355 | pindexNew->pnext = InsertBlockIndex(diskindex.hashNext); | ||
| 356 | pindexNew->nFile = diskindex.nFile; | ||
| 357 | pindexNew->nBlockPos = diskindex.nBlockPos; | ||
| 358 | pindexNew->nHeight = diskindex.nHeight; | ||
| 359 | pindexNew->nVersion = diskindex.nVersion; | ||
| 360 | pindexNew->hashMerkleRoot = diskindex.hashMerkleRoot; | ||
| 361 | pindexNew->nTime = diskindex.nTime; | ||
| 362 | pindexNew->nBits = diskindex.nBits; | ||
| 363 | pindexNew->nNonce = diskindex.nNonce; | ||
| 364 | |||
| 365 | // Watch for genesis block and best block | ||
| 366 | if (pindexGenesisBlock == NULL && diskindex.GetBlockHash() == hashGenesisBlock) | ||
| 367 | pindexGenesisBlock = pindexNew; | ||
| 368 | } | ||
| 369 | else | ||
| 370 | { | ||
| 371 | break; | ||
| 372 | } | ||
| 373 | } | ||
| 374 | |||
| 375 | if (!ReadHashBestChain(hashBestChain)) | ||
| 376 | { | ||
| 377 | if (pindexGenesisBlock == NULL) | ||
| 378 | return true; | ||
| 379 | return error("CTxDB::LoadBlockIndex() : hashBestChain not found\n"); | ||
| 380 | } | ||
| 381 | |||
| 382 | if (!mapBlockIndex.count(hashBestChain)) | ||
| 383 | return error("CTxDB::LoadBlockIndex() : blockindex for hashBestChain not found\n"); | ||
| 384 | pindexBest = mapBlockIndex[hashBestChain]; | ||
| 385 | nBestHeight = pindexBest->nHeight; | ||
| 386 | printf("LoadBlockIndex(): hashBestChain=%s height=%d\n", hashBestChain.ToString().substr(0,14).c_str(), nBestHeight); | ||
| 387 | |||
| 388 | return true; | ||
| 389 | } | ||
| 390 | |||
| 391 | |||
| 392 | |||
| 393 | |||
| 394 | |||
| 395 | // | ||
| 396 | // CAddrDB | ||
| 397 | // | ||
| 398 | |||
| 399 | bool CAddrDB::WriteAddress(const CAddress& addr) | ||
| 400 | { | ||
| 401 | return Write(make_pair(string("addr"), addr.GetKey()), addr); | ||
| 402 | } | ||
| 403 | |||
| 404 | bool CAddrDB::LoadAddresses() | ||
| 405 | { | ||
| 406 | CRITICAL_BLOCK(cs_mapAddresses) | ||
| 407 | { | ||
| 408 | // Load user provided addresses | ||
| 409 | CAutoFile filein = fopen("addr.txt", "rt"); | ||
| 410 | if (filein) | ||
| 411 | { | ||
| 412 | try | ||
| 413 | { | ||
| 414 | char psz[1000]; | ||
| 415 | while (fgets(psz, sizeof(psz), filein)) | ||
| 416 | { | ||
| 417 | CAddress addr(psz, NODE_NETWORK); | ||
| 418 | if (addr.ip != 0) | ||
| 419 | AddAddress(*this, addr); | ||
| 420 | } | ||
| 421 | } | ||
| 422 | catch (...) { } | ||
| 423 | } | ||
| 424 | |||
| 425 | // Get cursor | ||
| 426 | Dbc* pcursor = GetCursor(); | ||
| 427 | if (!pcursor) | ||
| 428 | return false; | ||
| 429 | |||
| 430 | loop | ||
| 431 | { | ||
| 432 | // Read next record | ||
| 433 | CDataStream ssKey; | ||
| 434 | CDataStream ssValue; | ||
| 435 | int ret = ReadAtCursor(pcursor, ssKey, ssValue); | ||
| 436 | if (ret == DB_NOTFOUND) | ||
| 437 | break; | ||
| 438 | else if (ret != 0) | ||
| 439 | return false; | ||
| 440 | |||
| 441 | // Unserialize | ||
| 442 | string strType; | ||
| 443 | ssKey >> strType; | ||
| 444 | if (strType == "addr") | ||
| 445 | { | ||
| 446 | CAddress addr; | ||
| 447 | ssValue >> addr; | ||
| 448 | mapAddresses.insert(make_pair(addr.GetKey(), addr)); | ||
| 449 | } | ||
| 450 | } | ||
| 451 | |||
| 452 | //// debug print | ||
| 453 | printf("mapAddresses:\n"); | ||
| 454 | foreach(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses) | ||
| 455 | item.second.print(); | ||
| 456 | printf("-----\n"); | ||
| 457 | } | ||
| 458 | |||
| 459 | return true; | ||
| 460 | } | ||
| 461 | |||
| 462 | bool LoadAddresses() | ||
| 463 | { | ||
| 464 | return CAddrDB("cr+").LoadAddresses(); | ||
| 465 | } | ||
| 466 | |||
| 467 | |||
| 468 | |||
| 469 | |||
| 470 | // | ||
| 471 | // CReviewDB | ||
| 472 | // | ||
| 473 | |||
| 474 | bool CReviewDB::ReadReviews(uint256 hash, vector<CReview>& vReviews) | ||
| 475 | { | ||
| 476 | vReviews.size(); // msvc workaround, just need to do anything with vReviews | ||
| 477 | return Read(make_pair(string("reviews"), hash), vReviews); | ||
| 478 | } | ||
| 479 | |||
| 480 | bool CReviewDB::WriteReviews(uint256 hash, const vector<CReview>& vReviews) | ||
| 481 | { | ||
| 482 | return Write(make_pair(string("reviews"), hash), vReviews); | ||
| 483 | } | ||
| 484 | |||
| 485 | |||
| 486 | |||
| 487 | |||
| 488 | |||
| 489 | |||
| 490 | |||
| 491 | // | ||
| 492 | // CWalletDB | ||
| 493 | // | ||
| 494 | |||
| 495 | bool CWalletDB::LoadWallet(vector<unsigned char>& vchDefaultKeyRet) | ||
| 496 | { | ||
| 497 | vchDefaultKeyRet.clear(); | ||
| 498 | |||
| 499 | //// todo: shouldn't we catch exceptions and try to recover and continue? | ||
| 500 | CRITICAL_BLOCK(cs_mapKeys) | ||
| 501 | CRITICAL_BLOCK(cs_mapWallet) | ||
| 502 | { | ||
| 503 | // Get cursor | ||
| 504 | Dbc* pcursor = GetCursor(); | ||
| 505 | if (!pcursor) | ||
| 506 | return false; | ||
| 507 | |||
| 508 | loop | ||
| 509 | { | ||
| 510 | // Read next record | ||
| 511 | CDataStream ssKey; | ||
| 512 | CDataStream ssValue; | ||
| 513 | int ret = ReadAtCursor(pcursor, ssKey, ssValue); | ||
| 514 | if (ret == DB_NOTFOUND) | ||
| 515 | break; | ||
| 516 | else if (ret != 0) | ||
| 517 | return false; | ||
| 518 | |||
| 519 | // Unserialize | ||
| 520 | // Taking advantage of the fact that pair serialization | ||
| 521 | // is just the two items serialized one after the other | ||
| 522 | string strType; | ||
| 523 | ssKey >> strType; | ||
| 524 | if (strType == "name") | ||
| 525 | { | ||
| 526 | string strAddress; | ||
| 527 | ssKey >> strAddress; | ||
| 528 | ssValue >> mapAddressBook[strAddress]; | ||
| 529 | } | ||
| 530 | else if (strType == "tx") | ||
| 531 | { | ||
| 532 | uint256 hash; | ||
| 533 | ssKey >> hash; | ||
| 534 | CWalletTx& wtx = mapWallet[hash]; | ||
| 535 | ssValue >> wtx; | ||
| 536 | |||
| 537 | if (wtx.GetHash() != hash) | ||
| 538 | printf("Error in wallet.dat, hash mismatch\n"); | ||
| 539 | |||
| 540 | //// debug print | ||
| 541 | //printf("LoadWallet %s\n", wtx.GetHash().ToString().c_str()); | ||
| 542 | //printf(" %12I64d %s %s %s\n", | ||
| 543 | // wtx.vout[0].nValue, | ||
| 544 | // DateTimeStr(wtx.nTime).c_str(), | ||
| 545 | // wtx.hashBlock.ToString().substr(0,14).c_str(), | ||
| 546 | // wtx.mapValue["message"].c_str()); | ||
| 547 | } | ||
| 548 | else if (strType == "key") | ||
| 549 | { | ||
| 550 | vector<unsigned char> vchPubKey; | ||
| 551 | ssKey >> vchPubKey; | ||
| 552 | CPrivKey vchPrivKey; | ||
| 553 | ssValue >> vchPrivKey; | ||
| 554 | |||
| 555 | mapKeys[vchPubKey] = vchPrivKey; | ||
| 556 | mapPubKeys[Hash160(vchPubKey)] = vchPubKey; | ||
| 557 | } | ||
| 558 | else if (strType == "defaultkey") | ||
| 559 | { | ||
| 560 | ssValue >> vchDefaultKeyRet; | ||
| 561 | } | ||
| 562 | else if (strType == "setting") /// or settings or option or options or config? | ||
| 563 | { | ||
| 564 | string strKey; | ||
| 565 | ssKey >> strKey; | ||
| 566 | if (strKey == "fGenerateBitcoins") ssValue >> fGenerateBitcoins; | ||
| 567 | if (strKey == "nTransactionFee") ssValue >> nTransactionFee; | ||
| 568 | if (strKey == "addrIncoming") ssValue >> addrIncoming; | ||
| 569 | } | ||
| 570 | } | ||
| 571 | } | ||
| 572 | |||
| 573 | printf("fGenerateBitcoins = %d\n", fGenerateBitcoins); | ||
| 574 | printf("nTransactionFee = %I64d\n", nTransactionFee); | ||
| 575 | printf("addrIncoming = %s\n", addrIncoming.ToString().c_str()); | ||
| 576 | |||
| 577 | return true; | ||
| 578 | } | ||
| 579 | |||
| 580 | bool LoadWallet() | ||
| 581 | { | ||
| 582 | vector<unsigned char> vchDefaultKey; | ||
| 583 | if (!CWalletDB("cr").LoadWallet(vchDefaultKey)) | ||
| 584 | return false; | ||
| 585 | |||
| 586 | if (mapKeys.count(vchDefaultKey)) | ||
| 587 | { | ||
| 588 | // Set keyUser | ||
| 589 | keyUser.SetPubKey(vchDefaultKey); | ||
| 590 | keyUser.SetPrivKey(mapKeys[vchDefaultKey]); | ||
| 591 | } | ||
| 592 | else | ||
| 593 | { | ||
| 594 | // Create new keyUser and set as default key | ||
| 595 | keyUser.MakeNewKey(); | ||
| 596 | if (!AddKey(keyUser)) | ||
| 597 | return false; | ||
| 598 | if (!SetAddressBookName(PubKeyToAddress(keyUser.GetPubKey()), "Your Address")) | ||
| 599 | return false; | ||
| 600 | CWalletDB().WriteDefaultKey(keyUser.GetPubKey()); | ||
| 601 | } | ||
| 602 | |||
| 603 | return true; | ||
| 604 | } | ||
diff --git a/src/db.h b/src/db.h new file mode 100644 index 0000000..feaa45e --- /dev/null +++ b/src/db.h | |||
| @@ -0,0 +1,420 @@ | |||
| 1 | // Copyright (c) 2009 Satoshi Nakamoto | ||
| 2 | // Distributed under the MIT/X11 software license, see the accompanying | ||
| 3 | // file license.txt or http://www.opensource.org/licenses/mit-license.php. | ||
| 4 | |||
| 5 | #include <db_cxx.h> | ||
| 6 | class CTransaction; | ||
| 7 | class CTxIndex; | ||
| 8 | class CDiskBlockIndex; | ||
| 9 | class CDiskTxPos; | ||
| 10 | class COutPoint; | ||
| 11 | class CUser; | ||
| 12 | class CReview; | ||
| 13 | class CAddress; | ||
| 14 | class CWalletTx; | ||
| 15 | |||
| 16 | extern map<string, string> mapAddressBook; | ||
| 17 | extern bool fClient; | ||
| 18 | |||
| 19 | |||
| 20 | extern DbEnv dbenv; | ||
| 21 | extern void DBFlush(bool fShutdown); | ||
| 22 | |||
| 23 | |||
| 24 | |||
| 25 | |||
| 26 | class CDB | ||
| 27 | { | ||
| 28 | protected: | ||
| 29 | Db* pdb; | ||
| 30 | string strFile; | ||
| 31 | vector<DbTxn*> vTxn; | ||
| 32 | |||
| 33 | explicit CDB(const char* pszFile, const char* pszMode="r+", bool fTxn=false); | ||
| 34 | ~CDB() { Close(); } | ||
| 35 | public: | ||
| 36 | void Close(); | ||
| 37 | private: | ||
| 38 | CDB(const CDB&); | ||
| 39 | void operator=(const CDB&); | ||
| 40 | |||
| 41 | protected: | ||
| 42 | template<typename K, typename T> | ||
| 43 | bool Read(const K& key, T& value) | ||
| 44 | { | ||
| 45 | if (!pdb) | ||
| 46 | return false; | ||
| 47 | |||
| 48 | // Key | ||
| 49 | CDataStream ssKey(SER_DISK); | ||
| 50 | ssKey.reserve(1000); | ||
| 51 | ssKey << key; | ||
| 52 | Dbt datKey(&ssKey[0], ssKey.size()); | ||
| 53 | |||
| 54 | // Read | ||
| 55 | Dbt datValue; | ||
| 56 | datValue.set_flags(DB_DBT_MALLOC); | ||
| 57 | int ret = pdb->get(GetTxn(), &datKey, &datValue, 0); | ||
| 58 | memset(datKey.get_data(), 0, datKey.get_size()); | ||
| 59 | if (datValue.get_data() == NULL) | ||
| 60 | return false; | ||
| 61 | |||
| 62 | // Unserialize value | ||
| 63 | CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK); | ||
| 64 | ssValue >> value; | ||
| 65 | |||
| 66 | // Clear and free memory | ||
| 67 | memset(datValue.get_data(), 0, datValue.get_size()); | ||
| 68 | free(datValue.get_data()); | ||
| 69 | return (ret == 0); | ||
| 70 | } | ||
| 71 | |||
| 72 | template<typename K, typename T> | ||
| 73 | bool Write(const K& key, const T& value, bool fOverwrite=true) | ||
| 74 | { | ||
| 75 | if (!pdb) | ||
| 76 | return false; | ||
| 77 | |||
| 78 | // Key | ||
| 79 | CDataStream ssKey(SER_DISK); | ||
| 80 | ssKey.reserve(1000); | ||
| 81 | ssKey << key; | ||
| 82 | Dbt datKey(&ssKey[0], ssKey.size()); | ||
| 83 | |||
| 84 | // Value | ||
| 85 | CDataStream ssValue(SER_DISK); | ||
| 86 | ssValue.reserve(10000); | ||
| 87 | ssValue << value; | ||
| 88 | Dbt datValue(&ssValue[0], ssValue.size()); | ||
| 89 | |||
| 90 | // Write | ||
| 91 | int ret = pdb->put(GetTxn(), &datKey, &datValue, (fOverwrite ? 0 : DB_NOOVERWRITE)); | ||
| 92 | |||
| 93 | // Clear memory in case it was a private key | ||
| 94 | memset(datKey.get_data(), 0, datKey.get_size()); | ||
| 95 | memset(datValue.get_data(), 0, datValue.get_size()); | ||
| 96 | return (ret == 0); | ||
| 97 | } | ||
| 98 | |||
| 99 | template<typename K> | ||
| 100 | bool Erase(const K& key) | ||
| 101 | { | ||
| 102 | if (!pdb) | ||
| 103 | return false; | ||
| 104 | |||
| 105 | // Key | ||
| 106 | CDataStream ssKey(SER_DISK); | ||
| 107 | ssKey.reserve(1000); | ||
| 108 | ssKey << key; | ||
| 109 | Dbt datKey(&ssKey[0], ssKey.size()); | ||
| 110 | |||
| 111 | // Erase | ||
| 112 | int ret = pdb->del(GetTxn(), &datKey, 0); | ||
| 113 | |||
| 114 | // Clear memory | ||
| 115 | memset(datKey.get_data(), 0, datKey.get_size()); | ||
| 116 | return (ret == 0 || ret == DB_NOTFOUND); | ||
| 117 | } | ||
| 118 | |||
| 119 | template<typename K> | ||
| 120 | bool Exists(const K& key) | ||
| 121 | { | ||
| 122 | if (!pdb) | ||
| 123 | return false; | ||
| 124 | |||
| 125 | // Key | ||
| 126 | CDataStream ssKey(SER_DISK); | ||
| 127 | ssKey.reserve(1000); | ||
| 128 | ssKey << key; | ||
| 129 | Dbt datKey(&ssKey[0], ssKey.size()); | ||
| 130 | |||
| 131 | // Exists | ||
| 132 | int ret = pdb->exists(GetTxn(), &datKey, 0); | ||
| 133 | |||
| 134 | // Clear memory | ||
| 135 | memset(datKey.get_data(), 0, datKey.get_size()); | ||
| 136 | return (ret == 0); | ||
| 137 | } | ||
| 138 | |||
| 139 | Dbc* GetCursor() | ||
| 140 | { | ||
| 141 | if (!pdb) | ||
| 142 | return NULL; | ||
| 143 | Dbc* pcursor = NULL; | ||
| 144 | int ret = pdb->cursor(NULL, &pcursor, 0); | ||
| 145 | if (ret != 0) | ||
| 146 | return NULL; | ||
| 147 | return pcursor; | ||
| 148 | } | ||
| 149 | |||
| 150 | int ReadAtCursor(Dbc* pcursor, CDataStream& ssKey, CDataStream& ssValue, unsigned int fFlags=DB_NEXT) | ||
| 151 | { | ||
| 152 | // Read at cursor | ||
| 153 | Dbt datKey; | ||
| 154 | if (fFlags == DB_SET || fFlags == DB_SET_RANGE || fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE) | ||
| 155 | { | ||
| 156 | datKey.set_data(&ssKey[0]); | ||
| 157 | datKey.set_size(ssKey.size()); | ||
| 158 | } | ||
| 159 | Dbt datValue; | ||
| 160 | if (fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE) | ||
| 161 | { | ||
| 162 | datValue.set_data(&ssValue[0]); | ||
| 163 | datValue.set_size(ssValue.size()); | ||
| 164 | } | ||
| 165 | datKey.set_flags(DB_DBT_MALLOC); | ||
| 166 | datValue.set_flags(DB_DBT_MALLOC); | ||
| 167 | int ret = pcursor->get(&datKey, &datValue, fFlags); | ||
| 168 | if (ret != 0) | ||
| 169 | return ret; | ||
| 170 | else if (datKey.get_data() == NULL || datValue.get_data() == NULL) | ||
| 171 | return 99999; | ||
| 172 | |||
| 173 | // Convert to streams | ||
| 174 | ssKey.SetType(SER_DISK); | ||
| 175 | ssKey.clear(); | ||
| 176 | ssKey.write((char*)datKey.get_data(), datKey.get_size()); | ||
| 177 | ssValue.SetType(SER_DISK); | ||
| 178 | ssValue.clear(); | ||
| 179 | ssValue.write((char*)datValue.get_data(), datValue.get_size()); | ||
| 180 | |||
| 181 | // Clear and free memory | ||
| 182 | memset(datKey.get_data(), 0, datKey.get_size()); | ||
| 183 | memset(datValue.get_data(), 0, datValue.get_size()); | ||
| 184 | free(datKey.get_data()); | ||
| 185 | free(datValue.get_data()); | ||
| 186 | return 0; | ||
| 187 | } | ||
| 188 | |||
| 189 | DbTxn* GetTxn() | ||
| 190 | { | ||
| 191 | if (!vTxn.empty()) | ||
| 192 | return vTxn.back(); | ||
| 193 | else | ||
| 194 | return NULL; | ||
| 195 | } | ||
| 196 | |||
| 197 | public: | ||
| 198 | bool TxnBegin() | ||
| 199 | { | ||
| 200 | if (!pdb) | ||
| 201 | return false; | ||
| 202 | DbTxn* ptxn = NULL; | ||
| 203 | int ret = dbenv.txn_begin(GetTxn(), &ptxn, 0); | ||
| 204 | if (!ptxn || ret != 0) | ||
| 205 | return false; | ||
| 206 | vTxn.push_back(ptxn); | ||
| 207 | return true; | ||
| 208 | } | ||
| 209 | |||
| 210 | bool TxnCommit() | ||
| 211 | { | ||
| 212 | if (!pdb) | ||
| 213 | return false; | ||
| 214 | if (vTxn.empty()) | ||
| 215 | return false; | ||
| 216 | int ret = vTxn.back()->commit(0); | ||
| 217 | vTxn.pop_back(); | ||
| 218 | return (ret == 0); | ||
| 219 | } | ||
| 220 | |||
| 221 | bool TxnAbort() | ||
| 222 | { | ||
| 223 | if (!pdb) | ||
| 224 | return false; | ||
| 225 | if (vTxn.empty()) | ||
| 226 | return false; | ||
| 227 | int ret = vTxn.back()->abort(); | ||
| 228 | vTxn.pop_back(); | ||
| 229 | return (ret == 0); | ||
| 230 | } | ||
| 231 | |||
| 232 | bool ReadVersion(int& nVersion) | ||
| 233 | { | ||
| 234 | nVersion = 0; | ||
| 235 | return Read(string("version"), nVersion); | ||
| 236 | } | ||
| 237 | |||
| 238 | bool WriteVersion(int nVersion) | ||
| 239 | { | ||
| 240 | return Write(string("version"), nVersion); | ||
| 241 | } | ||
| 242 | }; | ||
| 243 | |||
| 244 | |||
| 245 | |||
| 246 | |||
| 247 | |||
| 248 | |||
| 249 | |||
| 250 | |||
| 251 | class CTxDB : public CDB | ||
| 252 | { | ||
| 253 | public: | ||
| 254 | CTxDB(const char* pszMode="r+", bool fTxn=false) : CDB(!fClient ? "blkindex.dat" : NULL, pszMode, fTxn) { } | ||
| 255 | private: | ||
| 256 | CTxDB(const CTxDB&); | ||
| 257 | void operator=(const CTxDB&); | ||
| 258 | public: | ||
| 259 | bool ReadTxIndex(uint256 hash, CTxIndex& txindex); | ||
| 260 | bool UpdateTxIndex(uint256 hash, const CTxIndex& txindex); | ||
| 261 | bool AddTxIndex(const CTransaction& tx, const CDiskTxPos& pos, int nHeight); | ||
| 262 | bool EraseTxIndex(const CTransaction& tx); | ||
| 263 | bool ContainsTx(uint256 hash); | ||
| 264 | bool ReadOwnerTxes(uint160 hash160, int nHeight, vector<CTransaction>& vtx); | ||
| 265 | bool ReadDiskTx(uint256 hash, CTransaction& tx, CTxIndex& txindex); | ||
| 266 | bool ReadDiskTx(uint256 hash, CTransaction& tx); | ||
| 267 | bool ReadDiskTx(COutPoint outpoint, CTransaction& tx, CTxIndex& txindex); | ||
| 268 | bool ReadDiskTx(COutPoint outpoint, CTransaction& tx); | ||
| 269 | bool WriteBlockIndex(const CDiskBlockIndex& blockindex); | ||
| 270 | bool EraseBlockIndex(uint256 hash); | ||
| 271 | bool ReadHashBestChain(uint256& hashBestChain); | ||
| 272 | bool WriteHashBestChain(uint256 hashBestChain); | ||
| 273 | bool LoadBlockIndex(); | ||
| 274 | }; | ||
| 275 | |||
| 276 | |||
| 277 | |||
| 278 | |||
| 279 | |||
| 280 | class CReviewDB : public CDB | ||
| 281 | { | ||
| 282 | public: | ||
| 283 | CReviewDB(const char* pszMode="r+", bool fTxn=false) : CDB("reviews.dat", pszMode, fTxn) { } | ||
| 284 | private: | ||
| 285 | CReviewDB(const CReviewDB&); | ||
| 286 | void operator=(const CReviewDB&); | ||
| 287 | public: | ||
| 288 | bool ReadUser(uint256 hash, CUser& user) | ||
| 289 | { | ||
| 290 | return Read(make_pair(string("user"), hash), user); | ||
| 291 | } | ||
| 292 | |||
| 293 | bool WriteUser(uint256 hash, const CUser& user) | ||
| 294 | { | ||
| 295 | return Write(make_pair(string("user"), hash), user); | ||
| 296 | } | ||
| 297 | |||
| 298 | bool ReadReviews(uint256 hash, vector<CReview>& vReviews); | ||
| 299 | bool WriteReviews(uint256 hash, const vector<CReview>& vReviews); | ||
| 300 | }; | ||
| 301 | |||
| 302 | |||
| 303 | |||
| 304 | |||
| 305 | |||
| 306 | class CMarketDB : public CDB | ||
| 307 | { | ||
| 308 | public: | ||
| 309 | CMarketDB(const char* pszMode="r+", bool fTxn=false) : CDB("market.dat", pszMode, fTxn) { } | ||
| 310 | private: | ||
| 311 | CMarketDB(const CMarketDB&); | ||
| 312 | void operator=(const CMarketDB&); | ||
| 313 | }; | ||
| 314 | |||
| 315 | |||
| 316 | |||
| 317 | |||
| 318 | |||
| 319 | class CAddrDB : public CDB | ||
| 320 | { | ||
| 321 | public: | ||
| 322 | CAddrDB(const char* pszMode="r+", bool fTxn=false) : CDB("addr.dat", pszMode, fTxn) { } | ||
| 323 | private: | ||
| 324 | CAddrDB(const CAddrDB&); | ||
| 325 | void operator=(const CAddrDB&); | ||
| 326 | public: | ||
| 327 | bool WriteAddress(const CAddress& addr); | ||
| 328 | bool LoadAddresses(); | ||
| 329 | }; | ||
| 330 | |||
| 331 | bool LoadAddresses(); | ||
| 332 | |||
| 333 | |||
| 334 | |||
| 335 | |||
| 336 | |||
| 337 | class CWalletDB : public CDB | ||
| 338 | { | ||
| 339 | public: | ||
| 340 | CWalletDB(const char* pszMode="r+", bool fTxn=false) : CDB("wallet.dat", pszMode, fTxn) { } | ||
| 341 | private: | ||
| 342 | CWalletDB(const CWalletDB&); | ||
| 343 | void operator=(const CWalletDB&); | ||
| 344 | public: | ||
| 345 | bool ReadName(const string& strAddress, string& strName) | ||
| 346 | { | ||
| 347 | strName = ""; | ||
| 348 | return Read(make_pair(string("name"), strAddress), strName); | ||
| 349 | } | ||
| 350 | |||
| 351 | bool WriteName(const string& strAddress, const string& strName) | ||
| 352 | { | ||
| 353 | mapAddressBook[strAddress] = strName; | ||
| 354 | return Write(make_pair(string("name"), strAddress), strName); | ||
| 355 | } | ||
| 356 | |||
| 357 | bool EraseName(const string& strAddress) | ||
| 358 | { | ||
| 359 | mapAddressBook.erase(strAddress); | ||
| 360 | return Erase(make_pair(string("name"), strAddress)); | ||
| 361 | } | ||
| 362 | |||
| 363 | bool ReadTx(uint256 hash, CWalletTx& wtx) | ||
| 364 | { | ||
| 365 | return Read(make_pair(string("tx"), hash), wtx); | ||
| 366 | } | ||
| 367 | |||
| 368 | bool WriteTx(uint256 hash, const CWalletTx& wtx) | ||
| 369 | { | ||
| 370 | return Write(make_pair(string("tx"), hash), wtx); | ||
| 371 | } | ||
| 372 | |||
| 373 | bool EraseTx(uint256 hash) | ||
| 374 | { | ||
| 375 | return Erase(make_pair(string("tx"), hash)); | ||
| 376 | } | ||
| 377 | |||
| 378 | bool ReadKey(const vector<unsigned char>& vchPubKey, CPrivKey& vchPrivKey) | ||
| 379 | { | ||
| 380 | vchPrivKey.clear(); | ||
| 381 | return Read(make_pair(string("key"), vchPubKey), vchPrivKey); | ||
| 382 | } | ||
| 383 | |||
| 384 | bool WriteKey(const vector<unsigned char>& vchPubKey, const CPrivKey& vchPrivKey) | ||
| 385 | { | ||
| 386 | return Write(make_pair(string("key"), vchPubKey), vchPrivKey, false); | ||
| 387 | } | ||
| 388 | |||
| 389 | bool ReadDefaultKey(vector<unsigned char>& vchPubKey) | ||
| 390 | { | ||
| 391 | vchPubKey.clear(); | ||
| 392 | return Read(string("defaultkey"), vchPubKey); | ||
| 393 | } | ||
| 394 | |||
| 395 | bool WriteDefaultKey(const vector<unsigned char>& vchPubKey) | ||
| 396 | { | ||
| 397 | return Write(string("defaultkey"), vchPubKey); | ||
| 398 | } | ||
| 399 | |||
| 400 | template<typename T> | ||
| 401 | bool ReadSetting(const string& strKey, T& value) | ||
| 402 | { | ||
| 403 | return Read(make_pair(string("setting"), strKey), value); | ||
| 404 | } | ||
| 405 | |||
| 406 | template<typename T> | ||
| 407 | bool WriteSetting(const string& strKey, const T& value) | ||
| 408 | { | ||
| 409 | return Write(make_pair(string("setting"), strKey), value); | ||
| 410 | } | ||
| 411 | |||
| 412 | bool LoadWallet(vector<unsigned char>& vchDefaultKeyRet); | ||
| 413 | }; | ||
| 414 | |||
| 415 | bool LoadWallet(); | ||
| 416 | |||
| 417 | inline bool SetAddressBookName(const string& strAddress, const string& strName) | ||
| 418 | { | ||
| 419 | return CWalletDB().WriteName(strAddress, strName); | ||
| 420 | } | ||
diff --git a/src/headers.h b/src/headers.h new file mode 100644 index 0000000..e253803 --- /dev/null +++ b/src/headers.h | |||
| @@ -0,0 +1,111 @@ | |||
| 1 | // Copyright (c) 2009 Satoshi Nakamoto | ||
| 2 | // Distributed under the MIT/X11 software license, see the accompanying | ||
| 3 | // file license.txt or http://www.opensource.org/licenses/mit-license.php. | ||
| 4 | |||
| 5 | #ifdef _MSC_VER | ||
| 6 | #pragma warning(disable:4786) | ||
| 7 | #pragma warning(disable:4804) | ||
| 8 | #pragma warning(disable:4717) | ||
| 9 | #endif | ||
| 10 | |||
| 11 | #ifdef _WIN32 | ||
| 12 | // ---- Windows build (GUI wallet + miner) ---- | ||
| 13 | #ifdef _WIN32_WINNT | ||
| 14 | #undef _WIN32_WINNT | ||
| 15 | #endif | ||
| 16 | #define _WIN32_WINNT 0x0601 | ||
| 17 | #define WIN32_LEAN_AND_MEAN 1 | ||
| 18 | // winsock2.h must come before windows.h/wx to avoid pulling in winsock 1 | ||
| 19 | #include <winsock2.h> | ||
| 20 | #include <ws2tcpip.h> | ||
| 21 | #include <mswsock.h> | ||
| 22 | #include <wx/wx.h> | ||
| 23 | #include <wx/clipbrd.h> | ||
| 24 | #include <wx/snglinst.h> | ||
| 25 | #include <openssl/ecdsa.h> | ||
| 26 | #include <openssl/evp.h> | ||
| 27 | #include <openssl/rand.h> | ||
| 28 | #include <openssl/sha.h> | ||
| 29 | #include <openssl/ripemd.h> | ||
| 30 | #include <windows.h> | ||
| 31 | #include <stdio.h> | ||
| 32 | #include <stdlib.h> | ||
| 33 | #include <io.h> | ||
| 34 | #include <direct.h> | ||
| 35 | #include <math.h> | ||
| 36 | #include <limits.h> | ||
| 37 | #include <float.h> | ||
| 38 | #include <assert.h> | ||
| 39 | #include <process.h> | ||
| 40 | #include <malloc.h> | ||
| 41 | #include <memory> | ||
| 42 | #else | ||
| 43 | // ---- Linux/POSIX headless build (bitflash-node) ---- | ||
| 44 | #include "compat.h" | ||
| 45 | #include <openssl/ecdsa.h> | ||
| 46 | #include <openssl/evp.h> | ||
| 47 | #include <openssl/rand.h> | ||
| 48 | #include <openssl/sha.h> | ||
| 49 | #include <openssl/ripemd.h> | ||
| 50 | #include <stdio.h> | ||
| 51 | #include <stdlib.h> | ||
| 52 | #include <math.h> | ||
| 53 | #include <limits.h> | ||
| 54 | #include <float.h> | ||
| 55 | #include <assert.h> | ||
| 56 | #include <memory> | ||
| 57 | #endif | ||
| 58 | #define BOUNDSCHECK 1 | ||
| 59 | #include <sstream> | ||
| 60 | #include <string> | ||
| 61 | #include <vector> | ||
| 62 | #include <list> | ||
| 63 | #include <deque> | ||
| 64 | #include <map> | ||
| 65 | #include <set> | ||
| 66 | #include <algorithm> | ||
| 67 | #include <numeric> | ||
| 68 | #include <array> | ||
| 69 | #include <boost/foreach.hpp> | ||
| 70 | #pragma hdrstop | ||
| 71 | using namespace std; | ||
| 72 | |||
| 73 | // In 2009 windows.h provided min/max macros accepting mixed types; wxWidgets 3 | ||
| 74 | // defines NOMINMAX, so we restore mixed-type versions here. For matching types, | ||
| 75 | // std::min/std::max remain preferred during overload resolution. | ||
| 76 | template<typename T1, typename T2> | ||
| 77 | inline typename std::common_type<T1, T2>::type min(const T1& a, const T2& b) | ||
| 78 | { | ||
| 79 | return (a < b) ? a : b; | ||
| 80 | } | ||
| 81 | template<typename T1, typename T2> | ||
| 82 | inline typename std::common_type<T1, T2>::type max(const T1& a, const T2& b) | ||
| 83 | { | ||
| 84 | return (a > b) ? a : b; | ||
| 85 | } | ||
| 86 | |||
| 87 | |||
| 88 | |||
| 89 | #include "serialize.h" | ||
| 90 | #include "uint256.h" | ||
| 91 | #include "util.h" | ||
| 92 | #include "key.h" | ||
| 93 | #include "bignum.h" | ||
| 94 | #include "base58.h" | ||
| 95 | #include "script.h" | ||
| 96 | #include "db.h" | ||
| 97 | #include "net.h" | ||
| 98 | #include "irc.h" | ||
| 99 | #include "nostr.h" | ||
| 100 | #include "randomx_pow.h" | ||
| 101 | #include "main.h" | ||
| 102 | #include "market.h" | ||
| 103 | #ifdef _WIN32 | ||
| 104 | #include "uibase.h" | ||
| 105 | #include "ui.h" | ||
| 106 | #else | ||
| 107 | // Headless build has no GUI; the core only calls a couple of UI helpers, | ||
| 108 | // provided by headless.cpp (a no-op repaint and a timestamp formatter). | ||
| 109 | void MainFrameRepaint(); | ||
| 110 | string DateTimeStr(int64 nTime); | ||
| 111 | #endif | ||
diff --git a/src/headless.cpp b/src/headless.cpp new file mode 100644 index 0000000..94597f1 --- /dev/null +++ b/src/headless.cpp | |||
| @@ -0,0 +1,177 @@ | |||
| 1 | // Copyright (c) 2026 Bitflash developers | ||
| 2 | // Distributed under the MIT/X11 software license. | ||
| 3 | // | ||
| 4 | // Headless entry point for the Linux node/miner `bitflash-node`. Replaces the | ||
| 5 | // wxWidgets GUI (ui.cpp) with a command-line daemon: it loads the chain and | ||
| 6 | // wallet, starts the P2P/Nostr node (which auto-discovers .btf peers through | ||
| 7 | // the rendezvous relay), and optionally mines with RandomX. No GUI, no wx. | ||
| 8 | // | ||
| 9 | // ./bitflash-node -gen mine with the CPU, auto-connect peers | ||
| 10 | // ./bitflash-node -gen -datadir=/path use a specific data directory | ||
| 11 | // ./bitflash-node -rvrelay=host:port use a specific rendezvous relay | ||
| 12 | // ./bitflash-node -connectbtf=<addr>.btf pin a specific peer | ||
| 13 | // ./bitflash-node -solomine -gen mine without waiting for a peer (test) | ||
| 14 | |||
| 15 | #include "headers.h" | ||
| 16 | #include <csignal> | ||
| 17 | |||
| 18 | // ---- UI hooks the core references, provided here as headless equivalents ---- | ||
| 19 | |||
| 20 | // The core asks the GUI to repaint on new blocks/transactions; nothing to do. | ||
| 21 | void MainFrameRepaint() {} | ||
| 22 | |||
| 23 | // Wallet address book -- defined in ui.cpp on Windows; the core (db.cpp) reads | ||
| 24 | // and writes it, so the headless build must provide the definition. | ||
| 25 | map<string, string> mapAddressBook; | ||
| 26 | |||
| 27 | // Format a unix timestamp for transaction listings (ui.cpp used wxDateTime). | ||
| 28 | string DateTimeStr(int64 nTime) | ||
| 29 | { | ||
| 30 | time_t t = (time_t)nTime; | ||
| 31 | struct tm* ptm = localtime(&t); | ||
| 32 | if (!ptm) | ||
| 33 | return ""; | ||
| 34 | char buf[64]; | ||
| 35 | strftime(buf, sizeof(buf), "%m/%d/%y %H:%M", ptm); | ||
| 36 | return string(buf); | ||
| 37 | } | ||
| 38 | |||
| 39 | |||
| 40 | // ---- argument parsing (mirrors ui.cpp's ParseParameters) ---- | ||
| 41 | static map<string, string> ParseParameters(int argc, char* argv[]) | ||
| 42 | { | ||
| 43 | map<string, string> mapArgs; | ||
| 44 | for (int i = 0; i < argc; i++) | ||
| 45 | { | ||
| 46 | string s = argv[i]; | ||
| 47 | string val; | ||
| 48 | size_t eq = s.find('='); | ||
| 49 | if (eq != string::npos) | ||
| 50 | { | ||
| 51 | val = s.substr(eq + 1); | ||
| 52 | s = s.substr(0, eq); | ||
| 53 | } | ||
| 54 | for (size_t j = 0; j < s.size(); j++) | ||
| 55 | s[j] = (char)tolower((unsigned char)s[j]); | ||
| 56 | if (!s.empty() && s[0] == '-') | ||
| 57 | s[0] = '/'; | ||
| 58 | mapArgs[s] = val; | ||
| 59 | } | ||
| 60 | return mapArgs; | ||
| 61 | } | ||
| 62 | |||
| 63 | |||
| 64 | static void HandleSignal(int) | ||
| 65 | { | ||
| 66 | fShutdown = true; | ||
| 67 | } | ||
| 68 | |||
| 69 | |||
| 70 | int main(int argc, char* argv[]) | ||
| 71 | { | ||
| 72 | map<string, string> mapArgs = ParseParameters(argc, argv); | ||
| 73 | |||
| 74 | if (mapArgs.count("/?") || mapArgs.count("/help") || mapArgs.count("/h")) | ||
| 75 | { | ||
| 76 | fprintf(stderr, | ||
| 77 | "Bitflash headless node\n" | ||
| 78 | "Usage: %s [options]\n" | ||
| 79 | " -gen generate coins (mine with RandomX)\n" | ||
| 80 | " -datadir=<dir> data directory (default ~/.bitflash)\n" | ||
| 81 | " -port=<n> P2P listen port (default 8433)\n" | ||
| 82 | " -rvrelay=host:port rendezvous meeting relay (has a seed default)\n" | ||
| 83 | " -connectbtf=<a>.btf keep a connection to a specific .btf peer\n" | ||
| 84 | " -solomine mine without waiting for a peer (testing)\n" | ||
| 85 | " -debug verbose logging\n", | ||
| 86 | argv[0]); | ||
| 87 | return 0; | ||
| 88 | } | ||
| 89 | |||
| 90 | // Parameters (same set the Windows UI honors) | ||
| 91 | if (mapArgs.count("/datadir")) | ||
| 92 | strSetDataDir = mapArgs["/datadir"]; | ||
| 93 | if (mapArgs.count("/port")) | ||
| 94 | nListenPort = htons(atoi(mapArgs["/port"].c_str())); | ||
| 95 | if (mapArgs.count("/proxy")) | ||
| 96 | addrProxy = CAddress(mapArgs["/proxy"].c_str()); | ||
| 97 | if (mapArgs.count("/rvrelay")) | ||
| 98 | strBtfMeetingRelay = mapArgs["/rvrelay"]; | ||
| 99 | if (mapArgs.count("/connectbtf")) | ||
| 100 | strBtfConnect = mapArgs["/connectbtf"]; | ||
| 101 | if (mapArgs.count("/debug")) | ||
| 102 | fDebug = true; | ||
| 103 | if (mapArgs.count("/solomine")) | ||
| 104 | fSoloMineTest = true; | ||
| 105 | if (mapArgs.count("/gen")) | ||
| 106 | fGenerateBitcoins = mapArgs["/gen"].empty() ? true : atoi(mapArgs["/gen"].c_str()); | ||
| 107 | |||
| 108 | printf("\nBitflash headless node starting\n"); | ||
| 109 | |||
| 110 | // | ||
| 111 | // Load data files (mirror of the Windows OnInit2 startup) | ||
| 112 | // | ||
| 113 | printf("Loading addresses...\n"); | ||
| 114 | if (!LoadAddresses()) | ||
| 115 | printf("Error loading addr.dat\n"); | ||
| 116 | |||
| 117 | printf("Loading block index...\n"); | ||
| 118 | if (!LoadBlockIndex()) | ||
| 119 | { | ||
| 120 | printf("Error loading blkindex.dat\n"); | ||
| 121 | return 1; | ||
| 122 | } | ||
| 123 | |||
| 124 | printf("Loading wallet...\n"); | ||
| 125 | if (!LoadWallet()) | ||
| 126 | { | ||
| 127 | printf("Error loading wallet.dat\n"); | ||
| 128 | return 1; | ||
| 129 | } | ||
| 130 | |||
| 131 | printf("Done loading. nBestHeight=%d, wallet keys=%d\n", | ||
| 132 | nBestHeight, (int)mapKeys.size()); | ||
| 133 | |||
| 134 | // Rebroadcast any wallet transactions not yet in a block | ||
| 135 | ReacceptWalletTransactions(); | ||
| 136 | |||
| 137 | // | ||
| 138 | // Start the node (P2P + Nostr discovery + .btf rendezvous) | ||
| 139 | // | ||
| 140 | string strErrors; | ||
| 141 | if (!StartNode(strErrors)) | ||
| 142 | { | ||
| 143 | printf("StartNode failed: %s\n", strErrors.c_str()); | ||
| 144 | return 1; | ||
| 145 | } | ||
| 146 | |||
| 147 | // | ||
| 148 | // Start mining if requested | ||
| 149 | // | ||
| 150 | if (fGenerateBitcoins) | ||
| 151 | { | ||
| 152 | if (_beginthread(ThreadBitcoinMiner, 0, NULL) == (uintptr_t)-1) | ||
| 153 | printf("Error: _beginthread(ThreadBitcoinMiner) failed\n"); | ||
| 154 | else | ||
| 155 | printf("Mining enabled (RandomX, CPU)\n"); | ||
| 156 | } | ||
| 157 | else | ||
| 158 | { | ||
| 159 | printf("Mining disabled (pass -gen to mine)\n"); | ||
| 160 | } | ||
| 161 | |||
| 162 | // | ||
| 163 | // Run until interrupted | ||
| 164 | // | ||
| 165 | signal(SIGINT, HandleSignal); | ||
| 166 | signal(SIGTERM, HandleSignal); | ||
| 167 | printf("Bitflash node running. Press Ctrl-C to stop.\n"); | ||
| 168 | |||
| 169 | while (!fShutdown) | ||
| 170 | Sleep(500); | ||
| 171 | |||
| 172 | printf("Shutting down...\n"); | ||
| 173 | StopNode(); | ||
| 174 | Sleep(500); | ||
| 175 | printf("Bitflash node stopped.\n"); | ||
| 176 | return 0; | ||
| 177 | } | ||
diff --git a/src/irc.cpp b/src/irc.cpp new file mode 100644 index 0000000..ff82c66 --- /dev/null +++ b/src/irc.cpp | |||
| @@ -0,0 +1,271 @@ | |||
| 1 | // Copyright (c) 2009 Satoshi Nakamoto | ||
| 2 | // Distributed under the MIT/X11 software license, see the accompanying | ||
| 3 | // file license.txt or http://www.opensource.org/licenses/mit-license.php. | ||
| 4 | |||
| 5 | #include "headers.h" | ||
| 6 | |||
| 7 | |||
| 8 | |||
| 9 | |||
| 10 | #pragma pack(1) | ||
| 11 | struct ircaddr | ||
| 12 | { | ||
| 13 | int ip; | ||
| 14 | short port; | ||
| 15 | }; | ||
| 16 | |||
| 17 | string EncodeAddress(const CAddress& addr) | ||
| 18 | { | ||
| 19 | struct ircaddr tmp; | ||
| 20 | tmp.ip = addr.ip; | ||
| 21 | tmp.port = addr.port; | ||
| 22 | |||
| 23 | vector<unsigned char> vch(UBEGIN(tmp), UEND(tmp)); | ||
| 24 | return string("u") + EncodeBase58Check(vch); | ||
| 25 | } | ||
| 26 | |||
| 27 | bool DecodeAddress(string str, CAddress& addr) | ||
| 28 | { | ||
| 29 | vector<unsigned char> vch; | ||
| 30 | if (!DecodeBase58Check(str.substr(1), vch)) | ||
| 31 | return false; | ||
| 32 | |||
| 33 | struct ircaddr tmp; | ||
| 34 | if (vch.size() != sizeof(tmp)) | ||
| 35 | return false; | ||
| 36 | memcpy(&tmp, &vch[0], sizeof(tmp)); | ||
| 37 | |||
| 38 | addr = CAddress(tmp.ip, tmp.port); | ||
| 39 | return true; | ||
| 40 | } | ||
| 41 | |||
| 42 | |||
| 43 | |||
| 44 | |||
| 45 | |||
| 46 | |||
| 47 | static bool Send(SOCKET hSocket, const char* pszSend) | ||
| 48 | { | ||
| 49 | if (strstr(pszSend, "PONG") != pszSend) | ||
| 50 | printf("SENDING: %s\n", pszSend); | ||
| 51 | const char* psz = pszSend; | ||
| 52 | const char* pszEnd = psz + strlen(psz); | ||
| 53 | while (psz < pszEnd) | ||
| 54 | { | ||
| 55 | int ret = send(hSocket, psz, pszEnd - psz, 0); | ||
| 56 | if (ret < 0) | ||
| 57 | return false; | ||
| 58 | psz += ret; | ||
| 59 | } | ||
| 60 | return true; | ||
| 61 | } | ||
| 62 | |||
| 63 | bool RecvLine(SOCKET hSocket, string& strLine) | ||
| 64 | { | ||
| 65 | strLine = ""; | ||
| 66 | loop | ||
| 67 | { | ||
| 68 | char c; | ||
| 69 | int nBytes = recv(hSocket, &c, 1, 0); | ||
| 70 | if (nBytes > 0) | ||
| 71 | { | ||
| 72 | if (c == '\n') | ||
| 73 | continue; | ||
| 74 | if (c == '\r') | ||
| 75 | return true; | ||
| 76 | strLine += c; | ||
| 77 | } | ||
| 78 | else if (nBytes <= 0) | ||
| 79 | { | ||
| 80 | if (!strLine.empty()) | ||
| 81 | return true; | ||
| 82 | // socket closed | ||
| 83 | printf("IRC socket closed\n"); | ||
| 84 | return false; | ||
| 85 | } | ||
| 86 | else | ||
| 87 | { | ||
| 88 | // socket error | ||
| 89 | int nErr = WSAGetLastError(); | ||
| 90 | if (nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS) | ||
| 91 | { | ||
| 92 | printf("IRC recv failed: %d\n", nErr); | ||
| 93 | return false; | ||
| 94 | } | ||
| 95 | } | ||
| 96 | } | ||
| 97 | } | ||
| 98 | |||
| 99 | bool RecvLineIRC(SOCKET hSocket, string& strLine) | ||
| 100 | { | ||
| 101 | loop | ||
| 102 | { | ||
| 103 | bool fRet = RecvLine(hSocket, strLine); | ||
| 104 | if (fRet) | ||
| 105 | { | ||
| 106 | if (fShutdown) | ||
| 107 | return false; | ||
| 108 | vector<string> vWords; | ||
| 109 | ParseString(strLine, ' ', vWords); | ||
| 110 | if (vWords[0] == "PING") | ||
| 111 | { | ||
| 112 | strLine[1] = 'O'; | ||
| 113 | strLine += '\r'; | ||
| 114 | Send(hSocket, strLine.c_str()); | ||
| 115 | continue; | ||
| 116 | } | ||
| 117 | } | ||
| 118 | return fRet; | ||
| 119 | } | ||
| 120 | } | ||
| 121 | |||
| 122 | bool RecvUntil(SOCKET hSocket, const char* psz1, const char* psz2=NULL, const char* psz3=NULL) | ||
| 123 | { | ||
| 124 | loop | ||
| 125 | { | ||
| 126 | string strLine; | ||
| 127 | if (!RecvLineIRC(hSocket, strLine)) | ||
| 128 | return false; | ||
| 129 | printf("IRC %s\n", strLine.c_str()); | ||
| 130 | if (psz1 && strLine.find(psz1) != -1) | ||
| 131 | return true; | ||
| 132 | if (psz2 && strLine.find(psz2) != -1) | ||
| 133 | return true; | ||
| 134 | if (psz3 && strLine.find(psz3) != -1) | ||
| 135 | return true; | ||
| 136 | } | ||
| 137 | } | ||
| 138 | |||
| 139 | |||
| 140 | |||
| 141 | |||
| 142 | bool fRestartIRCSeed = false; | ||
| 143 | |||
| 144 | void ThreadIRCSeed(void* parg) | ||
| 145 | { | ||
| 146 | // IRC peer discovery disabled: the 2009 IRC network no longer exists (and | ||
| 147 | // what answers today crashes the parser). Replaced by Nostr relay | ||
| 148 | // discovery. | ||
| 149 | printf("ThreadIRCSeed: IRC peer discovery disabled (using Nostr)\n"); | ||
| 150 | return; | ||
| 151 | |||
| 152 | loop | ||
| 153 | { | ||
| 154 | struct hostent* phostent = gethostbyname("chat.freenode.net"); | ||
| 155 | CAddress addrConnect(*(u_long*)phostent->h_addr_list[0], htons(6667)); | ||
| 156 | |||
| 157 | SOCKET hSocket; | ||
| 158 | if (!ConnectSocket(addrConnect, hSocket)) | ||
| 159 | { | ||
| 160 | printf("IRC connect failed\n"); | ||
| 161 | return; | ||
| 162 | } | ||
| 163 | |||
| 164 | if (!RecvUntil(hSocket, "Found your hostname", "using your IP address instead", "Couldn't look up your hostname")) | ||
| 165 | { | ||
| 166 | closesocket(hSocket); | ||
| 167 | return; | ||
| 168 | } | ||
| 169 | |||
| 170 | string strMyName = EncodeAddress(addrLocalHost); | ||
| 171 | |||
| 172 | if (!addrLocalHost.IsRoutable()) | ||
| 173 | strMyName = strprintf("x%u", GetRand(1000000000)); | ||
| 174 | |||
| 175 | Send(hSocket, strprintf("NICK %s\r", strMyName.c_str()).c_str()); | ||
| 176 | Send(hSocket, strprintf("USER %s 8 * : %s\r", strMyName.c_str(), strMyName.c_str()).c_str()); | ||
| 177 | |||
| 178 | if (!RecvUntil(hSocket, " 004 ")) | ||
| 179 | { | ||
| 180 | closesocket(hSocket); | ||
| 181 | return; | ||
| 182 | } | ||
| 183 | Sleep(500); | ||
| 184 | |||
| 185 | Send(hSocket, "JOIN #bitcoin\r"); | ||
| 186 | Send(hSocket, "WHO #bitcoin\r"); | ||
| 187 | |||
| 188 | while (!fRestartIRCSeed) | ||
| 189 | { | ||
| 190 | string strLine; | ||
| 191 | if (fShutdown || !RecvLineIRC(hSocket, strLine)) | ||
| 192 | { | ||
| 193 | closesocket(hSocket); | ||
| 194 | return; | ||
| 195 | } | ||
| 196 | if (strLine.empty() || strLine[0] != ':') | ||
| 197 | continue; | ||
| 198 | printf("IRC %s\n", strLine.c_str()); | ||
| 199 | |||
| 200 | vector<string> vWords; | ||
| 201 | ParseString(strLine, ' ', vWords); | ||
| 202 | if (vWords.size() < 2) | ||
| 203 | continue; | ||
| 204 | |||
| 205 | char pszName[10000]; | ||
| 206 | pszName[0] = '\0'; | ||
| 207 | |||
| 208 | if (vWords[1] == "352" && vWords.size() >= 8) | ||
| 209 | { | ||
| 210 | // index 7 is limited to 16 characters | ||
| 211 | // could get full length name at index 10, but would be different from join messages | ||
| 212 | strcpy(pszName, vWords[7].c_str()); | ||
| 213 | printf("GOT WHO: [%s] ", pszName); | ||
| 214 | } | ||
| 215 | |||
| 216 | if (vWords[1] == "JOIN") | ||
| 217 | { | ||
| 218 | // :username!username@50000007.F000000B.90000002.IP JOIN :#channelname | ||
| 219 | strcpy(pszName, vWords[0].c_str() + 1); | ||
| 220 | if (strchr(pszName, '!')) | ||
| 221 | *strchr(pszName, '!') = '\0'; | ||
| 222 | printf("GOT JOIN: [%s] ", pszName); | ||
| 223 | } | ||
| 224 | |||
| 225 | if (pszName[0] == 'u') | ||
| 226 | { | ||
| 227 | CAddress addr; | ||
| 228 | if (DecodeAddress(pszName, addr)) | ||
| 229 | { | ||
| 230 | CAddrDB addrdb; | ||
| 231 | if (AddAddress(addrdb, addr)) | ||
| 232 | printf("new "); | ||
| 233 | addr.print(); | ||
| 234 | } | ||
| 235 | else | ||
| 236 | { | ||
| 237 | printf("decode failed\n"); | ||
| 238 | } | ||
| 239 | } | ||
| 240 | } | ||
| 241 | |||
| 242 | fRestartIRCSeed = false; | ||
| 243 | closesocket(hSocket); | ||
| 244 | } | ||
| 245 | } | ||
| 246 | |||
| 247 | |||
| 248 | |||
| 249 | |||
| 250 | |||
| 251 | |||
| 252 | |||
| 253 | |||
| 254 | |||
| 255 | |||
| 256 | #ifdef TEST | ||
| 257 | int main(int argc, char *argv[]) | ||
| 258 | { | ||
| 259 | WSADATA wsadata; | ||
| 260 | if (WSAStartup(MAKEWORD(2,2), &wsadata) != NO_ERROR) | ||
| 261 | { | ||
| 262 | printf("Error at WSAStartup()\n"); | ||
| 263 | return false; | ||
| 264 | } | ||
| 265 | |||
| 266 | ThreadIRCSeed(NULL); | ||
| 267 | |||
| 268 | WSACleanup(); | ||
| 269 | return 0; | ||
| 270 | } | ||
| 271 | #endif | ||
diff --git a/src/irc.h b/src/irc.h new file mode 100644 index 0000000..1ae4ffc --- /dev/null +++ b/src/irc.h | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | // Copyright (c) 2009 Satoshi Nakamoto | ||
| 2 | // Distributed under the MIT/X11 software license, see the accompanying | ||
| 3 | // file license.txt or http://www.opensource.org/licenses/mit-license.php. | ||
| 4 | |||
| 5 | extern bool RecvLine(SOCKET hSocket, string& strLine); | ||
| 6 | extern void ThreadIRCSeed(void* parg); | ||
| 7 | extern bool fRestartIRCSeed; | ||
diff --git a/src/key.h b/src/key.h new file mode 100644 index 0000000..26e1ae2 --- /dev/null +++ b/src/key.h | |||
| @@ -0,0 +1,156 @@ | |||
| 1 | // Copyright (c) 2009 Satoshi Nakamoto | ||
| 2 | // Distributed under the MIT/X11 software license, see the accompanying | ||
| 3 | // file license.txt or http://www.opensource.org/licenses/mit-license.php. | ||
| 4 | |||
| 5 | |||
| 6 | // secp160k1 | ||
| 7 | // const unsigned int PRIVATE_KEY_SIZE = 192; | ||
| 8 | // const unsigned int PUBLIC_KEY_SIZE = 41; | ||
| 9 | // const unsigned int SIGNATURE_SIZE = 48; | ||
| 10 | // | ||
| 11 | // secp192k1 | ||
| 12 | // const unsigned int PRIVATE_KEY_SIZE = 222; | ||
| 13 | // const unsigned int PUBLIC_KEY_SIZE = 49; | ||
| 14 | // const unsigned int SIGNATURE_SIZE = 57; | ||
| 15 | // | ||
| 16 | // secp224k1 | ||
| 17 | // const unsigned int PRIVATE_KEY_SIZE = 250; | ||
| 18 | // const unsigned int PUBLIC_KEY_SIZE = 57; | ||
| 19 | // const unsigned int SIGNATURE_SIZE = 66; | ||
| 20 | // | ||
| 21 | // secp256k1: | ||
| 22 | // const unsigned int PRIVATE_KEY_SIZE = 279; | ||
| 23 | // const unsigned int PUBLIC_KEY_SIZE = 65; | ||
| 24 | // const unsigned int SIGNATURE_SIZE = 72; | ||
| 25 | // | ||
| 26 | // see www.keylength.com | ||
| 27 | // script supports up to 75 for single byte push | ||
| 28 | |||
| 29 | |||
| 30 | |||
| 31 | class key_error : public std::runtime_error | ||
| 32 | { | ||
| 33 | public: | ||
| 34 | explicit key_error(const std::string& str) : std::runtime_error(str) {} | ||
| 35 | }; | ||
| 36 | |||
| 37 | |||
| 38 | // secure_allocator is defined is serialize.h | ||
| 39 | typedef vector<unsigned char, secure_allocator<unsigned char> > CPrivKey; | ||
| 40 | |||
| 41 | |||
| 42 | |||
| 43 | class CKey | ||
| 44 | { | ||
| 45 | protected: | ||
| 46 | EC_KEY* pkey; | ||
| 47 | |||
| 48 | public: | ||
| 49 | CKey() | ||
| 50 | { | ||
| 51 | pkey = EC_KEY_new_by_curve_name(NID_secp256k1); | ||
| 52 | if (pkey == NULL) | ||
| 53 | throw key_error("CKey::CKey() : EC_KEY_new_by_curve_name failed"); | ||
| 54 | } | ||
| 55 | |||
| 56 | CKey(const CKey& b) | ||
| 57 | { | ||
| 58 | pkey = EC_KEY_dup(b.pkey); | ||
| 59 | if (pkey == NULL) | ||
| 60 | throw key_error("CKey::CKey(const CKey&) : EC_KEY_dup failed"); | ||
| 61 | } | ||
| 62 | |||
| 63 | CKey& operator=(const CKey& b) | ||
| 64 | { | ||
| 65 | if (!EC_KEY_copy(pkey, b.pkey)) | ||
| 66 | throw key_error("CKey::operator=(const CKey&) : EC_KEY_copy failed"); | ||
| 67 | return (*this); | ||
| 68 | } | ||
| 69 | |||
| 70 | ~CKey() | ||
| 71 | { | ||
| 72 | EC_KEY_free(pkey); | ||
| 73 | } | ||
| 74 | |||
| 75 | void MakeNewKey() | ||
| 76 | { | ||
| 77 | if (!EC_KEY_generate_key(pkey)) | ||
| 78 | throw key_error("CKey::MakeNewKey() : EC_KEY_generate_key failed"); | ||
| 79 | } | ||
| 80 | |||
| 81 | bool SetPrivKey(const CPrivKey& vchPrivKey) | ||
| 82 | { | ||
| 83 | const unsigned char* pbegin = &vchPrivKey[0]; | ||
| 84 | if (!d2i_ECPrivateKey(&pkey, &pbegin, vchPrivKey.size())) | ||
| 85 | return false; | ||
| 86 | return true; | ||
| 87 | } | ||
| 88 | |||
| 89 | CPrivKey GetPrivKey() const | ||
| 90 | { | ||
| 91 | unsigned int nSize = i2d_ECPrivateKey(pkey, NULL); | ||
| 92 | if (!nSize) | ||
| 93 | throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey failed"); | ||
| 94 | CPrivKey vchPrivKey(nSize, 0); | ||
| 95 | unsigned char* pbegin = &vchPrivKey[0]; | ||
| 96 | if (i2d_ECPrivateKey(pkey, &pbegin) != nSize) | ||
| 97 | throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey returned unexpected size"); | ||
| 98 | return vchPrivKey; | ||
| 99 | } | ||
| 100 | |||
| 101 | bool SetPubKey(const vector<unsigned char>& vchPubKey) | ||
| 102 | { | ||
| 103 | const unsigned char* pbegin = &vchPubKey[0]; | ||
| 104 | if (!o2i_ECPublicKey(&pkey, &pbegin, vchPubKey.size())) | ||
| 105 | return false; | ||
| 106 | return true; | ||
| 107 | } | ||
| 108 | |||
| 109 | vector<unsigned char> GetPubKey() const | ||
| 110 | { | ||
| 111 | unsigned int nSize = i2o_ECPublicKey(pkey, NULL); | ||
| 112 | if (!nSize) | ||
| 113 | throw key_error("CKey::GetPubKey() : i2o_ECPublicKey failed"); | ||
| 114 | vector<unsigned char> vchPubKey(nSize, 0); | ||
| 115 | unsigned char* pbegin = &vchPubKey[0]; | ||
| 116 | if (i2o_ECPublicKey(pkey, &pbegin) != nSize) | ||
| 117 | throw key_error("CKey::GetPubKey() : i2o_ECPublicKey returned unexpected size"); | ||
| 118 | return vchPubKey; | ||
| 119 | } | ||
| 120 | |||
| 121 | bool Sign(uint256 hash, vector<unsigned char>& vchSig) | ||
| 122 | { | ||
| 123 | vchSig.clear(); | ||
| 124 | unsigned char pchSig[10000]; | ||
| 125 | unsigned int nSize = 0; | ||
| 126 | if (!ECDSA_sign(0, (unsigned char*)&hash, sizeof(hash), pchSig, &nSize, pkey)) | ||
| 127 | return false; | ||
| 128 | vchSig.resize(nSize); | ||
| 129 | memcpy(&vchSig[0], pchSig, nSize); | ||
| 130 | return true; | ||
| 131 | } | ||
| 132 | |||
| 133 | bool Verify(uint256 hash, const vector<unsigned char>& vchSig) | ||
| 134 | { | ||
| 135 | // -1 = error, 0 = bad sig, 1 = good | ||
| 136 | if (ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], vchSig.size(), pkey) != 1) | ||
| 137 | return false; | ||
| 138 | return true; | ||
| 139 | } | ||
| 140 | |||
| 141 | static bool Sign(const CPrivKey& vchPrivKey, uint256 hash, vector<unsigned char>& vchSig) | ||
| 142 | { | ||
| 143 | CKey key; | ||
| 144 | if (!key.SetPrivKey(vchPrivKey)) | ||
| 145 | return false; | ||
| 146 | return key.Sign(hash, vchSig); | ||
| 147 | } | ||
| 148 | |||
| 149 | static bool Verify(const vector<unsigned char>& vchPubKey, uint256 hash, const vector<unsigned char>& vchSig) | ||
| 150 | { | ||
| 151 | CKey key; | ||
| 152 | if (!key.SetPubKey(vchPubKey)) | ||
| 153 | return false; | ||
| 154 | return key.Verify(hash, vchSig); | ||
| 155 | } | ||
| 156 | }; | ||
diff --git a/src/license.txt b/src/license.txt new file mode 100644 index 0000000..a456302 --- /dev/null +++ b/src/license.txt | |||
| @@ -0,0 +1,19 @@ | |||
| 1 | Copyright (c) 2009 Satoshi Nakamoto | ||
| 2 | |||
| 3 | Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| 4 | of this software and associated documentation files (the "Software"), to deal | ||
| 5 | in the Software without restriction, including without limitation the rights | ||
| 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| 7 | copies of the Software, and to permit persons to whom the Software is | ||
| 8 | furnished to do so, subject to the following conditions: | ||
| 9 | |||
| 10 | The above copyright notice and this permission notice shall be included in | ||
| 11 | all copies or substantial portions of the Software. | ||
| 12 | |||
| 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
| 19 | THE SOFTWARE. | ||
diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..1dbce58 --- /dev/null +++ b/src/main.cpp | |||
| @@ -0,0 +1,2696 @@ | |||
| 1 | // Copyright (c) 2009 Satoshi Nakamoto | ||
| 2 | // Distributed under the MIT/X11 software license, see the accompanying | ||
| 3 | // file license.txt or http://www.opensource.org/licenses/mit-license.php. | ||
| 4 | |||
| 5 | #include "headers.h" | ||
| 6 | #include "sha.h" | ||
| 7 | |||
| 8 | |||
| 9 | |||
| 10 | |||
| 11 | |||
| 12 | // | ||
| 13 | // Global state | ||
| 14 | // | ||
| 15 | |||
| 16 | CCriticalSection cs_main; | ||
| 17 | |||
| 18 | map<uint256, CTransaction> mapTransactions; | ||
| 19 | CCriticalSection cs_mapTransactions; | ||
| 20 | unsigned int nTransactionsUpdated = 0; | ||
| 21 | map<COutPoint, CInPoint> mapNextTx; | ||
| 22 | |||
| 23 | map<uint256, CBlockIndex*> mapBlockIndex; | ||
| 24 | // Bitflash genesis -- mined under RandomX PoW on 2026-07-22 | ||
| 25 | // (nTime 1753142400, nBits 0x1f0fffff, RandomX key "Bitflash/RandomX/v1/...") | ||
| 26 | // Bitflash 2026 stable relaunch genesis (2-min blocks, RandomX). Mined values. | ||
| 27 | unsigned int GENESIS_NONCE = 3141; | ||
| 28 | uint256 hashGenesisBlock("0x5bd7cb255d814e48cebcdfb72da4dc87b34bd774227f8ceb546c5640f4bdc169"); | ||
| 29 | uint256 hashGenesisMerkleRoot("0x1a45b4482532abb29b10e234d3f13132230525a339ecea91658ffa675a5b1325"); | ||
| 30 | CBlockIndex* pindexGenesisBlock = NULL; | ||
| 31 | int nBestHeight = -1; | ||
| 32 | uint256 hashBestChain = 0; | ||
| 33 | CBlockIndex* pindexBest = NULL; | ||
| 34 | |||
| 35 | map<uint256, CBlock*> mapOrphanBlocks; | ||
| 36 | multimap<uint256, CBlock*> mapOrphanBlocksByPrev; | ||
| 37 | |||
| 38 | map<uint256, CDataStream*> mapOrphanTransactions; | ||
| 39 | multimap<uint256, CDataStream*> mapOrphanTransactionsByPrev; | ||
| 40 | |||
| 41 | map<uint256, CWalletTx> mapWallet; | ||
| 42 | vector<pair<uint256, bool> > vWalletUpdated; | ||
| 43 | CCriticalSection cs_mapWallet; | ||
| 44 | |||
| 45 | map<vector<unsigned char>, CPrivKey> mapKeys; | ||
| 46 | map<uint160, vector<unsigned char> > mapPubKeys; | ||
| 47 | CCriticalSection cs_mapKeys; | ||
| 48 | CKey keyUser; | ||
| 49 | |||
| 50 | string strSetDataDir; | ||
| 51 | int nDropMessagesTest = 0; | ||
| 52 | bool fSoloMineTest = false; // /solomine: mine without requiring a peer (local test) | ||
| 53 | |||
| 54 | // Settings | ||
| 55 | int fGenerateBitcoins; | ||
| 56 | int64 nTransactionFee = 0; | ||
| 57 | CAddress addrIncoming; | ||
| 58 | |||
| 59 | |||
| 60 | |||
| 61 | |||
| 62 | |||
| 63 | |||
| 64 | |||
| 65 | |||
| 66 | ////////////////////////////////////////////////////////////////////////////// | ||
| 67 | // | ||
| 68 | // mapKeys | ||
| 69 | // | ||
| 70 | |||
| 71 | bool AddKey(const CKey& key) | ||
| 72 | { | ||
| 73 | CRITICAL_BLOCK(cs_mapKeys) | ||
| 74 | { | ||
| 75 | mapKeys[key.GetPubKey()] = key.GetPrivKey(); | ||
| 76 | mapPubKeys[Hash160(key.GetPubKey())] = key.GetPubKey(); | ||
| 77 | } | ||
| 78 | return CWalletDB().WriteKey(key.GetPubKey(), key.GetPrivKey()); | ||
| 79 | } | ||
| 80 | |||
| 81 | vector<unsigned char> GenerateNewKey() | ||
| 82 | { | ||
| 83 | CKey key; | ||
| 84 | key.MakeNewKey(); | ||
| 85 | if (!AddKey(key)) | ||
| 86 | throw runtime_error("GenerateNewKey() : AddKey failed\n"); | ||
| 87 | return key.GetPubKey(); | ||
| 88 | } | ||
| 89 | |||
| 90 | |||
| 91 | |||
| 92 | |||
| 93 | ////////////////////////////////////////////////////////////////////////////// | ||
| 94 | // | ||
| 95 | // mapWallet | ||
| 96 | // | ||
| 97 | |||
| 98 | bool AddToWallet(const CWalletTx& wtxIn) | ||
| 99 | { | ||
| 100 | uint256 hash = wtxIn.GetHash(); | ||
| 101 | CRITICAL_BLOCK(cs_mapWallet) | ||
| 102 | { | ||
| 103 | // Inserts only if not already there, returns tx inserted or tx found | ||
| 104 | pair<map<uint256, CWalletTx>::iterator, bool> ret = mapWallet.insert(make_pair(hash, wtxIn)); | ||
| 105 | CWalletTx& wtx = (*ret.first).second; | ||
| 106 | bool fInsertedNew = ret.second; | ||
| 107 | if (fInsertedNew) | ||
| 108 | wtx.nTimeReceived = GetAdjustedTime(); | ||
| 109 | |||
| 110 | //// debug print | ||
| 111 | printf("AddToWallet %s %s\n", wtxIn.GetHash().ToString().substr(0,6).c_str(), fInsertedNew ? "new" : "update"); | ||
| 112 | |||
| 113 | if (!fInsertedNew) | ||
| 114 | { | ||
| 115 | // Merge | ||
| 116 | bool fUpdated = false; | ||
| 117 | if (wtxIn.hashBlock != 0 && wtxIn.hashBlock != wtx.hashBlock) | ||
| 118 | { | ||
| 119 | wtx.hashBlock = wtxIn.hashBlock; | ||
| 120 | fUpdated = true; | ||
| 121 | } | ||
| 122 | if (wtxIn.nIndex != -1 && (wtxIn.vMerkleBranch != wtx.vMerkleBranch || wtxIn.nIndex != wtx.nIndex)) | ||
| 123 | { | ||
| 124 | wtx.vMerkleBranch = wtxIn.vMerkleBranch; | ||
| 125 | wtx.nIndex = wtxIn.nIndex; | ||
| 126 | fUpdated = true; | ||
| 127 | } | ||
| 128 | if (wtxIn.fFromMe && wtxIn.fFromMe != wtx.fFromMe) | ||
| 129 | { | ||
| 130 | wtx.fFromMe = wtxIn.fFromMe; | ||
| 131 | fUpdated = true; | ||
| 132 | } | ||
| 133 | if (wtxIn.fSpent && wtxIn.fSpent != wtx.fSpent) | ||
| 134 | { | ||
| 135 | wtx.fSpent = wtxIn.fSpent; | ||
| 136 | fUpdated = true; | ||
| 137 | } | ||
| 138 | if (!fUpdated) | ||
| 139 | return true; | ||
| 140 | } | ||
| 141 | |||
| 142 | // Write to disk | ||
| 143 | if (!wtx.WriteToDisk()) | ||
| 144 | return false; | ||
| 145 | |||
| 146 | // Notify UI | ||
| 147 | vWalletUpdated.push_back(make_pair(hash, fInsertedNew)); | ||
| 148 | } | ||
| 149 | |||
| 150 | // Refresh UI | ||
| 151 | MainFrameRepaint(); | ||
| 152 | return true; | ||
| 153 | } | ||
| 154 | |||
| 155 | bool AddToWalletIfMine(const CTransaction& tx, const CBlock* pblock) | ||
| 156 | { | ||
| 157 | if (tx.IsMine() || mapWallet.count(tx.GetHash())) | ||
| 158 | { | ||
| 159 | CWalletTx wtx(tx); | ||
| 160 | // Get merkle branch if transaction was found in a block | ||
| 161 | if (pblock) | ||
| 162 | wtx.SetMerkleBranch(pblock); | ||
| 163 | return AddToWallet(wtx); | ||
| 164 | } | ||
| 165 | return true; | ||
| 166 | } | ||
| 167 | |||
| 168 | bool EraseFromWallet(uint256 hash) | ||
| 169 | { | ||
| 170 | CRITICAL_BLOCK(cs_mapWallet) | ||
| 171 | { | ||
| 172 | if (mapWallet.erase(hash)) | ||
| 173 | CWalletDB().EraseTx(hash); | ||
| 174 | } | ||
| 175 | return true; | ||
| 176 | } | ||
| 177 | |||
| 178 | |||
| 179 | |||
| 180 | |||
| 181 | |||
| 182 | |||
| 183 | |||
| 184 | |||
| 185 | |||
| 186 | ////////////////////////////////////////////////////////////////////////////// | ||
| 187 | // | ||
| 188 | // mapOrphanTransactions | ||
| 189 | // | ||
| 190 | |||
| 191 | void AddOrphanTx(const CDataStream& vMsg) | ||
| 192 | { | ||
| 193 | CTransaction tx; | ||
| 194 | CDataStream(vMsg) >> tx; | ||
| 195 | uint256 hash = tx.GetHash(); | ||
| 196 | if (mapOrphanTransactions.count(hash)) | ||
| 197 | return; | ||
| 198 | CDataStream* pvMsg = mapOrphanTransactions[hash] = new CDataStream(vMsg); | ||
| 199 | foreach(const CTxIn& txin, tx.vin) | ||
| 200 | mapOrphanTransactionsByPrev.insert(make_pair(txin.prevout.hash, pvMsg)); | ||
| 201 | } | ||
| 202 | |||
| 203 | void EraseOrphanTx(uint256 hash) | ||
| 204 | { | ||
| 205 | if (!mapOrphanTransactions.count(hash)) | ||
| 206 | return; | ||
| 207 | const CDataStream* pvMsg = mapOrphanTransactions[hash]; | ||
| 208 | CTransaction tx; | ||
| 209 | CDataStream(*pvMsg) >> tx; | ||
| 210 | foreach(const CTxIn& txin, tx.vin) | ||
| 211 | { | ||
| 212 | for (multimap<uint256, CDataStream*>::iterator mi = mapOrphanTransactionsByPrev.lower_bound(txin.prevout.hash); | ||
| 213 | mi != mapOrphanTransactionsByPrev.upper_bound(txin.prevout.hash);) | ||
| 214 | { | ||
| 215 | if ((*mi).second == pvMsg) | ||
| 216 | mapOrphanTransactionsByPrev.erase(mi++); | ||
| 217 | else | ||
| 218 | mi++; | ||
| 219 | } | ||
| 220 | } | ||
| 221 | delete pvMsg; | ||
| 222 | mapOrphanTransactions.erase(hash); | ||
| 223 | } | ||
| 224 | |||
| 225 | |||
| 226 | |||
| 227 | |||
| 228 | |||
| 229 | |||
| 230 | |||
| 231 | |||
| 232 | ////////////////////////////////////////////////////////////////////////////// | ||
| 233 | // | ||
| 234 | // CTransaction | ||
| 235 | // | ||
| 236 | |||
| 237 | bool CTxIn::IsMine() const | ||
| 238 | { | ||
| 239 | CRITICAL_BLOCK(cs_mapWallet) | ||
| 240 | { | ||
| 241 | map<uint256, CWalletTx>::iterator mi = mapWallet.find(prevout.hash); | ||
| 242 | if (mi != mapWallet.end()) | ||
| 243 | { | ||
| 244 | const CWalletTx& prev = (*mi).second; | ||
| 245 | if (prevout.n < prev.vout.size()) | ||
| 246 | if (prev.vout[prevout.n].IsMine()) | ||
| 247 | return true; | ||
| 248 | } | ||
| 249 | } | ||
| 250 | return false; | ||
| 251 | } | ||
| 252 | |||
| 253 | int64 CTxIn::GetDebit() const | ||
| 254 | { | ||
| 255 | CRITICAL_BLOCK(cs_mapWallet) | ||
| 256 | { | ||
| 257 | map<uint256, CWalletTx>::iterator mi = mapWallet.find(prevout.hash); | ||
| 258 | if (mi != mapWallet.end()) | ||
| 259 | { | ||
| 260 | const CWalletTx& prev = (*mi).second; | ||
| 261 | if (prevout.n < prev.vout.size()) | ||
| 262 | if (prev.vout[prevout.n].IsMine()) | ||
| 263 | return prev.vout[prevout.n].nValue; | ||
| 264 | } | ||
| 265 | } | ||
| 266 | return 0; | ||
| 267 | } | ||
| 268 | |||
| 269 | int64 CWalletTx::GetTxTime() const | ||
| 270 | { | ||
| 271 | if (!fTimeReceivedIsTxTime && hashBlock != 0) | ||
| 272 | { | ||
| 273 | // If we did not receive the transaction directly, we rely on the block's | ||
| 274 | // time to figure out when it happened. We use the median over a range | ||
| 275 | // of blocks to try to filter out inaccurate block times. | ||
| 276 | map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock); | ||
| 277 | if (mi != mapBlockIndex.end()) | ||
| 278 | { | ||
| 279 | CBlockIndex* pindex = (*mi).second; | ||
| 280 | if (pindex) | ||
| 281 | return pindex->GetMedianTime(); | ||
| 282 | } | ||
| 283 | } | ||
| 284 | return nTimeReceived; | ||
| 285 | } | ||
| 286 | |||
| 287 | |||
| 288 | |||
| 289 | |||
| 290 | |||
| 291 | |||
| 292 | int CMerkleTx::SetMerkleBranch(const CBlock* pblock) | ||
| 293 | { | ||
| 294 | if (fClient) | ||
| 295 | { | ||
| 296 | if (hashBlock == 0) | ||
| 297 | return 0; | ||
| 298 | } | ||
| 299 | else | ||
| 300 | { | ||
| 301 | CBlock blockTmp; | ||
| 302 | if (pblock == NULL) | ||
| 303 | { | ||
| 304 | // Load the block this tx is in | ||
| 305 | CTxIndex txindex; | ||
| 306 | if (!CTxDB("r").ReadTxIndex(GetHash(), txindex)) | ||
| 307 | return 0; | ||
| 308 | if (!blockTmp.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, true)) | ||
| 309 | return 0; | ||
| 310 | pblock = &blockTmp; | ||
| 311 | } | ||
| 312 | |||
| 313 | // Update the tx's hashBlock | ||
| 314 | hashBlock = pblock->GetHash(); | ||
| 315 | |||
| 316 | // Locate the transaction | ||
| 317 | for (nIndex = 0; nIndex < pblock->vtx.size(); nIndex++) | ||
| 318 | if (pblock->vtx[nIndex] == *(CTransaction*)this) | ||
| 319 | break; | ||
| 320 | if (nIndex == pblock->vtx.size()) | ||
| 321 | { | ||
| 322 | vMerkleBranch.clear(); | ||
| 323 | nIndex = -1; | ||
| 324 | printf("ERROR: SetMerkleBranch() : couldn't find tx in block\n"); | ||
| 325 | return 0; | ||
| 326 | } | ||
| 327 | |||
| 328 | // Fill in merkle branch | ||
| 329 | vMerkleBranch = pblock->GetMerkleBranch(nIndex); | ||
| 330 | } | ||
| 331 | |||
| 332 | // Is the tx in a block that's in the main chain | ||
| 333 | map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock); | ||
| 334 | if (mi == mapBlockIndex.end()) | ||
| 335 | return 0; | ||
| 336 | CBlockIndex* pindex = (*mi).second; | ||
| 337 | if (!pindex || !pindex->IsInMainChain()) | ||
| 338 | return 0; | ||
| 339 | |||
| 340 | return pindexBest->nHeight - pindex->nHeight + 1; | ||
| 341 | } | ||
| 342 | |||
| 343 | |||
| 344 | |||
| 345 | void CWalletTx::AddSupportingTransactions(CTxDB& txdb) | ||
| 346 | { | ||
| 347 | vtxPrev.clear(); | ||
| 348 | |||
| 349 | const int COPY_DEPTH = 3; | ||
| 350 | if (SetMerkleBranch() < COPY_DEPTH) | ||
| 351 | { | ||
| 352 | vector<uint256> vWorkQueue; | ||
| 353 | foreach(const CTxIn& txin, vin) | ||
| 354 | vWorkQueue.push_back(txin.prevout.hash); | ||
| 355 | |||
| 356 | // This critsect is OK because txdb is already open | ||
| 357 | CRITICAL_BLOCK(cs_mapWallet) | ||
| 358 | { | ||
| 359 | map<uint256, const CMerkleTx*> mapWalletPrev; | ||
| 360 | set<uint256> setAlreadyDone; | ||
| 361 | for (int i = 0; i < vWorkQueue.size(); i++) | ||
| 362 | { | ||
| 363 | uint256 hash = vWorkQueue[i]; | ||
| 364 | if (setAlreadyDone.count(hash)) | ||
| 365 | continue; | ||
| 366 | setAlreadyDone.insert(hash); | ||
| 367 | |||
| 368 | CMerkleTx tx; | ||
| 369 | if (mapWallet.count(hash)) | ||
| 370 | { | ||
| 371 | tx = mapWallet[hash]; | ||
| 372 | foreach(const CMerkleTx& txWalletPrev, mapWallet[hash].vtxPrev) | ||
| 373 | mapWalletPrev[txWalletPrev.GetHash()] = &txWalletPrev; | ||
| 374 | } | ||
| 375 | else if (mapWalletPrev.count(hash)) | ||
| 376 | { | ||
| 377 | tx = *mapWalletPrev[hash]; | ||
| 378 | } | ||
| 379 | else if (!fClient && txdb.ReadDiskTx(hash, tx)) | ||
| 380 | { | ||
| 381 | ; | ||
| 382 | } | ||
| 383 | else | ||
| 384 | { | ||
| 385 | printf("ERROR: AddSupportingTransactions() : unsupported transaction\n"); | ||
| 386 | continue; | ||
| 387 | } | ||
| 388 | |||
| 389 | int nDepth = tx.SetMerkleBranch(); | ||
| 390 | vtxPrev.push_back(tx); | ||
| 391 | |||
| 392 | if (nDepth < COPY_DEPTH) | ||
| 393 | foreach(const CTxIn& txin, tx.vin) | ||
| 394 | vWorkQueue.push_back(txin.prevout.hash); | ||
| 395 | } | ||
| 396 | } | ||
| 397 | } | ||
| 398 | |||
| 399 | reverse(vtxPrev.begin(), vtxPrev.end()); | ||
| 400 | } | ||
| 401 | |||
| 402 | |||
| 403 | |||
| 404 | |||
| 405 | |||
| 406 | |||
| 407 | |||
| 408 | |||
| 409 | |||
| 410 | |||
| 411 | |||
| 412 | bool CTransaction::AcceptTransaction(CTxDB& txdb, bool fCheckInputs, bool* pfMissingInputs) | ||
| 413 | { | ||
| 414 | if (pfMissingInputs) | ||
| 415 | *pfMissingInputs = false; | ||
| 416 | |||
| 417 | // Coinbase is only valid in a block, not as a loose transaction | ||
| 418 | if (IsCoinBase()) | ||
| 419 | return error("AcceptTransaction() : coinbase as individual tx"); | ||
| 420 | |||
| 421 | if (!CheckTransaction()) | ||
| 422 | return error("AcceptTransaction() : CheckTransaction failed"); | ||
| 423 | |||
| 424 | // Do we already have it? | ||
| 425 | uint256 hash = GetHash(); | ||
| 426 | CRITICAL_BLOCK(cs_mapTransactions) | ||
| 427 | if (mapTransactions.count(hash)) | ||
| 428 | return false; | ||
| 429 | if (fCheckInputs) | ||
| 430 | if (txdb.ContainsTx(hash)) | ||
| 431 | return false; | ||
| 432 | |||
| 433 | // Check for conflicts with in-memory transactions | ||
| 434 | CTransaction* ptxOld = NULL; | ||
| 435 | for (int i = 0; i < vin.size(); i++) | ||
| 436 | { | ||
| 437 | COutPoint outpoint = vin[i].prevout; | ||
| 438 | if (mapNextTx.count(outpoint)) | ||
| 439 | { | ||
| 440 | // Allow replacing with a newer version of the same transaction | ||
| 441 | if (i != 0) | ||
| 442 | return false; | ||
| 443 | ptxOld = mapNextTx[outpoint].ptx; | ||
| 444 | if (!IsNewerThan(*ptxOld)) | ||
| 445 | return false; | ||
| 446 | for (int i = 0; i < vin.size(); i++) | ||
| 447 | { | ||
| 448 | COutPoint outpoint = vin[i].prevout; | ||
| 449 | if (!mapNextTx.count(outpoint) || mapNextTx[outpoint].ptx != ptxOld) | ||
| 450 | return false; | ||
| 451 | } | ||
| 452 | break; | ||
| 453 | } | ||
| 454 | } | ||
| 455 | |||
| 456 | // Check against previous transactions | ||
| 457 | map<uint256, CTxIndex> mapUnused; | ||
| 458 | int64 nFees = 0; | ||
| 459 | if (fCheckInputs && !ConnectInputs(txdb, mapUnused, CDiskTxPos(1,1,1), 0, nFees, false, false)) | ||
| 460 | { | ||
| 461 | if (pfMissingInputs) | ||
| 462 | *pfMissingInputs = true; | ||
| 463 | return error("AcceptTransaction() : ConnectInputs failed %s", hash.ToString().substr(0,6).c_str()); | ||
| 464 | } | ||
| 465 | |||
| 466 | // Store transaction in memory | ||
| 467 | CRITICAL_BLOCK(cs_mapTransactions) | ||
| 468 | { | ||
| 469 | if (ptxOld) | ||
| 470 | { | ||
| 471 | printf("mapTransaction.erase(%s) replacing with new version\n", ptxOld->GetHash().ToString().c_str()); | ||
| 472 | mapTransactions.erase(ptxOld->GetHash()); | ||
| 473 | } | ||
| 474 | AddToMemoryPool(); | ||
| 475 | } | ||
| 476 | |||
| 477 | ///// are we sure this is ok when loading transactions or restoring block txes | ||
| 478 | // If updated, erase old tx from wallet | ||
| 479 | if (ptxOld) | ||
| 480 | EraseFromWallet(ptxOld->GetHash()); | ||
| 481 | |||
| 482 | printf("AcceptTransaction(): accepted %s\n", hash.ToString().substr(0,6).c_str()); | ||
| 483 | return true; | ||
| 484 | } | ||
| 485 | |||
| 486 | |||
| 487 | bool CTransaction::AddToMemoryPool() | ||
| 488 | { | ||
| 489 | // Add to memory pool without checking anything. Don't call this directly, | ||
| 490 | // call AcceptTransaction to properly check the transaction first. | ||
| 491 | CRITICAL_BLOCK(cs_mapTransactions) | ||
| 492 | { | ||
| 493 | uint256 hash = GetHash(); | ||
| 494 | mapTransactions[hash] = *this; | ||
| 495 | for (int i = 0; i < vin.size(); i++) | ||
| 496 | mapNextTx[vin[i].prevout] = CInPoint(&mapTransactions[hash], i); | ||
| 497 | nTransactionsUpdated++; | ||
| 498 | } | ||
| 499 | return true; | ||
| 500 | } | ||
| 501 | |||
| 502 | |||
| 503 | bool CTransaction::RemoveFromMemoryPool() | ||
| 504 | { | ||
| 505 | // Remove transaction from memory pool | ||
| 506 | CRITICAL_BLOCK(cs_mapTransactions) | ||
| 507 | { | ||
| 508 | foreach(const CTxIn& txin, vin) | ||
| 509 | mapNextTx.erase(txin.prevout); | ||
| 510 | mapTransactions.erase(GetHash()); | ||
| 511 | nTransactionsUpdated++; | ||
| 512 | } | ||
| 513 | return true; | ||
| 514 | } | ||
| 515 | |||
| 516 | |||
| 517 | |||
| 518 | |||
| 519 | |||
| 520 | |||
| 521 | int CMerkleTx::GetDepthInMainChain() const | ||
| 522 | { | ||
| 523 | if (hashBlock == 0 || nIndex == -1) | ||
| 524 | return 0; | ||
| 525 | |||
| 526 | // Find the block it claims to be in | ||
| 527 | map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock); | ||
| 528 | if (mi == mapBlockIndex.end()) | ||
| 529 | return 0; | ||
| 530 | CBlockIndex* pindex = (*mi).second; | ||
| 531 | if (!pindex || !pindex->IsInMainChain()) | ||
| 532 | return 0; | ||
| 533 | |||
| 534 | // Make sure the merkle branch connects to this block | ||
| 535 | if (!fMerkleVerified) | ||
| 536 | { | ||
| 537 | if (CBlock::CheckMerkleBranch(GetHash(), vMerkleBranch, nIndex) != pindex->hashMerkleRoot) | ||
| 538 | return 0; | ||
| 539 | fMerkleVerified = true; | ||
| 540 | } | ||
| 541 | |||
| 542 | return pindexBest->nHeight - pindex->nHeight + 1; | ||
| 543 | } | ||
| 544 | |||
| 545 | |||
| 546 | int CMerkleTx::GetBlocksToMaturity() const | ||
| 547 | { | ||
| 548 | if (!IsCoinBase()) | ||
| 549 | return 0; | ||
| 550 | return max(0, (COINBASE_MATURITY+20) - GetDepthInMainChain()); | ||
| 551 | } | ||
| 552 | |||
| 553 | |||
| 554 | bool CMerkleTx::AcceptTransaction(CTxDB& txdb, bool fCheckInputs) | ||
| 555 | { | ||
| 556 | if (fClient) | ||
| 557 | { | ||
| 558 | if (!IsInMainChain() && !ClientConnectInputs()) | ||
| 559 | return false; | ||
| 560 | return CTransaction::AcceptTransaction(txdb, false); | ||
| 561 | } | ||
| 562 | else | ||
| 563 | { | ||
| 564 | return CTransaction::AcceptTransaction(txdb, fCheckInputs); | ||
| 565 | } | ||
| 566 | } | ||
| 567 | |||
| 568 | |||
| 569 | |||
| 570 | bool CWalletTx::AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs) | ||
| 571 | { | ||
| 572 | CRITICAL_BLOCK(cs_mapTransactions) | ||
| 573 | { | ||
| 574 | foreach(CMerkleTx& tx, vtxPrev) | ||
| 575 | { | ||
| 576 | if (!tx.IsCoinBase()) | ||
| 577 | { | ||
| 578 | uint256 hash = tx.GetHash(); | ||
| 579 | if (!mapTransactions.count(hash) && !txdb.ContainsTx(hash)) | ||
| 580 | tx.AcceptTransaction(txdb, fCheckInputs); | ||
| 581 | } | ||
| 582 | } | ||
| 583 | if (!IsCoinBase()) | ||
| 584 | return AcceptTransaction(txdb, fCheckInputs); | ||
| 585 | } | ||
| 586 | return true; | ||
| 587 | } | ||
| 588 | |||
| 589 | void ReacceptWalletTransactions() | ||
| 590 | { | ||
| 591 | // Reaccept any txes of ours that aren't already in a block | ||
| 592 | CTxDB txdb("r"); | ||
| 593 | CRITICAL_BLOCK(cs_mapWallet) | ||
| 594 | { | ||
| 595 | foreach(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet) | ||
| 596 | { | ||
| 597 | CWalletTx& wtx = item.second; | ||
| 598 | if (!wtx.IsCoinBase() && !txdb.ContainsTx(wtx.GetHash())) | ||
| 599 | wtx.AcceptWalletTransaction(txdb, false); | ||
| 600 | } | ||
| 601 | } | ||
| 602 | } | ||
| 603 | |||
| 604 | |||
| 605 | void CWalletTx::RelayWalletTransaction(CTxDB& txdb) | ||
| 606 | { | ||
| 607 | foreach(const CMerkleTx& tx, vtxPrev) | ||
| 608 | { | ||
| 609 | if (!tx.IsCoinBase()) | ||
| 610 | { | ||
| 611 | uint256 hash = tx.GetHash(); | ||
| 612 | if (!txdb.ContainsTx(hash)) | ||
| 613 | RelayMessage(CInv(MSG_TX, hash), (CTransaction)tx); | ||
| 614 | } | ||
| 615 | } | ||
| 616 | if (!IsCoinBase()) | ||
| 617 | { | ||
| 618 | uint256 hash = GetHash(); | ||
| 619 | if (!txdb.ContainsTx(hash)) | ||
| 620 | { | ||
| 621 | printf("Relaying wtx %s\n", hash.ToString().substr(0,6).c_str()); | ||
| 622 | RelayMessage(CInv(MSG_TX, hash), (CTransaction)*this); | ||
| 623 | } | ||
| 624 | } | ||
| 625 | } | ||
| 626 | |||
| 627 | void RelayWalletTransactions() | ||
| 628 | { | ||
| 629 | static int64 nLastTime; | ||
| 630 | if (GetTime() - nLastTime < 10 * 60) | ||
| 631 | return; | ||
| 632 | nLastTime = GetTime(); | ||
| 633 | |||
| 634 | // Rebroadcast any of our txes that aren't in a block yet | ||
| 635 | printf("RelayWalletTransactions()\n"); | ||
| 636 | CTxDB txdb("r"); | ||
| 637 | CRITICAL_BLOCK(cs_mapWallet) | ||
| 638 | { | ||
| 639 | // Sort them in chronological order | ||
| 640 | multimap<unsigned int, CWalletTx*> mapSorted; | ||
| 641 | foreach(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet) | ||
| 642 | { | ||
| 643 | CWalletTx& wtx = item.second; | ||
| 644 | mapSorted.insert(make_pair(wtx.nTimeReceived, &wtx)); | ||
| 645 | } | ||
| 646 | foreach(PAIRTYPE(const unsigned int, CWalletTx*)& item, mapSorted) | ||
| 647 | { | ||
| 648 | CWalletTx& wtx = *item.second; | ||
| 649 | wtx.RelayWalletTransaction(txdb); | ||
| 650 | } | ||
| 651 | } | ||
| 652 | } | ||
| 653 | |||
| 654 | |||
| 655 | |||
| 656 | |||
| 657 | |||
| 658 | |||
| 659 | |||
| 660 | |||
| 661 | |||
| 662 | |||
| 663 | ////////////////////////////////////////////////////////////////////////////// | ||
| 664 | // | ||
| 665 | // CBlock and CBlockIndex | ||
| 666 | // | ||
| 667 | |||
| 668 | bool CBlock::ReadFromDisk(const CBlockIndex* pblockindex, bool fReadTransactions) | ||
| 669 | { | ||
| 670 | return ReadFromDisk(pblockindex->nFile, pblockindex->nBlockPos, fReadTransactions); | ||
| 671 | } | ||
| 672 | |||
| 673 | uint256 GetOrphanRoot(const CBlock* pblock) | ||
| 674 | { | ||
| 675 | // Work back to the first block in the orphan chain | ||
| 676 | while (mapOrphanBlocks.count(pblock->hashPrevBlock)) | ||
| 677 | pblock = mapOrphanBlocks[pblock->hashPrevBlock]; | ||
| 678 | return pblock->GetHash(); | ||
| 679 | } | ||
| 680 | |||
| 681 | int64 CBlock::GetBlockValue(int64 nFees) const | ||
| 682 | { | ||
| 683 | int64 nSubsidy = 50 * COIN; | ||
| 684 | |||
| 685 | // Subsidy is cut in half every 4 years | ||
| 686 | nSubsidy >>= (nBestHeight / 210000); | ||
| 687 | |||
| 688 | return nSubsidy + nFees; | ||
| 689 | } | ||
| 690 | |||
| 691 | unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast) | ||
| 692 | { | ||
| 693 | // Bitflash: 2-minute target block time with a fast retarget (every 30 | ||
| 694 | // blocks, ~1h) so difficulty tracks the small, volatile CPU hashrate and | ||
| 695 | // brief disconnections no longer spawn divergent forks. | ||
| 696 | const unsigned int nTargetSpacing = 2 * 60; // 2 minutes | ||
| 697 | const unsigned int nInterval = 30; // retarget window | ||
| 698 | const unsigned int nTargetTimespan = nInterval * nTargetSpacing; // 3600s | ||
| 699 | |||
| 700 | // Genesis block | ||
| 701 | if (pindexLast == NULL) | ||
| 702 | return bnProofOfWorkLimit.GetCompact(); | ||
| 703 | |||
| 704 | // Only change once per interval | ||
| 705 | if ((pindexLast->nHeight+1) % nInterval != 0) | ||
| 706 | return pindexLast->nBits; | ||
| 707 | |||
| 708 | // Go back by what we want to be 14 days worth of blocks | ||
| 709 | const CBlockIndex* pindexFirst = pindexLast; | ||
| 710 | for (int i = 0; pindexFirst && i < nInterval-1; i++) | ||
| 711 | pindexFirst = pindexFirst->pprev; | ||
| 712 | assert(pindexFirst); | ||
| 713 | |||
| 714 | // Limit adjustment step | ||
| 715 | unsigned int nActualTimespan = pindexLast->nTime - pindexFirst->nTime; | ||
| 716 | printf(" nActualTimespan = %d before bounds\n", nActualTimespan); | ||
| 717 | if (nActualTimespan < nTargetTimespan/4) | ||
| 718 | nActualTimespan = nTargetTimespan/4; | ||
| 719 | if (nActualTimespan > nTargetTimespan*4) | ||
| 720 | nActualTimespan = nTargetTimespan*4; | ||
| 721 | |||
| 722 | // Retarget | ||
| 723 | CBigNum bnNew; | ||
| 724 | bnNew.SetCompact(pindexLast->nBits); | ||
| 725 | bnNew *= nActualTimespan; | ||
| 726 | bnNew /= nTargetTimespan; | ||
| 727 | |||
| 728 | if (bnNew > bnProofOfWorkLimit) | ||
| 729 | bnNew = bnProofOfWorkLimit; | ||
| 730 | |||
| 731 | /// debug print | ||
| 732 | printf("\n\n\nGetNextWorkRequired RETARGET *****\n"); | ||
| 733 | printf("nTargetTimespan = %d nActualTimespan = %d\n", nTargetTimespan, nActualTimespan); | ||
| 734 | printf("Before: %08x %s\n", pindexLast->nBits, CBigNum().SetCompact(pindexLast->nBits).getuint256().ToString().c_str()); | ||
| 735 | printf("After: %08x %s\n", bnNew.GetCompact(), bnNew.getuint256().ToString().c_str()); | ||
| 736 | |||
| 737 | return bnNew.GetCompact(); | ||
| 738 | } | ||
| 739 | |||
| 740 | |||
| 741 | |||
| 742 | |||
| 743 | |||
| 744 | |||
| 745 | |||
| 746 | |||
| 747 | |||
| 748 | bool CTransaction::DisconnectInputs(CTxDB& txdb) | ||
| 749 | { | ||
| 750 | // Relinquish previous transactions' spent pointers | ||
| 751 | if (!IsCoinBase()) | ||
| 752 | { | ||
| 753 | foreach(const CTxIn& txin, vin) | ||
| 754 | { | ||
| 755 | COutPoint prevout = txin.prevout; | ||
| 756 | |||
| 757 | // Get prev txindex from disk | ||
| 758 | CTxIndex txindex; | ||
| 759 | if (!txdb.ReadTxIndex(prevout.hash, txindex)) | ||
| 760 | return error("DisconnectInputs() : ReadTxIndex failed"); | ||
| 761 | |||
| 762 | if (prevout.n >= txindex.vSpent.size()) | ||
| 763 | return error("DisconnectInputs() : prevout.n out of range"); | ||
| 764 | |||
| 765 | // Mark outpoint as not spent | ||
| 766 | txindex.vSpent[prevout.n].SetNull(); | ||
| 767 | |||
| 768 | // Write back | ||
| 769 | txdb.UpdateTxIndex(prevout.hash, txindex); | ||
| 770 | } | ||
| 771 | } | ||
| 772 | |||
| 773 | // Remove transaction from index | ||
| 774 | if (!txdb.EraseTxIndex(*this)) | ||
| 775 | return error("DisconnectInputs() : EraseTxPos failed"); | ||
| 776 | |||
| 777 | return true; | ||
| 778 | } | ||
| 779 | |||
| 780 | |||
| 781 | bool CTransaction::ConnectInputs(CTxDB& txdb, map<uint256, CTxIndex>& mapTestPool, CDiskTxPos posThisTx, int nHeight, int64& nFees, bool fBlock, bool fMiner, int64 nMinFee) | ||
| 782 | { | ||
| 783 | // Take over previous transactions' spent pointers | ||
| 784 | if (!IsCoinBase()) | ||
| 785 | { | ||
| 786 | int64 nValueIn = 0; | ||
| 787 | for (int i = 0; i < vin.size(); i++) | ||
| 788 | { | ||
| 789 | COutPoint prevout = vin[i].prevout; | ||
| 790 | |||
| 791 | // Read txindex | ||
| 792 | CTxIndex txindex; | ||
| 793 | bool fFound = true; | ||
| 794 | if (fMiner && mapTestPool.count(prevout.hash)) | ||
| 795 | { | ||
| 796 | // Get txindex from current proposed changes | ||
| 797 | txindex = mapTestPool[prevout.hash]; | ||
| 798 | } | ||
| 799 | else | ||
| 800 | { | ||
| 801 | // Read txindex from txdb | ||
| 802 | fFound = txdb.ReadTxIndex(prevout.hash, txindex); | ||
| 803 | } | ||
| 804 | if (!fFound && (fBlock || fMiner)) | ||
| 805 | return fMiner ? false : error("ConnectInputs() : %s prev tx %s index entry not found", GetHash().ToString().substr(0,6).c_str(), prevout.hash.ToString().substr(0,6).c_str()); | ||
| 806 | |||
| 807 | // Read txPrev | ||
| 808 | CTransaction txPrev; | ||
| 809 | if (!fFound || txindex.pos == CDiskTxPos(1,1,1)) | ||
| 810 | { | ||
| 811 | // Get prev tx from single transactions in memory | ||
| 812 | CRITICAL_BLOCK(cs_mapTransactions) | ||
| 813 | { | ||
| 814 | if (!mapTransactions.count(prevout.hash)) | ||
| 815 | return error("ConnectInputs() : %s mapTransactions prev not found %s", GetHash().ToString().substr(0,6).c_str(), prevout.hash.ToString().substr(0,6).c_str()); | ||
| 816 | txPrev = mapTransactions[prevout.hash]; | ||
| 817 | } | ||
| 818 | if (!fFound) | ||
| 819 | txindex.vSpent.resize(txPrev.vout.size()); | ||
| 820 | } | ||
| 821 | else | ||
| 822 | { | ||
| 823 | // Get prev tx from disk | ||
| 824 | if (!txPrev.ReadFromDisk(txindex.pos)) | ||
| 825 | return error("ConnectInputs() : %s ReadFromDisk prev tx %s failed", GetHash().ToString().substr(0,6).c_str(), prevout.hash.ToString().substr(0,6).c_str()); | ||
| 826 | } | ||
| 827 | |||
| 828 | if (prevout.n >= txPrev.vout.size() || prevout.n >= txindex.vSpent.size()) | ||
| 829 | return error("ConnectInputs() : %s prevout.n out of range %d %d %d", GetHash().ToString().substr(0,6).c_str(), prevout.n, txPrev.vout.size(), txindex.vSpent.size()); | ||
| 830 | |||
| 831 | // If prev is coinbase, check that it's matured | ||
| 832 | if (txPrev.IsCoinBase()) | ||
| 833 | for (CBlockIndex* pindex = pindexBest; pindex && nBestHeight - pindex->nHeight < COINBASE_MATURITY-1; pindex = pindex->pprev) | ||
| 834 | if (pindex->nBlockPos == txindex.pos.nBlockPos && pindex->nFile == txindex.pos.nFile) | ||
| 835 | return error("ConnectInputs() : tried to spend coinbase at depth %d", nBestHeight - pindex->nHeight); | ||
| 836 | |||
| 837 | // Verify signature | ||
| 838 | if (!VerifySignature(txPrev, *this, i)) | ||
| 839 | return error("ConnectInputs() : %s VerifySignature failed", GetHash().ToString().substr(0,6).c_str()); | ||
| 840 | |||
| 841 | // Check for conflicts | ||
| 842 | if (!txindex.vSpent[prevout.n].IsNull()) | ||
| 843 | return fMiner ? false : error("ConnectInputs() : %s prev tx already used at %s", GetHash().ToString().substr(0,6).c_str(), txindex.vSpent[prevout.n].ToString().c_str()); | ||
| 844 | |||
| 845 | // Mark outpoints as spent | ||
| 846 | txindex.vSpent[prevout.n] = posThisTx; | ||
| 847 | |||
| 848 | // Write back | ||
| 849 | if (fBlock) | ||
| 850 | txdb.UpdateTxIndex(prevout.hash, txindex); | ||
| 851 | else if (fMiner) | ||
| 852 | mapTestPool[prevout.hash] = txindex; | ||
| 853 | |||
| 854 | nValueIn += txPrev.vout[prevout.n].nValue; | ||
| 855 | if (!MoneyRange(txPrev.vout[prevout.n].nValue) || !MoneyRange(nValueIn)) | ||
| 856 | return error("ConnectInputs() : txin values out of range"); | ||
| 857 | } | ||
| 858 | |||
| 859 | // Tally transaction fees | ||
| 860 | int64 nTxFee = nValueIn - GetValueOut(); | ||
| 861 | if (nTxFee < 0) | ||
| 862 | return error("ConnectInputs() : %s nTxFee < 0", GetHash().ToString().substr(0,6).c_str()); | ||
| 863 | if (nTxFee < nMinFee) | ||
| 864 | return false; | ||
| 865 | nFees += nTxFee; | ||
| 866 | if (!MoneyRange(nFees)) | ||
| 867 | return error("ConnectInputs() : nFees out of range"); | ||
| 868 | } | ||
| 869 | |||
| 870 | if (fBlock) | ||
| 871 | { | ||
| 872 | // Add transaction to disk index | ||
| 873 | if (!txdb.AddTxIndex(*this, posThisTx, nHeight)) | ||
| 874 | return error("ConnectInputs() : AddTxPos failed"); | ||
| 875 | } | ||
| 876 | else if (fMiner) | ||
| 877 | { | ||
| 878 | // Add transaction to test pool | ||
| 879 | mapTestPool[GetHash()] = CTxIndex(CDiskTxPos(1,1,1), vout.size()); | ||
| 880 | } | ||
| 881 | |||
| 882 | return true; | ||
| 883 | } | ||
| 884 | |||
| 885 | |||
| 886 | bool CTransaction::ClientConnectInputs() | ||
| 887 | { | ||
| 888 | if (IsCoinBase()) | ||
| 889 | return false; | ||
| 890 | |||
| 891 | // Take over previous transactions' spent pointers | ||
| 892 | CRITICAL_BLOCK(cs_mapTransactions) | ||
| 893 | { | ||
| 894 | int64 nValueIn = 0; | ||
| 895 | for (int i = 0; i < vin.size(); i++) | ||
| 896 | { | ||
| 897 | // Get prev tx from single transactions in memory | ||
| 898 | COutPoint prevout = vin[i].prevout; | ||
| 899 | if (!mapTransactions.count(prevout.hash)) | ||
| 900 | return false; | ||
| 901 | CTransaction& txPrev = mapTransactions[prevout.hash]; | ||
| 902 | |||
| 903 | if (prevout.n >= txPrev.vout.size()) | ||
| 904 | return false; | ||
| 905 | |||
| 906 | // Verify signature | ||
| 907 | if (!VerifySignature(txPrev, *this, i)) | ||
| 908 | return error("ConnectInputs() : VerifySignature failed"); | ||
| 909 | |||
| 910 | ///// this is redundant with the mapNextTx stuff, not sure which I want to get rid of | ||
| 911 | ///// this has to go away now that posNext is gone | ||
| 912 | // // Check for conflicts | ||
| 913 | // if (!txPrev.vout[prevout.n].posNext.IsNull()) | ||
| 914 | // return error("ConnectInputs() : prev tx already used"); | ||
| 915 | // | ||
| 916 | // // Flag outpoints as used | ||
| 917 | // txPrev.vout[prevout.n].posNext = posThisTx; | ||
| 918 | |||
| 919 | nValueIn += txPrev.vout[prevout.n].nValue; | ||
| 920 | } | ||
| 921 | if (GetValueOut() > nValueIn) | ||
| 922 | return false; | ||
| 923 | } | ||
| 924 | |||
| 925 | return true; | ||
| 926 | } | ||
| 927 | |||
| 928 | |||
| 929 | |||
| 930 | |||
| 931 | bool CBlock::DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex) | ||
| 932 | { | ||
| 933 | // Disconnect in reverse order | ||
| 934 | for (int i = vtx.size()-1; i >= 0; i--) | ||
| 935 | if (!vtx[i].DisconnectInputs(txdb)) | ||
| 936 | return false; | ||
| 937 | |||
| 938 | // Update block index on disk without changing it in memory. | ||
| 939 | // The memory index structure will be changed after the db commits. | ||
| 940 | if (pindex->pprev) | ||
| 941 | { | ||
| 942 | CDiskBlockIndex blockindexPrev(pindex->pprev); | ||
| 943 | blockindexPrev.hashNext = 0; | ||
| 944 | txdb.WriteBlockIndex(blockindexPrev); | ||
| 945 | } | ||
| 946 | |||
| 947 | return true; | ||
| 948 | } | ||
| 949 | |||
| 950 | bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex) | ||
| 951 | { | ||
| 952 | //// issue here: it doesn't know the version | ||
| 953 | unsigned int nTxPos = pindex->nBlockPos + ::GetSerializeSize(CBlock(), SER_DISK) - 1 + GetSizeOfCompactSize(vtx.size()); | ||
| 954 | |||
| 955 | map<uint256, CTxIndex> mapUnused; | ||
| 956 | int64 nFees = 0; | ||
| 957 | foreach(CTransaction& tx, vtx) | ||
| 958 | { | ||
| 959 | CDiskTxPos posThisTx(pindex->nFile, pindex->nBlockPos, nTxPos); | ||
| 960 | nTxPos += ::GetSerializeSize(tx, SER_DISK); | ||
| 961 | |||
| 962 | if (!tx.ConnectInputs(txdb, mapUnused, posThisTx, pindex->nHeight, nFees, true, false)) | ||
| 963 | return false; | ||
| 964 | } | ||
| 965 | |||
| 966 | if (vtx[0].GetValueOut() > GetBlockValue(nFees)) | ||
| 967 | return false; | ||
| 968 | |||
| 969 | // Update block index on disk without changing it in memory. | ||
| 970 | // The memory index structure will be changed after the db commits. | ||
| 971 | if (pindex->pprev) | ||
| 972 | { | ||
| 973 | CDiskBlockIndex blockindexPrev(pindex->pprev); | ||
| 974 | blockindexPrev.hashNext = pindex->GetBlockHash(); | ||
| 975 | txdb.WriteBlockIndex(blockindexPrev); | ||
| 976 | } | ||
| 977 | |||
| 978 | // Watch for transactions paying to me | ||
| 979 | foreach(CTransaction& tx, vtx) | ||
| 980 | AddToWalletIfMine(tx, this); | ||
| 981 | |||
| 982 | return true; | ||
| 983 | } | ||
| 984 | |||
| 985 | |||
| 986 | |||
| 987 | bool Reorganize(CTxDB& txdb, CBlockIndex* pindexNew) | ||
| 988 | { | ||
| 989 | printf("*** REORGANIZE ***\n"); | ||
| 990 | |||
| 991 | // Find the fork | ||
| 992 | CBlockIndex* pfork = pindexBest; | ||
| 993 | CBlockIndex* plonger = pindexNew; | ||
| 994 | while (pfork != plonger) | ||
| 995 | { | ||
| 996 | if (!(pfork = pfork->pprev)) | ||
| 997 | return error("Reorganize() : pfork->pprev is null"); | ||
| 998 | while (plonger->nHeight > pfork->nHeight) | ||
| 999 | if (!(plonger = plonger->pprev)) | ||
| 1000 | return error("Reorganize() : plonger->pprev is null"); | ||
| 1001 | } | ||
| 1002 | |||
| 1003 | // List of what to disconnect | ||
| 1004 | vector<CBlockIndex*> vDisconnect; | ||
| 1005 | for (CBlockIndex* pindex = pindexBest; pindex != pfork; pindex = pindex->pprev) | ||
| 1006 | vDisconnect.push_back(pindex); | ||
| 1007 | |||
| 1008 | // List of what to connect | ||
| 1009 | vector<CBlockIndex*> vConnect; | ||
| 1010 | for (CBlockIndex* pindex = pindexNew; pindex != pfork; pindex = pindex->pprev) | ||
| 1011 | vConnect.push_back(pindex); | ||
| 1012 | reverse(vConnect.begin(), vConnect.end()); | ||
| 1013 | |||
| 1014 | // Disconnect shorter branch | ||
| 1015 | vector<CTransaction> vResurrect; | ||
| 1016 | foreach(CBlockIndex* pindex, vDisconnect) | ||
| 1017 | { | ||
| 1018 | CBlock block; | ||
| 1019 | if (!block.ReadFromDisk(pindex->nFile, pindex->nBlockPos, true)) | ||
| 1020 | return error("Reorganize() : ReadFromDisk for disconnect failed"); | ||
| 1021 | if (!block.DisconnectBlock(txdb, pindex)) | ||
| 1022 | return error("Reorganize() : DisconnectBlock failed"); | ||
| 1023 | |||
| 1024 | // Queue memory transactions to resurrect | ||
| 1025 | foreach(const CTransaction& tx, block.vtx) | ||
| 1026 | if (!tx.IsCoinBase()) | ||
| 1027 | vResurrect.push_back(tx); | ||
| 1028 | } | ||
| 1029 | |||
| 1030 | // Connect longer branch | ||
| 1031 | vector<CTransaction> vDelete; | ||
| 1032 | for (int i = 0; i < vConnect.size(); i++) | ||
| 1033 | { | ||
| 1034 | CBlockIndex* pindex = vConnect[i]; | ||
| 1035 | CBlock block; | ||
| 1036 | if (!block.ReadFromDisk(pindex->nFile, pindex->nBlockPos, true)) | ||
| 1037 | return error("Reorganize() : ReadFromDisk for connect failed"); | ||
| 1038 | if (!block.ConnectBlock(txdb, pindex)) | ||
| 1039 | { | ||
| 1040 | // Invalid block, delete the rest of this branch | ||
| 1041 | txdb.TxnAbort(); | ||
| 1042 | for (int j = i; j < vConnect.size(); j++) | ||
| 1043 | { | ||
| 1044 | CBlockIndex* pindex = vConnect[j]; | ||
| 1045 | pindex->EraseBlockFromDisk(); | ||
| 1046 | txdb.EraseBlockIndex(pindex->GetBlockHash()); | ||
| 1047 | mapBlockIndex.erase(pindex->GetBlockHash()); | ||
| 1048 | delete pindex; | ||
| 1049 | } | ||
| 1050 | return error("Reorganize() : ConnectBlock failed"); | ||
| 1051 | } | ||
| 1052 | |||
| 1053 | // Queue memory transactions to delete | ||
| 1054 | foreach(const CTransaction& tx, block.vtx) | ||
| 1055 | vDelete.push_back(tx); | ||
| 1056 | } | ||
| 1057 | if (!txdb.WriteHashBestChain(pindexNew->GetBlockHash())) | ||
| 1058 | return error("Reorganize() : WriteHashBestChain failed"); | ||
| 1059 | |||
| 1060 | // Commit now because resurrecting could take some time | ||
| 1061 | txdb.TxnCommit(); | ||
| 1062 | |||
| 1063 | // Disconnect shorter branch | ||
| 1064 | foreach(CBlockIndex* pindex, vDisconnect) | ||
| 1065 | if (pindex->pprev) | ||
| 1066 | pindex->pprev->pnext = NULL; | ||
| 1067 | |||
| 1068 | // Connect longer branch | ||
| 1069 | foreach(CBlockIndex* pindex, vConnect) | ||
| 1070 | if (pindex->pprev) | ||
| 1071 | pindex->pprev->pnext = pindex; | ||
| 1072 | |||
| 1073 | // Resurrect memory transactions that were in the disconnected branch | ||
| 1074 | foreach(CTransaction& tx, vResurrect) | ||
| 1075 | tx.AcceptTransaction(txdb, false); | ||
| 1076 | |||
| 1077 | // Delete redundant memory transactions that are in the connected branch | ||
| 1078 | foreach(CTransaction& tx, vDelete) | ||
| 1079 | tx.RemoveFromMemoryPool(); | ||
| 1080 | |||
| 1081 | return true; | ||
| 1082 | } | ||
| 1083 | |||
| 1084 | |||
| 1085 | bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos) | ||
| 1086 | { | ||
| 1087 | // Check for duplicate | ||
| 1088 | uint256 hash = GetHash(); | ||
| 1089 | if (mapBlockIndex.count(hash)) | ||
| 1090 | return error("AddToBlockIndex() : %s already exists", hash.ToString().substr(0,14).c_str()); | ||
| 1091 | |||
| 1092 | // Construct new block index object | ||
| 1093 | CBlockIndex* pindexNew = new CBlockIndex(nFile, nBlockPos, *this); | ||
| 1094 | if (!pindexNew) | ||
| 1095 | return error("AddToBlockIndex() : new CBlockIndex failed"); | ||
| 1096 | map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first; | ||
| 1097 | pindexNew->phashBlock = &((*mi).first); | ||
| 1098 | map<uint256, CBlockIndex*>::iterator miPrev = mapBlockIndex.find(hashPrevBlock); | ||
| 1099 | if (miPrev != mapBlockIndex.end()) | ||
| 1100 | { | ||
| 1101 | pindexNew->pprev = (*miPrev).second; | ||
| 1102 | pindexNew->nHeight = pindexNew->pprev->nHeight + 1; | ||
| 1103 | } | ||
| 1104 | |||
| 1105 | CTxDB txdb; | ||
| 1106 | txdb.TxnBegin(); | ||
| 1107 | txdb.WriteBlockIndex(CDiskBlockIndex(pindexNew)); | ||
| 1108 | |||
| 1109 | // New best | ||
| 1110 | if (pindexNew->nHeight > nBestHeight) | ||
| 1111 | { | ||
| 1112 | if (pindexGenesisBlock == NULL && hash == hashGenesisBlock) | ||
| 1113 | { | ||
| 1114 | pindexGenesisBlock = pindexNew; | ||
| 1115 | txdb.WriteHashBestChain(hash); | ||
| 1116 | } | ||
| 1117 | else if (hashPrevBlock == hashBestChain) | ||
| 1118 | { | ||
| 1119 | // Adding to current best branch | ||
| 1120 | if (!ConnectBlock(txdb, pindexNew) || !txdb.WriteHashBestChain(hash)) | ||
| 1121 | { | ||
| 1122 | txdb.TxnAbort(); | ||
| 1123 | pindexNew->EraseBlockFromDisk(); | ||
| 1124 | mapBlockIndex.erase(pindexNew->GetBlockHash()); | ||
| 1125 | delete pindexNew; | ||
| 1126 | return error("AddToBlockIndex() : ConnectBlock failed"); | ||
| 1127 | } | ||
| 1128 | txdb.TxnCommit(); | ||
| 1129 | pindexNew->pprev->pnext = pindexNew; | ||
| 1130 | |||
| 1131 | // Delete redundant memory transactions | ||
| 1132 | foreach(CTransaction& tx, vtx) | ||
| 1133 | tx.RemoveFromMemoryPool(); | ||
| 1134 | } | ||
| 1135 | else | ||
| 1136 | { | ||
| 1137 | // New best branch | ||
| 1138 | if (!Reorganize(txdb, pindexNew)) | ||
| 1139 | { | ||
| 1140 | txdb.TxnAbort(); | ||
| 1141 | return error("AddToBlockIndex() : Reorganize failed"); | ||
| 1142 | } | ||
| 1143 | } | ||
| 1144 | |||
| 1145 | // New best link | ||
| 1146 | hashBestChain = hash; | ||
| 1147 | pindexBest = pindexNew; | ||
| 1148 | nBestHeight = pindexBest->nHeight; | ||
| 1149 | nTransactionsUpdated++; | ||
| 1150 | printf("AddToBlockIndex: new best=%s height=%d\n", hashBestChain.ToString().substr(0,14).c_str(), nBestHeight); | ||
| 1151 | } | ||
| 1152 | |||
| 1153 | txdb.TxnCommit(); | ||
| 1154 | txdb.Close(); | ||
| 1155 | |||
| 1156 | // Relay wallet transactions that haven't gotten in yet | ||
| 1157 | if (pindexNew == pindexBest) | ||
| 1158 | RelayWalletTransactions(); | ||
| 1159 | |||
| 1160 | MainFrameRepaint(); | ||
| 1161 | return true; | ||
| 1162 | } | ||
| 1163 | |||
| 1164 | |||
| 1165 | |||
| 1166 | |||
| 1167 | bool CBlock::CheckBlock() const | ||
| 1168 | { | ||
| 1169 | // These are checks that are independent of context | ||
| 1170 | // that can be verified before saving an orphan block. | ||
| 1171 | |||
| 1172 | // Size limits | ||
| 1173 | if (vtx.empty() || vtx.size() > MAX_SIZE || ::GetSerializeSize(*this, SER_DISK) > MAX_SIZE) | ||
| 1174 | return error("CheckBlock() : size limits failed"); | ||
| 1175 | |||
| 1176 | // Check timestamp | ||
| 1177 | if (nTime > GetAdjustedTime() + 2 * 60 * 60) | ||
| 1178 | return error("CheckBlock() : block timestamp too far in the future"); | ||
| 1179 | |||
| 1180 | // First transaction must be coinbase, the rest must not be | ||
| 1181 | if (vtx.empty() || !vtx[0].IsCoinBase()) | ||
| 1182 | return error("CheckBlock() : first tx is not coinbase"); | ||
| 1183 | for (int i = 1; i < vtx.size(); i++) | ||
| 1184 | if (vtx[i].IsCoinBase()) | ||
| 1185 | return error("CheckBlock() : more than one coinbase"); | ||
| 1186 | |||
| 1187 | // Check transactions | ||
| 1188 | foreach(const CTransaction& tx, vtx) | ||
| 1189 | if (!tx.CheckTransaction()) | ||
| 1190 | return error("CheckBlock() : CheckTransaction failed"); | ||
| 1191 | |||
| 1192 | // Check proof of work matches claimed amount (memory-hard RandomX PoW) | ||
| 1193 | if (CBigNum().SetCompact(nBits) > bnProofOfWorkLimit) | ||
| 1194 | return error("CheckBlock() : nBits below minimum work"); | ||
| 1195 | if (GetPoWHash() > CBigNum().SetCompact(nBits).getuint256()) | ||
| 1196 | return error("CheckBlock() : RandomX proof-of-work does not match nBits"); | ||
| 1197 | |||
| 1198 | // Check merkleroot | ||
| 1199 | if (hashMerkleRoot != BuildMerkleTree()) | ||
| 1200 | return error("CheckBlock() : hashMerkleRoot mismatch"); | ||
| 1201 | |||
| 1202 | return true; | ||
| 1203 | } | ||
| 1204 | |||
| 1205 | bool CBlock::AcceptBlock() | ||
| 1206 | { | ||
| 1207 | // Check for duplicate | ||
| 1208 | uint256 hash = GetHash(); | ||
| 1209 | if (mapBlockIndex.count(hash)) | ||
| 1210 | return error("AcceptBlock() : block already in mapBlockIndex"); | ||
| 1211 | |||
| 1212 | // Get prev block index | ||
| 1213 | map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashPrevBlock); | ||
| 1214 | if (mi == mapBlockIndex.end()) | ||
| 1215 | return error("AcceptBlock() : prev block not found"); | ||
| 1216 | CBlockIndex* pindexPrev = (*mi).second; | ||
| 1217 | |||
| 1218 | // Check timestamp against prev | ||
| 1219 | if (nTime <= pindexPrev->GetMedianTimePast()) | ||
| 1220 | return error("AcceptBlock() : block's timestamp is too early"); | ||
| 1221 | |||
| 1222 | // Check proof of work | ||
| 1223 | if (nBits != GetNextWorkRequired(pindexPrev)) | ||
| 1224 | return error("AcceptBlock() : incorrect proof of work"); | ||
| 1225 | |||
| 1226 | // Write block to history file | ||
| 1227 | unsigned int nFile; | ||
| 1228 | unsigned int nBlockPos; | ||
| 1229 | if (!WriteToDisk(!fClient, nFile, nBlockPos)) | ||
| 1230 | return error("AcceptBlock() : WriteToDisk failed"); | ||
| 1231 | if (!AddToBlockIndex(nFile, nBlockPos)) | ||
| 1232 | return error("AcceptBlock() : AddToBlockIndex failed"); | ||
| 1233 | |||
| 1234 | if (hashBestChain == hash) | ||
| 1235 | RelayInventory(CInv(MSG_BLOCK, hash)); | ||
| 1236 | |||
| 1237 | // // Add atoms to user reviews for coins created | ||
| 1238 | // vector<unsigned char> vchPubKey; | ||
| 1239 | // if (ExtractPubKey(vtx[0].vout[0].scriptPubKey, false, vchPubKey)) | ||
| 1240 | // { | ||
| 1241 | // unsigned short nAtom = GetRand(USHRT_MAX - 100) + 100; | ||
| 1242 | // vector<unsigned short> vAtoms(1, nAtom); | ||
| 1243 | // AddAtomsAndPropagate(Hash(vchPubKey.begin(), vchPubKey.end()), vAtoms, true); | ||
| 1244 | // } | ||
| 1245 | |||
| 1246 | return true; | ||
| 1247 | } | ||
| 1248 | |||
| 1249 | bool ProcessBlock(CNode* pfrom, CBlock* pblock) | ||
| 1250 | { | ||
| 1251 | // Check for duplicate | ||
| 1252 | uint256 hash = pblock->GetHash(); | ||
| 1253 | if (mapBlockIndex.count(hash)) | ||
| 1254 | return error("ProcessBlock() : already have block %d %s", mapBlockIndex[hash]->nHeight, hash.ToString().substr(0,14).c_str()); | ||
| 1255 | if (mapOrphanBlocks.count(hash)) | ||
| 1256 | return error("ProcessBlock() : already have block (orphan) %s", hash.ToString().substr(0,14).c_str()); | ||
| 1257 | |||
| 1258 | // Preliminary checks | ||
| 1259 | if (!pblock->CheckBlock()) | ||
| 1260 | { | ||
| 1261 | delete pblock; | ||
| 1262 | return error("ProcessBlock() : CheckBlock FAILED"); | ||
| 1263 | } | ||
| 1264 | |||
| 1265 | // If don't already have its previous block, shunt it off to holding area until we get it | ||
| 1266 | if (!mapBlockIndex.count(pblock->hashPrevBlock)) | ||
| 1267 | { | ||
| 1268 | printf("ProcessBlock: ORPHAN BLOCK, prev=%s\n", pblock->hashPrevBlock.ToString().substr(0,14).c_str()); | ||
| 1269 | mapOrphanBlocks.insert(make_pair(hash, pblock)); | ||
| 1270 | mapOrphanBlocksByPrev.insert(make_pair(pblock->hashPrevBlock, pblock)); | ||
| 1271 | |||
| 1272 | // Ask this guy to fill in what we're missing | ||
| 1273 | if (pfrom) | ||
| 1274 | pfrom->PushMessage("getblocks", CBlockLocator(pindexBest), GetOrphanRoot(pblock)); | ||
| 1275 | return true; | ||
| 1276 | } | ||
| 1277 | |||
| 1278 | // Store to disk | ||
| 1279 | if (!pblock->AcceptBlock()) | ||
| 1280 | { | ||
| 1281 | delete pblock; | ||
| 1282 | return error("ProcessBlock() : AcceptBlock FAILED"); | ||
| 1283 | } | ||
| 1284 | delete pblock; | ||
| 1285 | |||
| 1286 | // Recursively process any orphan blocks that depended on this one | ||
| 1287 | vector<uint256> vWorkQueue; | ||
| 1288 | vWorkQueue.push_back(hash); | ||
| 1289 | for (int i = 0; i < vWorkQueue.size(); i++) | ||
| 1290 | { | ||
| 1291 | uint256 hashPrev = vWorkQueue[i]; | ||
| 1292 | for (multimap<uint256, CBlock*>::iterator mi = mapOrphanBlocksByPrev.lower_bound(hashPrev); | ||
| 1293 | mi != mapOrphanBlocksByPrev.upper_bound(hashPrev); | ||
| 1294 | ++mi) | ||
| 1295 | { | ||
| 1296 | CBlock* pblockOrphan = (*mi).second; | ||
| 1297 | if (pblockOrphan->AcceptBlock()) | ||
| 1298 | vWorkQueue.push_back(pblockOrphan->GetHash()); | ||
| 1299 | mapOrphanBlocks.erase(pblockOrphan->GetHash()); | ||
| 1300 | delete pblockOrphan; | ||
| 1301 | } | ||
| 1302 | mapOrphanBlocksByPrev.erase(hashPrev); | ||
| 1303 | } | ||
| 1304 | |||
| 1305 | printf("ProcessBlock: ACCEPTED\n"); | ||
| 1306 | return true; | ||
| 1307 | } | ||
| 1308 | |||
| 1309 | |||
| 1310 | |||
| 1311 | |||
| 1312 | |||
| 1313 | |||
| 1314 | |||
| 1315 | |||
| 1316 | template<typename Stream> | ||
| 1317 | bool ScanMessageStart(Stream& s) | ||
| 1318 | { | ||
| 1319 | // Scan ahead to the next pchMessageStart, which should normally be immediately | ||
| 1320 | // at the file pointer. Leaves file pointer at end of pchMessageStart. | ||
| 1321 | s.clear(0); | ||
| 1322 | short prevmask = s.exceptions(0); | ||
| 1323 | const char* p = BEGIN(pchMessageStart); | ||
| 1324 | try | ||
| 1325 | { | ||
| 1326 | loop | ||
| 1327 | { | ||
| 1328 | char c; | ||
| 1329 | s.read(&c, 1); | ||
| 1330 | if (s.fail()) | ||
| 1331 | { | ||
| 1332 | s.clear(0); | ||
| 1333 | s.exceptions(prevmask); | ||
| 1334 | return false; | ||
| 1335 | } | ||
| 1336 | if (*p != c) | ||
| 1337 | p = BEGIN(pchMessageStart); | ||
| 1338 | if (*p == c) | ||
| 1339 | { | ||
| 1340 | if (++p == END(pchMessageStart)) | ||
| 1341 | { | ||
| 1342 | s.clear(0); | ||
| 1343 | s.exceptions(prevmask); | ||
| 1344 | return true; | ||
| 1345 | } | ||
| 1346 | } | ||
| 1347 | } | ||
| 1348 | } | ||
| 1349 | catch (...) | ||
| 1350 | { | ||
| 1351 | s.clear(0); | ||
| 1352 | s.exceptions(prevmask); | ||
| 1353 | return false; | ||
| 1354 | } | ||
| 1355 | } | ||
| 1356 | |||
| 1357 | string GetAppDir() | ||
| 1358 | { | ||
| 1359 | string strDir; | ||
| 1360 | if (!strSetDataDir.empty()) | ||
| 1361 | { | ||
| 1362 | strDir = strSetDataDir; | ||
| 1363 | } | ||
| 1364 | #ifdef _WIN32 | ||
| 1365 | else if (getenv("APPDATA")) | ||
| 1366 | { | ||
| 1367 | strDir = strprintf("%s\\Bitflash", getenv("APPDATA")); | ||
| 1368 | } | ||
| 1369 | else if (getenv("USERPROFILE")) | ||
| 1370 | { | ||
| 1371 | string strAppData = strprintf("%s\\Application Data", getenv("USERPROFILE")); | ||
| 1372 | static bool fMkdirDone; | ||
| 1373 | if (!fMkdirDone) | ||
| 1374 | { | ||
| 1375 | fMkdirDone = true; | ||
| 1376 | _mkdir(strAppData.c_str()); | ||
| 1377 | } | ||
| 1378 | strDir = strprintf("%s\\Bitflash", strAppData.c_str()); | ||
| 1379 | } | ||
| 1380 | #else | ||
| 1381 | else if (getenv("HOME")) | ||
| 1382 | { | ||
| 1383 | strDir = strprintf("%s/.bitflash", getenv("HOME")); | ||
| 1384 | } | ||
| 1385 | #endif | ||
| 1386 | else | ||
| 1387 | { | ||
| 1388 | return "."; | ||
| 1389 | } | ||
| 1390 | static bool fMkdirDone; | ||
| 1391 | if (!fMkdirDone) | ||
| 1392 | { | ||
| 1393 | fMkdirDone = true; | ||
| 1394 | _mkdir(strDir.c_str()); | ||
| 1395 | } | ||
| 1396 | return strDir; | ||
| 1397 | } | ||
| 1398 | |||
| 1399 | FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode) | ||
| 1400 | { | ||
| 1401 | if (nFile == -1) | ||
| 1402 | return NULL; | ||
| 1403 | FILE* file = fopen(strprintf("%s/blk%04d.dat", GetAppDir().c_str(), nFile).c_str(), pszMode); | ||
| 1404 | if (!file) | ||
| 1405 | return NULL; | ||
| 1406 | if (nBlockPos != 0 && !strchr(pszMode, 'a') && !strchr(pszMode, 'w')) | ||
| 1407 | { | ||
| 1408 | if (fseek(file, nBlockPos, SEEK_SET) != 0) | ||
| 1409 | { | ||
| 1410 | fclose(file); | ||
| 1411 | return NULL; | ||
| 1412 | } | ||
| 1413 | } | ||
| 1414 | return file; | ||
| 1415 | } | ||
| 1416 | |||
| 1417 | static unsigned int nCurrentBlockFile = 1; | ||
| 1418 | |||
| 1419 | FILE* AppendBlockFile(unsigned int& nFileRet) | ||
| 1420 | { | ||
| 1421 | nFileRet = 0; | ||
| 1422 | loop | ||
| 1423 | { | ||
| 1424 | FILE* file = OpenBlockFile(nCurrentBlockFile, 0, "ab"); | ||
| 1425 | if (!file) | ||
| 1426 | return NULL; | ||
| 1427 | if (fseek(file, 0, SEEK_END) != 0) | ||
| 1428 | return NULL; | ||
| 1429 | // FAT32 filesize max 4GB, fseek and ftell max 2GB, so we must stay under 2GB | ||
| 1430 | if (ftell(file) < 0x7F000000 - MAX_SIZE) | ||
| 1431 | { | ||
| 1432 | nFileRet = nCurrentBlockFile; | ||
| 1433 | return file; | ||
| 1434 | } | ||
| 1435 | fclose(file); | ||
| 1436 | nCurrentBlockFile++; | ||
| 1437 | } | ||
| 1438 | } | ||
| 1439 | |||
| 1440 | bool LoadBlockIndex(bool fAllowNew) | ||
| 1441 | { | ||
| 1442 | // Initialize the RandomX PoW before touching any block (both the genesis | ||
| 1443 | // and verification depend on it). | ||
| 1444 | if (!RandomXInit()) | ||
| 1445 | return error("LoadBlockIndex() : RandomXInit failed"); | ||
| 1446 | |||
| 1447 | // | ||
| 1448 | // Load block index | ||
| 1449 | // | ||
| 1450 | CTxDB txdb("cr"); | ||
| 1451 | if (!txdb.LoadBlockIndex()) | ||
| 1452 | return false; | ||
| 1453 | txdb.Close(); | ||
| 1454 | |||
| 1455 | // | ||
| 1456 | // Init with genesis block | ||
| 1457 | // | ||
| 1458 | if (mapBlockIndex.empty()) | ||
| 1459 | { | ||
| 1460 | if (!fAllowNew) | ||
| 1461 | return false; | ||
| 1462 | |||
| 1463 | |||
| 1464 | // Genesis Block: | ||
| 1465 | // GetHash() = 0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f | ||
| 1466 | // hashMerkleRoot = 0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b | ||
| 1467 | // txNew.vin[0].scriptSig = 486604799 4 0x736B6E616220726F662074756F6C69616220646E6F63657320666F206B6E697262206E6F20726F6C6C65636E61684320393030322F6E614A2F33302073656D695420656854 | ||
| 1468 | // txNew.vout[0].nValue = 5000000000 | ||
| 1469 | // txNew.vout[0].scriptPubKey = 0x5F1DF16B2B704C8A578D0BBAF74D385CDE12C11EE50455F3C438EF4C3FBCF649B6DE611FEAE06279A60939E028A8D65C10B73071A6F16719274855FEB0FD8A6704 OP_CHECKSIG | ||
| 1470 | // block.nVersion = 1 | ||
| 1471 | // block.nTime = 1231006505 | ||
| 1472 | // block.nBits = 0x1d00ffff | ||
| 1473 | // block.nNonce = 2083236893 | ||
| 1474 | // CBlock(hash=000000000019d6, ver=1, hashPrevBlock=00000000000000, hashMerkleRoot=4a5e1e, nTime=1231006505, nBits=1d00ffff, nNonce=2083236893, vtx=1) | ||
| 1475 | // CTransaction(hash=4a5e1e, ver=1, vin.size=1, vout.size=1, nLockTime=0) | ||
| 1476 | // CTxIn(COutPoint(000000, -1), coinbase 04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73) | ||
| 1477 | // CTxOut(nValue=50.00000000, scriptPubKey=0x5F1DF16B2B704C8A578D0B) | ||
| 1478 | // vMerkleTree: 4a5e1e | ||
| 1479 | |||
| 1480 | // Bitflash genesis block -- own header (fair launch, 2026 stable relaunch) | ||
| 1481 | char* pszTimestamp = "Bitflash 24/Jul/2026 Fair launch: one CPU one vote, no premine"; | ||
| 1482 | CTransaction txNew; | ||
| 1483 | txNew.vin.resize(1); | ||
| 1484 | txNew.vout.resize(1); | ||
| 1485 | txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(4) << vector<unsigned char>((unsigned char*)pszTimestamp, (unsigned char*)pszTimestamp + strlen(pszTimestamp)); | ||
| 1486 | txNew.vout[0].nValue = 50 * COIN; | ||
| 1487 | txNew.vout[0].scriptPubKey = CScript() << CBigNum("0x5F1DF16B2B704C8A578D0BBAF74D385CDE12C11EE50455F3C438EF4C3FBCF649B6DE611FEAE06279A60939E028A8D65C10B73071A6F16719274855FEB0FD8A6704") << OP_CHECKSIG; | ||
| 1488 | CBlock block; | ||
| 1489 | block.vtx.push_back(txNew); | ||
| 1490 | block.hashPrevBlock = 0; | ||
| 1491 | block.hashMerkleRoot = block.BuildMerkleTree(); | ||
| 1492 | block.nVersion = 1; | ||
| 1493 | block.nTime = 1753315200; // 2026-07-24 00:00:00 UTC (stable relaunch) | ||
| 1494 | block.nBits = 0x1f0fffff; // = bnProofOfWorkLimit (Bitflash RandomX floor) | ||
| 1495 | block.nNonce = GENESIS_NONCE; | ||
| 1496 | |||
| 1497 | // If the nonce has not been found yet, mine the genesis once (RandomX) | ||
| 1498 | // and print the values to be hardcoded in the constants above. | ||
| 1499 | if (block.GetHash() != hashGenesisBlock) | ||
| 1500 | { | ||
| 1501 | printf("Mining Bitflash genesis block (RandomX)...\n"); | ||
| 1502 | uint256 hashTarget = CBigNum().SetCompact(block.nBits).getuint256(); | ||
| 1503 | while (block.GetPoWHash() > hashTarget) | ||
| 1504 | { | ||
| 1505 | if ((block.nNonce & 0x3ff) == 0) | ||
| 1506 | printf("nonce %u\r", block.nNonce); | ||
| 1507 | block.nNonce++; | ||
| 1508 | if (block.nNonce == 0) | ||
| 1509 | { | ||
| 1510 | printf("nonce overflow, incrementing nTime\n"); | ||
| 1511 | block.nTime++; | ||
| 1512 | } | ||
| 1513 | } | ||
| 1514 | printf("\n=== BITFLASH GENESIS (RandomX) FOUND ===\n"); | ||
| 1515 | printf("nTime = %u\n", block.nTime); | ||
| 1516 | printf("nNonce = %u (0x%08x)\n", block.nNonce, block.nNonce); | ||
| 1517 | printf("powhash = %s\n", block.GetPoWHash().ToString().c_str()); | ||
| 1518 | printf("hash = %s\n", block.GetHash().ToString().c_str()); | ||
| 1519 | printf("merkle = %s\n", block.hashMerkleRoot.ToString().c_str()); | ||
| 1520 | printf("========================================\n"); | ||
| 1521 | } | ||
| 1522 | |||
| 1523 | // Asserts only apply once the genesis values are hardcoded | ||
| 1524 | if (hashGenesisBlock != uint256(0)) | ||
| 1525 | { | ||
| 1526 | assert(block.hashMerkleRoot == hashGenesisMerkleRoot); | ||
| 1527 | assert(block.GetHash() == hashGenesisBlock); | ||
| 1528 | } | ||
| 1529 | |||
| 1530 | // Start new block file | ||
| 1531 | unsigned int nFile; | ||
| 1532 | unsigned int nBlockPos; | ||
| 1533 | if (!block.WriteToDisk(!fClient, nFile, nBlockPos)) | ||
| 1534 | return error("LoadBlockIndex() : writing genesis block to disk failed"); | ||
| 1535 | if (!block.AddToBlockIndex(nFile, nBlockPos)) | ||
| 1536 | return error("LoadBlockIndex() : genesis block not accepted"); | ||
| 1537 | } | ||
| 1538 | |||
| 1539 | return true; | ||
| 1540 | } | ||
| 1541 | |||
| 1542 | |||
| 1543 | |||
| 1544 | void PrintBlockTree() | ||
| 1545 | { | ||
| 1546 | // precompute tree structure | ||
| 1547 | map<CBlockIndex*, vector<CBlockIndex*> > mapNext; | ||
| 1548 | for (map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi) | ||
| 1549 | { | ||
| 1550 | CBlockIndex* pindex = (*mi).second; | ||
| 1551 | mapNext[pindex->pprev].push_back(pindex); | ||
| 1552 | // test | ||
| 1553 | //while (rand() % 3 == 0) | ||
| 1554 | // mapNext[pindex->pprev].push_back(pindex); | ||
| 1555 | } | ||
| 1556 | |||
| 1557 | vector<pair<int, CBlockIndex*> > vStack; | ||
| 1558 | vStack.push_back(make_pair(0, pindexGenesisBlock)); | ||
| 1559 | |||
| 1560 | int nPrevCol = 0; | ||
| 1561 | while (!vStack.empty()) | ||
| 1562 | { | ||
| 1563 | int nCol = vStack.back().first; | ||
| 1564 | CBlockIndex* pindex = vStack.back().second; | ||
| 1565 | vStack.pop_back(); | ||
| 1566 | |||
| 1567 | // print split or gap | ||
| 1568 | if (nCol > nPrevCol) | ||
| 1569 | { | ||
| 1570 | for (int i = 0; i < nCol-1; i++) | ||
| 1571 | printf("| "); | ||
| 1572 | printf("|\\\n"); | ||
| 1573 | } | ||
| 1574 | else if (nCol < nPrevCol) | ||
| 1575 | { | ||
| 1576 | for (int i = 0; i < nCol; i++) | ||
| 1577 | printf("| "); | ||
| 1578 | printf("|\n"); | ||
| 1579 | } | ||
| 1580 | nPrevCol = nCol; | ||
| 1581 | |||
| 1582 | // print columns | ||
| 1583 | for (int i = 0; i < nCol; i++) | ||
| 1584 | printf("| "); | ||
| 1585 | |||
| 1586 | // print item | ||
| 1587 | CBlock block; | ||
| 1588 | block.ReadFromDisk(pindex, true); | ||
| 1589 | printf("%d (%u,%u) %s %s tx %d", | ||
| 1590 | pindex->nHeight, | ||
| 1591 | pindex->nFile, | ||
| 1592 | pindex->nBlockPos, | ||
| 1593 | block.GetHash().ToString().substr(0,14).c_str(), | ||
| 1594 | DateTimeStr(block.nTime).c_str(), | ||
| 1595 | block.vtx.size()); | ||
| 1596 | |||
| 1597 | CRITICAL_BLOCK(cs_mapWallet) | ||
| 1598 | { | ||
| 1599 | if (mapWallet.count(block.vtx[0].GetHash())) | ||
| 1600 | { | ||
| 1601 | CWalletTx& wtx = mapWallet[block.vtx[0].GetHash()]; | ||
| 1602 | printf(" mine: %d %d %d", wtx.GetDepthInMainChain(), wtx.GetBlocksToMaturity(), wtx.GetCredit()); | ||
| 1603 | } | ||
| 1604 | } | ||
| 1605 | printf("\n"); | ||
| 1606 | |||
| 1607 | |||
| 1608 | // put the main timechain first | ||
| 1609 | vector<CBlockIndex*>& vNext = mapNext[pindex]; | ||
| 1610 | for (int i = 0; i < vNext.size(); i++) | ||
| 1611 | { | ||
| 1612 | if (vNext[i]->pnext) | ||
| 1613 | { | ||
| 1614 | swap(vNext[0], vNext[i]); | ||
| 1615 | break; | ||
| 1616 | } | ||
| 1617 | } | ||
| 1618 | |||
| 1619 | // iterate children | ||
| 1620 | for (int i = 0; i < vNext.size(); i++) | ||
| 1621 | vStack.push_back(make_pair(nCol+i, vNext[i])); | ||
| 1622 | } | ||
| 1623 | } | ||
| 1624 | |||
| 1625 | |||
| 1626 | |||
| 1627 | |||
| 1628 | |||
| 1629 | |||
| 1630 | |||
| 1631 | |||
| 1632 | |||
| 1633 | |||
| 1634 | ////////////////////////////////////////////////////////////////////////////// | ||
| 1635 | // | ||
| 1636 | // Messages | ||
| 1637 | // | ||
| 1638 | |||
| 1639 | |||
| 1640 | bool AlreadyHave(CTxDB& txdb, const CInv& inv) | ||
| 1641 | { | ||
| 1642 | switch (inv.type) | ||
| 1643 | { | ||
| 1644 | case MSG_TX: return mapTransactions.count(inv.hash) || txdb.ContainsTx(inv.hash); | ||
| 1645 | case MSG_BLOCK: return mapBlockIndex.count(inv.hash) || mapOrphanBlocks.count(inv.hash); | ||
| 1646 | case MSG_REVIEW: return true; | ||
| 1647 | case MSG_PRODUCT: return mapProducts.count(inv.hash); | ||
| 1648 | } | ||
| 1649 | // Don't know what it is, just say we already got one | ||
| 1650 | return true; | ||
| 1651 | } | ||
| 1652 | |||
| 1653 | |||
| 1654 | |||
| 1655 | |||
| 1656 | |||
| 1657 | |||
| 1658 | |||
| 1659 | bool ProcessMessages(CNode* pfrom) | ||
| 1660 | { | ||
| 1661 | CDataStream& vRecv = pfrom->vRecv; | ||
| 1662 | if (vRecv.empty()) | ||
| 1663 | return true; | ||
| 1664 | printf("ProcessMessages(%d bytes)\n", vRecv.size()); | ||
| 1665 | |||
| 1666 | // | ||
| 1667 | // Message format | ||
| 1668 | // (4) message start | ||
| 1669 | // (12) command | ||
| 1670 | // (4) size | ||
| 1671 | // (x) data | ||
| 1672 | // | ||
| 1673 | |||
| 1674 | loop | ||
| 1675 | { | ||
| 1676 | // Scan for message start | ||
| 1677 | CDataStream::iterator pstart = search(vRecv.begin(), vRecv.end(), BEGIN(pchMessageStart), END(pchMessageStart)); | ||
| 1678 | if (vRecv.end() - pstart < sizeof(CMessageHeader)) | ||
| 1679 | { | ||
| 1680 | if (vRecv.size() > sizeof(CMessageHeader)) | ||
| 1681 | { | ||
| 1682 | printf("\n\nPROCESSMESSAGE MESSAGESTART NOT FOUND\n\n"); | ||
| 1683 | vRecv.erase(vRecv.begin(), vRecv.end() - sizeof(CMessageHeader)); | ||
| 1684 | } | ||
| 1685 | break; | ||
| 1686 | } | ||
| 1687 | if (pstart - vRecv.begin() > 0) | ||
| 1688 | printf("\n\nPROCESSMESSAGE SKIPPED %d BYTES\n\n", pstart - vRecv.begin()); | ||
| 1689 | vRecv.erase(vRecv.begin(), pstart); | ||
| 1690 | |||
| 1691 | // Read header | ||
| 1692 | CMessageHeader hdr; | ||
| 1693 | vRecv >> hdr; | ||
| 1694 | if (!hdr.IsValid()) | ||
| 1695 | { | ||
| 1696 | printf("\n\nPROCESSMESSAGE: ERRORS IN HEADER %s\n\n\n", hdr.GetCommand().c_str()); | ||
| 1697 | continue; | ||
| 1698 | } | ||
| 1699 | string strCommand = hdr.GetCommand(); | ||
| 1700 | |||
| 1701 | // Message size | ||
| 1702 | unsigned int nMessageSize = hdr.nMessageSize; | ||
| 1703 | if (nMessageSize > vRecv.size()) | ||
| 1704 | { | ||
| 1705 | // Rewind and wait for rest of message | ||
| 1706 | ///// need a mechanism to give up waiting for overlong message size error | ||
| 1707 | printf("MESSAGE-BREAK 2\n"); | ||
| 1708 | vRecv.insert(vRecv.begin(), BEGIN(hdr), END(hdr)); | ||
| 1709 | Sleep(100); | ||
| 1710 | break; | ||
| 1711 | } | ||
| 1712 | |||
| 1713 | // Copy message to its own buffer | ||
| 1714 | CDataStream vMsg(vRecv.begin(), vRecv.begin() + nMessageSize, vRecv.nType, vRecv.nVersion); | ||
| 1715 | vRecv.ignore(nMessageSize); | ||
| 1716 | |||
| 1717 | // Process message | ||
| 1718 | bool fRet = false; | ||
| 1719 | try | ||
| 1720 | { | ||
| 1721 | CheckForShutdown(2); | ||
| 1722 | CRITICAL_BLOCK(cs_main) | ||
| 1723 | fRet = ProcessMessage(pfrom, strCommand, vMsg); | ||
| 1724 | CheckForShutdown(2); | ||
| 1725 | } | ||
| 1726 | CATCH_PRINT_EXCEPTION("ProcessMessage()") | ||
| 1727 | if (!fRet) | ||
| 1728 | printf("ProcessMessage(%s, %d bytes) from %s to %s FAILED\n", strCommand.c_str(), nMessageSize, pfrom->addr.ToString().c_str(), addrLocalHost.ToString().c_str()); | ||
| 1729 | } | ||
| 1730 | |||
| 1731 | vRecv.Compact(); | ||
| 1732 | return true; | ||
| 1733 | } | ||
| 1734 | |||
| 1735 | |||
| 1736 | |||
| 1737 | |||
| 1738 | bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) | ||
| 1739 | { | ||
| 1740 | static map<unsigned int, vector<unsigned char> > mapReuseKey; | ||
| 1741 | printf("received: %-12s (%d bytes) ", strCommand.c_str(), vRecv.size()); | ||
| 1742 | for (int i = 0; i < min(vRecv.size(), (unsigned int)25); i++) | ||
| 1743 | printf("%02x ", vRecv[i] & 0xff); | ||
| 1744 | printf("\n"); | ||
| 1745 | if (nDropMessagesTest > 0 && GetRand(nDropMessagesTest) == 0) | ||
| 1746 | { | ||
| 1747 | printf("dropmessages DROPPING RECV MESSAGE\n"); | ||
| 1748 | return true; | ||
| 1749 | } | ||
| 1750 | |||
| 1751 | |||
| 1752 | |||
| 1753 | if (strCommand == "version") | ||
| 1754 | { | ||
| 1755 | // Can only do this once | ||
| 1756 | if (pfrom->nVersion != 0) | ||
| 1757 | return false; | ||
| 1758 | |||
| 1759 | int64 nTime; | ||
| 1760 | CAddress addrMe; | ||
| 1761 | vRecv >> pfrom->nVersion >> pfrom->nServices >> nTime >> addrMe; | ||
| 1762 | if (pfrom->nVersion == 0) | ||
| 1763 | return false; | ||
| 1764 | |||
| 1765 | pfrom->vSend.SetVersion(min(pfrom->nVersion, VERSION)); | ||
| 1766 | pfrom->vRecv.SetVersion(min(pfrom->nVersion, VERSION)); | ||
| 1767 | |||
| 1768 | pfrom->fClient = !(pfrom->nServices & NODE_NETWORK); | ||
| 1769 | if (pfrom->fClient) | ||
| 1770 | { | ||
| 1771 | pfrom->vSend.nType |= SER_BLOCKHEADERONLY; | ||
| 1772 | pfrom->vRecv.nType |= SER_BLOCKHEADERONLY; | ||
| 1773 | } | ||
| 1774 | |||
| 1775 | AddTimeData(pfrom->addr.ip, nTime); | ||
| 1776 | |||
| 1777 | // Ask the first connected node for block updates | ||
| 1778 | static bool fAskedForBlocks; | ||
| 1779 | if (!fAskedForBlocks && !pfrom->fClient) | ||
| 1780 | { | ||
| 1781 | fAskedForBlocks = true; | ||
| 1782 | pfrom->PushMessage("getblocks", CBlockLocator(pindexBest), uint256(0)); | ||
| 1783 | } | ||
| 1784 | |||
| 1785 | printf("version addrMe = %s\n", addrMe.ToString().c_str()); | ||
| 1786 | } | ||
| 1787 | |||
| 1788 | |||
| 1789 | else if (pfrom->nVersion == 0) | ||
| 1790 | { | ||
| 1791 | // Must have a version message before anything else | ||
| 1792 | return false; | ||
| 1793 | } | ||
| 1794 | |||
| 1795 | |||
| 1796 | else if (strCommand == "addr") | ||
| 1797 | { | ||
| 1798 | vector<CAddress> vAddr; | ||
| 1799 | vRecv >> vAddr; | ||
| 1800 | |||
| 1801 | // Store the new addresses | ||
| 1802 | CAddrDB addrdb; | ||
| 1803 | foreach(const CAddress& addr, vAddr) | ||
| 1804 | { | ||
| 1805 | if (fShutdown) | ||
| 1806 | return true; | ||
| 1807 | if (AddAddress(addrdb, addr)) | ||
| 1808 | { | ||
| 1809 | // Put on lists to send to other nodes | ||
| 1810 | pfrom->setAddrKnown.insert(addr); | ||
| 1811 | CRITICAL_BLOCK(cs_vNodes) | ||
| 1812 | foreach(CNode* pnode, vNodes) | ||
| 1813 | if (!pnode->setAddrKnown.count(addr)) | ||
| 1814 | pnode->vAddrToSend.push_back(addr); | ||
| 1815 | } | ||
| 1816 | } | ||
| 1817 | } | ||
| 1818 | |||
| 1819 | |||
| 1820 | else if (strCommand == "inv") | ||
| 1821 | { | ||
| 1822 | vector<CInv> vInv; | ||
| 1823 | vRecv >> vInv; | ||
| 1824 | |||
| 1825 | CTxDB txdb("r"); | ||
| 1826 | foreach(const CInv& inv, vInv) | ||
| 1827 | { | ||
| 1828 | if (fShutdown) | ||
| 1829 | return true; | ||
| 1830 | pfrom->AddInventoryKnown(inv); | ||
| 1831 | |||
| 1832 | bool fAlreadyHave = AlreadyHave(txdb, inv); | ||
| 1833 | printf(" got inventory: %s %s\n", inv.ToString().c_str(), fAlreadyHave ? "have" : "new"); | ||
| 1834 | |||
| 1835 | if (!fAlreadyHave) | ||
| 1836 | pfrom->AskFor(inv); | ||
| 1837 | else if (inv.type == MSG_BLOCK && mapOrphanBlocks.count(inv.hash)) | ||
| 1838 | pfrom->PushMessage("getblocks", CBlockLocator(pindexBest), GetOrphanRoot(mapOrphanBlocks[inv.hash])); | ||
| 1839 | } | ||
| 1840 | } | ||
| 1841 | |||
| 1842 | |||
| 1843 | else if (strCommand == "getdata") | ||
| 1844 | { | ||
| 1845 | vector<CInv> vInv; | ||
| 1846 | vRecv >> vInv; | ||
| 1847 | |||
| 1848 | foreach(const CInv& inv, vInv) | ||
| 1849 | { | ||
| 1850 | if (fShutdown) | ||
| 1851 | return true; | ||
| 1852 | printf("received getdata for: %s\n", inv.ToString().c_str()); | ||
| 1853 | |||
| 1854 | if (inv.type == MSG_BLOCK) | ||
| 1855 | { | ||
| 1856 | // Send block from disk | ||
| 1857 | map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(inv.hash); | ||
| 1858 | if (mi != mapBlockIndex.end()) | ||
| 1859 | { | ||
| 1860 | //// could optimize this to send header straight from blockindex for client | ||
| 1861 | CBlock block; | ||
| 1862 | block.ReadFromDisk((*mi).second, !pfrom->fClient); | ||
| 1863 | pfrom->PushMessage("block", block); | ||
| 1864 | } | ||
| 1865 | } | ||
| 1866 | else if (inv.IsKnownType()) | ||
| 1867 | { | ||
| 1868 | // Send stream from relay memory | ||
| 1869 | CRITICAL_BLOCK(cs_mapRelay) | ||
| 1870 | { | ||
| 1871 | map<CInv, CDataStream>::iterator mi = mapRelay.find(inv); | ||
| 1872 | if (mi != mapRelay.end()) | ||
| 1873 | pfrom->PushMessage(inv.GetCommand(), (*mi).second); | ||
| 1874 | } | ||
| 1875 | } | ||
| 1876 | } | ||
| 1877 | } | ||
| 1878 | |||
| 1879 | |||
| 1880 | else if (strCommand == "getblocks") | ||
| 1881 | { | ||
| 1882 | CBlockLocator locator; | ||
| 1883 | uint256 hashStop; | ||
| 1884 | vRecv >> locator >> hashStop; | ||
| 1885 | |||
| 1886 | // Find the first block the caller has in the main chain | ||
| 1887 | CBlockIndex* pindex = locator.GetBlockIndex(); | ||
| 1888 | |||
| 1889 | // Send the rest of the chain | ||
| 1890 | if (pindex) | ||
| 1891 | pindex = pindex->pnext; | ||
| 1892 | printf("getblocks %d to %s\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().substr(0,14).c_str()); | ||
| 1893 | for (; pindex; pindex = pindex->pnext) | ||
| 1894 | { | ||
| 1895 | if (pindex->GetBlockHash() == hashStop) | ||
| 1896 | { | ||
| 1897 | printf(" getblocks stopping at %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,14).c_str()); | ||
| 1898 | break; | ||
| 1899 | } | ||
| 1900 | |||
| 1901 | // Bypass setInventoryKnown in case an inventory message got lost | ||
| 1902 | CRITICAL_BLOCK(pfrom->cs_inventory) | ||
| 1903 | { | ||
| 1904 | CInv inv(MSG_BLOCK, pindex->GetBlockHash()); | ||
| 1905 | // returns true if wasn't already contained in the set | ||
| 1906 | if (pfrom->setInventoryKnown2.insert(inv).second) | ||
| 1907 | { | ||
| 1908 | pfrom->setInventoryKnown.erase(inv); | ||
| 1909 | pfrom->vInventoryToSend.push_back(inv); | ||
| 1910 | } | ||
| 1911 | } | ||
| 1912 | } | ||
| 1913 | } | ||
| 1914 | |||
| 1915 | |||
| 1916 | else if (strCommand == "tx") | ||
| 1917 | { | ||
| 1918 | vector<uint256> vWorkQueue; | ||
| 1919 | CDataStream vMsg(vRecv); | ||
| 1920 | CTransaction tx; | ||
| 1921 | vRecv >> tx; | ||
| 1922 | |||
| 1923 | CInv inv(MSG_TX, tx.GetHash()); | ||
| 1924 | pfrom->AddInventoryKnown(inv); | ||
| 1925 | |||
| 1926 | bool fMissingInputs = false; | ||
| 1927 | if (tx.AcceptTransaction(true, &fMissingInputs)) | ||
| 1928 | { | ||
| 1929 | AddToWalletIfMine(tx, NULL); | ||
| 1930 | RelayMessage(inv, vMsg); | ||
| 1931 | mapAlreadyAskedFor.erase(inv); | ||
| 1932 | vWorkQueue.push_back(inv.hash); | ||
| 1933 | |||
| 1934 | // Recursively process any orphan transactions that depended on this one | ||
| 1935 | for (int i = 0; i < vWorkQueue.size(); i++) | ||
| 1936 | { | ||
| 1937 | uint256 hashPrev = vWorkQueue[i]; | ||
| 1938 | for (multimap<uint256, CDataStream*>::iterator mi = mapOrphanTransactionsByPrev.lower_bound(hashPrev); | ||
| 1939 | mi != mapOrphanTransactionsByPrev.upper_bound(hashPrev); | ||
| 1940 | ++mi) | ||
| 1941 | { | ||
| 1942 | const CDataStream& vMsg = *((*mi).second); | ||
| 1943 | CTransaction tx; | ||
| 1944 | CDataStream(vMsg) >> tx; | ||
| 1945 | CInv inv(MSG_TX, tx.GetHash()); | ||
| 1946 | |||
| 1947 | if (tx.AcceptTransaction(true)) | ||
| 1948 | { | ||
| 1949 | printf(" accepted orphan tx %s\n", inv.hash.ToString().substr(0,6).c_str()); | ||
| 1950 | AddToWalletIfMine(tx, NULL); | ||
| 1951 | RelayMessage(inv, vMsg); | ||
| 1952 | mapAlreadyAskedFor.erase(inv); | ||
| 1953 | vWorkQueue.push_back(inv.hash); | ||
| 1954 | } | ||
| 1955 | } | ||
| 1956 | } | ||
| 1957 | |||
| 1958 | foreach(uint256 hash, vWorkQueue) | ||
| 1959 | EraseOrphanTx(hash); | ||
| 1960 | } | ||
| 1961 | else if (fMissingInputs) | ||
| 1962 | { | ||
| 1963 | printf("storing orphan tx %s\n", inv.hash.ToString().substr(0,6).c_str()); | ||
| 1964 | AddOrphanTx(vMsg); | ||
| 1965 | } | ||
| 1966 | } | ||
| 1967 | |||
| 1968 | |||
| 1969 | else if (strCommand == "review") | ||
| 1970 | { | ||
| 1971 | CDataStream vMsg(vRecv); | ||
| 1972 | CReview review; | ||
| 1973 | vRecv >> review; | ||
| 1974 | |||
| 1975 | CInv inv(MSG_REVIEW, review.GetHash()); | ||
| 1976 | pfrom->AddInventoryKnown(inv); | ||
| 1977 | |||
| 1978 | if (review.AcceptReview()) | ||
| 1979 | { | ||
| 1980 | // Relay the original message as-is in case it's a higher version than we know how to parse | ||
| 1981 | RelayMessage(inv, vMsg); | ||
| 1982 | mapAlreadyAskedFor.erase(inv); | ||
| 1983 | } | ||
| 1984 | } | ||
| 1985 | |||
| 1986 | |||
| 1987 | else if (strCommand == "block") | ||
| 1988 | { | ||
| 1989 | auto_ptr<CBlock> pblock(new CBlock); | ||
| 1990 | vRecv >> *pblock; | ||
| 1991 | |||
| 1992 | //// debug print | ||
| 1993 | printf("received block:\n"); pblock->print(); | ||
| 1994 | |||
| 1995 | CInv inv(MSG_BLOCK, pblock->GetHash()); | ||
| 1996 | pfrom->AddInventoryKnown(inv); | ||
| 1997 | |||
| 1998 | if (ProcessBlock(pfrom, pblock.release())) | ||
| 1999 | mapAlreadyAskedFor.erase(inv); | ||
| 2000 | } | ||
| 2001 | |||
| 2002 | |||
| 2003 | else if (strCommand == "getaddr") | ||
| 2004 | { | ||
| 2005 | pfrom->vAddrToSend.clear(); | ||
| 2006 | //// need to expand the time range if not enough found | ||
| 2007 | int64 nSince = GetAdjustedTime() - 60 * 60; // in the last hour | ||
| 2008 | CRITICAL_BLOCK(cs_mapAddresses) | ||
| 2009 | { | ||
| 2010 | foreach(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses) | ||
| 2011 | { | ||
| 2012 | if (fShutdown) | ||
| 2013 | return true; | ||
| 2014 | const CAddress& addr = item.second; | ||
| 2015 | if (addr.nTime > nSince) | ||
| 2016 | pfrom->vAddrToSend.push_back(addr); | ||
| 2017 | } | ||
| 2018 | } | ||
| 2019 | } | ||
| 2020 | |||
| 2021 | |||
| 2022 | else if (strCommand == "checkorder") | ||
| 2023 | { | ||
| 2024 | uint256 hashReply; | ||
| 2025 | CWalletTx order; | ||
| 2026 | vRecv >> hashReply >> order; | ||
| 2027 | |||
| 2028 | /// we have a chance to check the order here | ||
| 2029 | |||
| 2030 | // Keep giving the same key to the same ip until they use it | ||
| 2031 | if (!mapReuseKey.count(pfrom->addr.ip)) | ||
| 2032 | mapReuseKey[pfrom->addr.ip] = GenerateNewKey(); | ||
| 2033 | |||
| 2034 | // Send back approval of order and pubkey to use | ||
| 2035 | CScript scriptPubKey; | ||
| 2036 | scriptPubKey << mapReuseKey[pfrom->addr.ip] << OP_CHECKSIG; | ||
| 2037 | pfrom->PushMessage("reply", hashReply, (int)0, scriptPubKey); | ||
| 2038 | } | ||
| 2039 | |||
| 2040 | |||
| 2041 | else if (strCommand == "submitorder") | ||
| 2042 | { | ||
| 2043 | uint256 hashReply; | ||
| 2044 | CWalletTx wtxNew; | ||
| 2045 | vRecv >> hashReply >> wtxNew; | ||
| 2046 | |||
| 2047 | // Broadcast | ||
| 2048 | if (!wtxNew.AcceptWalletTransaction()) | ||
| 2049 | { | ||
| 2050 | pfrom->PushMessage("reply", hashReply, (int)1); | ||
| 2051 | return error("submitorder AcceptWalletTransaction() failed, returning error 1"); | ||
| 2052 | } | ||
| 2053 | wtxNew.fTimeReceivedIsTxTime = true; | ||
| 2054 | AddToWallet(wtxNew); | ||
| 2055 | wtxNew.RelayWalletTransaction(); | ||
| 2056 | mapReuseKey.erase(pfrom->addr.ip); | ||
| 2057 | |||
| 2058 | // Send back confirmation | ||
| 2059 | pfrom->PushMessage("reply", hashReply, (int)0); | ||
| 2060 | } | ||
| 2061 | |||
| 2062 | |||
| 2063 | else if (strCommand == "reply") | ||
| 2064 | { | ||
| 2065 | uint256 hashReply; | ||
| 2066 | vRecv >> hashReply; | ||
| 2067 | |||
| 2068 | CRequestTracker tracker; | ||
| 2069 | CRITICAL_BLOCK(pfrom->cs_mapRequests) | ||
| 2070 | { | ||
| 2071 | map<uint256, CRequestTracker>::iterator mi = pfrom->mapRequests.find(hashReply); | ||
| 2072 | if (mi != pfrom->mapRequests.end()) | ||
| 2073 | { | ||
| 2074 | tracker = (*mi).second; | ||
| 2075 | pfrom->mapRequests.erase(mi); | ||
| 2076 | } | ||
| 2077 | } | ||
| 2078 | if (!tracker.IsNull()) | ||
| 2079 | tracker.fn(tracker.param1, vRecv); | ||
| 2080 | } | ||
| 2081 | |||
| 2082 | |||
| 2083 | else | ||
| 2084 | { | ||
| 2085 | // Ignore unknown commands for extensibility | ||
| 2086 | printf("ProcessMessage(%s) : Ignored unknown message\n", strCommand.c_str()); | ||
| 2087 | } | ||
| 2088 | |||
| 2089 | |||
| 2090 | if (!vRecv.empty()) | ||
| 2091 | printf("ProcessMessage(%s) : %d extra bytes\n", strCommand.c_str(), vRecv.size()); | ||
| 2092 | |||
| 2093 | return true; | ||
| 2094 | } | ||
| 2095 | |||
| 2096 | |||
| 2097 | |||
| 2098 | |||
| 2099 | |||
| 2100 | |||
| 2101 | |||
| 2102 | |||
| 2103 | |||
| 2104 | bool SendMessages(CNode* pto) | ||
| 2105 | { | ||
| 2106 | CheckForShutdown(2); | ||
| 2107 | CRITICAL_BLOCK(cs_main) | ||
| 2108 | { | ||
| 2109 | // Don't send anything until we get their version message | ||
| 2110 | if (pto->nVersion == 0) | ||
| 2111 | return true; | ||
| 2112 | |||
| 2113 | |||
| 2114 | // | ||
| 2115 | // Message: addr | ||
| 2116 | // | ||
| 2117 | vector<CAddress> vAddrToSend; | ||
| 2118 | vAddrToSend.reserve(pto->vAddrToSend.size()); | ||
| 2119 | foreach(const CAddress& addr, pto->vAddrToSend) | ||
| 2120 | if (!pto->setAddrKnown.count(addr)) | ||
| 2121 | vAddrToSend.push_back(addr); | ||
| 2122 | pto->vAddrToSend.clear(); | ||
| 2123 | if (!vAddrToSend.empty()) | ||
| 2124 | pto->PushMessage("addr", vAddrToSend); | ||
| 2125 | |||
| 2126 | |||
| 2127 | // | ||
| 2128 | // Message: inventory | ||
| 2129 | // | ||
| 2130 | vector<CInv> vInventoryToSend; | ||
| 2131 | CRITICAL_BLOCK(pto->cs_inventory) | ||
| 2132 | { | ||
| 2133 | vInventoryToSend.reserve(pto->vInventoryToSend.size()); | ||
| 2134 | foreach(const CInv& inv, pto->vInventoryToSend) | ||
| 2135 | { | ||
| 2136 | // returns true if wasn't already contained in the set | ||
| 2137 | if (pto->setInventoryKnown.insert(inv).second) | ||
| 2138 | vInventoryToSend.push_back(inv); | ||
| 2139 | } | ||
| 2140 | pto->vInventoryToSend.clear(); | ||
| 2141 | pto->setInventoryKnown2.clear(); | ||
| 2142 | } | ||
| 2143 | if (!vInventoryToSend.empty()) | ||
| 2144 | pto->PushMessage("inv", vInventoryToSend); | ||
| 2145 | |||
| 2146 | |||
| 2147 | // | ||
| 2148 | // Message: getdata | ||
| 2149 | // | ||
| 2150 | vector<CInv> vAskFor; | ||
| 2151 | int64 nNow = GetTime() * 1000000; | ||
| 2152 | CTxDB txdb("r"); | ||
| 2153 | while (!pto->mapAskFor.empty() && (*pto->mapAskFor.begin()).first <= nNow) | ||
| 2154 | { | ||
| 2155 | const CInv& inv = (*pto->mapAskFor.begin()).second; | ||
| 2156 | printf("sending getdata: %s\n", inv.ToString().c_str()); | ||
| 2157 | if (!AlreadyHave(txdb, inv)) | ||
| 2158 | vAskFor.push_back(inv); | ||
| 2159 | pto->mapAskFor.erase(pto->mapAskFor.begin()); | ||
| 2160 | } | ||
| 2161 | if (!vAskFor.empty()) | ||
| 2162 | pto->PushMessage("getdata", vAskFor); | ||
| 2163 | |||
| 2164 | } | ||
| 2165 | return true; | ||
| 2166 | } | ||
| 2167 | |||
| 2168 | |||
| 2169 | |||
| 2170 | |||
| 2171 | |||
| 2172 | |||
| 2173 | |||
| 2174 | |||
| 2175 | |||
| 2176 | |||
| 2177 | |||
| 2178 | |||
| 2179 | |||
| 2180 | |||
| 2181 | ////////////////////////////////////////////////////////////////////////////// | ||
| 2182 | // | ||
| 2183 | // BitcoinMiner | ||
| 2184 | // | ||
| 2185 | |||
| 2186 | int FormatHashBlocks(void* pbuffer, unsigned int len) | ||
| 2187 | { | ||
| 2188 | unsigned char* pdata = (unsigned char*)pbuffer; | ||
| 2189 | unsigned int blocks = 1 + ((len + 8) / 64); | ||
| 2190 | unsigned char* pend = pdata + 64 * blocks; | ||
| 2191 | memset(pdata + len, 0, 64 * blocks - len); | ||
| 2192 | pdata[len] = 0x80; | ||
| 2193 | unsigned int bits = len * 8; | ||
| 2194 | pend[-1] = (bits >> 0) & 0xff; | ||
| 2195 | pend[-2] = (bits >> 8) & 0xff; | ||
| 2196 | pend[-3] = (bits >> 16) & 0xff; | ||
| 2197 | pend[-4] = (bits >> 24) & 0xff; | ||
| 2198 | return blocks; | ||
| 2199 | } | ||
| 2200 | |||
| 2201 | using CryptoPP::ByteReverse; | ||
| 2202 | static int detectlittleendian = 1; | ||
| 2203 | |||
| 2204 | void BlockSHA256(const void* pin, unsigned int nBlocks, void* pout) | ||
| 2205 | { | ||
| 2206 | unsigned int* pinput = (unsigned int*)pin; | ||
| 2207 | unsigned int* pstate = (unsigned int*)pout; | ||
| 2208 | |||
| 2209 | CryptoPP::SHA256::InitState(pstate); | ||
| 2210 | |||
| 2211 | if (*(char*)&detectlittleendian != 0) | ||
| 2212 | { | ||
| 2213 | for (int n = 0; n < nBlocks; n++) | ||
| 2214 | { | ||
| 2215 | unsigned int pbuf[16]; | ||
| 2216 | for (int i = 0; i < 16; i++) | ||
| 2217 | pbuf[i] = ByteReverse(pinput[n * 16 + i]); | ||
| 2218 | CryptoPP::SHA256::Transform(pstate, pbuf); | ||
| 2219 | } | ||
| 2220 | for (int i = 0; i < 8; i++) | ||
| 2221 | pstate[i] = ByteReverse(pstate[i]); | ||
| 2222 | } | ||
| 2223 | else | ||
| 2224 | { | ||
| 2225 | for (int n = 0; n < nBlocks; n++) | ||
| 2226 | CryptoPP::SHA256::Transform(pstate, pinput + n * 16); | ||
| 2227 | } | ||
| 2228 | } | ||
| 2229 | |||
| 2230 | |||
| 2231 | bool BitcoinMiner() | ||
| 2232 | { | ||
| 2233 | printf("BitcoinMiner started\n"); | ||
| 2234 | SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST); | ||
| 2235 | |||
| 2236 | CKey key; | ||
| 2237 | key.MakeNewKey(); | ||
| 2238 | CBigNum bnExtraNonce = 0; | ||
| 2239 | while (fGenerateBitcoins) | ||
| 2240 | { | ||
| 2241 | Sleep(50); | ||
| 2242 | CheckForShutdown(3); | ||
| 2243 | while (vNodes.empty() && !fSoloMineTest) | ||
| 2244 | { | ||
| 2245 | Sleep(1000); | ||
| 2246 | CheckForShutdown(3); | ||
| 2247 | } | ||
| 2248 | |||
| 2249 | unsigned int nTransactionsUpdatedLast = nTransactionsUpdated; | ||
| 2250 | CBlockIndex* pindexPrev = pindexBest; | ||
| 2251 | unsigned int nBits = GetNextWorkRequired(pindexPrev); | ||
| 2252 | |||
| 2253 | |||
| 2254 | // | ||
| 2255 | // Create coinbase tx | ||
| 2256 | // | ||
| 2257 | CTransaction txNew; | ||
| 2258 | txNew.vin.resize(1); | ||
| 2259 | txNew.vin[0].prevout.SetNull(); | ||
| 2260 | txNew.vin[0].scriptSig << nBits << ++bnExtraNonce; | ||
| 2261 | txNew.vout.resize(1); | ||
| 2262 | txNew.vout[0].scriptPubKey << key.GetPubKey() << OP_CHECKSIG; | ||
| 2263 | |||
| 2264 | |||
| 2265 | // | ||
| 2266 | // Create new block | ||
| 2267 | // | ||
| 2268 | auto_ptr<CBlock> pblock(new CBlock()); | ||
| 2269 | if (!pblock.get()) | ||
| 2270 | return false; | ||
| 2271 | |||
| 2272 | // Add our coinbase tx as first transaction | ||
| 2273 | pblock->vtx.push_back(txNew); | ||
| 2274 | |||
| 2275 | // Collect the latest transactions into the block | ||
| 2276 | int64 nFees = 0; | ||
| 2277 | CRITICAL_BLOCK(cs_main) | ||
| 2278 | CRITICAL_BLOCK(cs_mapTransactions) | ||
| 2279 | { | ||
| 2280 | CTxDB txdb("r"); | ||
| 2281 | map<uint256, CTxIndex> mapTestPool; | ||
| 2282 | vector<char> vfAlreadyAdded(mapTransactions.size()); | ||
| 2283 | bool fFoundSomething = true; | ||
| 2284 | unsigned int nBlockSize = 0; | ||
| 2285 | while (fFoundSomething && nBlockSize < MAX_SIZE/2) | ||
| 2286 | { | ||
| 2287 | fFoundSomething = false; | ||
| 2288 | unsigned int n = 0; | ||
| 2289 | for (map<uint256, CTransaction>::iterator mi = mapTransactions.begin(); mi != mapTransactions.end(); ++mi, ++n) | ||
| 2290 | { | ||
| 2291 | if (vfAlreadyAdded[n]) | ||
| 2292 | continue; | ||
| 2293 | CTransaction& tx = (*mi).second; | ||
| 2294 | if (tx.IsCoinBase() || !tx.IsFinal()) | ||
| 2295 | continue; | ||
| 2296 | |||
| 2297 | // Transaction fee requirements, mainly only needed for flood control | ||
| 2298 | // Under 10K (about 80 inputs) is free for first 100 transactions | ||
| 2299 | // Base rate is 0.01 per KB | ||
| 2300 | int64 nMinFee = tx.GetMinFee(pblock->vtx.size() < 100); | ||
| 2301 | |||
| 2302 | map<uint256, CTxIndex> mapTestPoolTmp(mapTestPool); | ||
| 2303 | if (!tx.ConnectInputs(txdb, mapTestPoolTmp, CDiskTxPos(1,1,1), 0, nFees, false, true, nMinFee)) | ||
| 2304 | continue; | ||
| 2305 | swap(mapTestPool, mapTestPoolTmp); | ||
| 2306 | |||
| 2307 | pblock->vtx.push_back(tx); | ||
| 2308 | nBlockSize += ::GetSerializeSize(tx, SER_NETWORK); | ||
| 2309 | vfAlreadyAdded[n] = true; | ||
| 2310 | fFoundSomething = true; | ||
| 2311 | } | ||
| 2312 | } | ||
| 2313 | } | ||
| 2314 | pblock->nBits = nBits; | ||
| 2315 | pblock->vtx[0].vout[0].nValue = pblock->GetBlockValue(nFees); | ||
| 2316 | printf("\n\nRunning BitcoinMiner with %d transactions in block\n", pblock->vtx.size()); | ||
| 2317 | |||
| 2318 | |||
| 2319 | // | ||
| 2320 | // Prepare the block header | ||
| 2321 | // | ||
| 2322 | pblock->hashPrevBlock = (pindexPrev ? pindexPrev->GetBlockHash() : 0); | ||
| 2323 | pblock->hashMerkleRoot = pblock->BuildMerkleTree(); | ||
| 2324 | pblock->nTime = max((pindexPrev ? pindexPrev->GetMedianTimePast()+1 : 0), GetAdjustedTime()); | ||
| 2325 | pblock->nBits = nBits; | ||
| 2326 | pblock->nNonce = 1; | ||
| 2327 | |||
| 2328 | |||
| 2329 | // | ||
| 2330 | // Search (memory-hard RandomX PoW) -- each thread uses its own VM | ||
| 2331 | // | ||
| 2332 | void* rxvm = RandomXCreateMinerVM(); | ||
| 2333 | if (!rxvm) | ||
| 2334 | { | ||
| 2335 | printf("BitcoinMiner: failed to create RandomX VM\n"); | ||
| 2336 | Sleep(1000); | ||
| 2337 | continue; | ||
| 2338 | } | ||
| 2339 | printf("BitcoinMiner: mining with RandomX (%s)\n", | ||
| 2340 | RandomXFastReady() ? "fast 2GB" : "light 256MB"); | ||
| 2341 | |||
| 2342 | unsigned int nStart = GetTime(); | ||
| 2343 | uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); | ||
| 2344 | loop | ||
| 2345 | { | ||
| 2346 | uint256 hash = RandomXHashWithVM(rxvm, (const void*)BEGIN(pblock->nVersion), | ||
| 2347 | END(pblock->nNonce) - BEGIN(pblock->nVersion)); | ||
| 2348 | |||
| 2349 | if (hash <= hashTarget) | ||
| 2350 | { | ||
| 2351 | //// debug print | ||
| 2352 | printf("BitcoinMiner:\n"); | ||
| 2353 | printf("RandomX proof-of-work found \n powhash: %s \ntarget: %s\n", hash.GetHex().c_str(), hashTarget.GetHex().c_str()); | ||
| 2354 | pblock->print(); | ||
| 2355 | |||
| 2356 | SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL); | ||
| 2357 | CRITICAL_BLOCK(cs_main) | ||
| 2358 | { | ||
| 2359 | // Save key | ||
| 2360 | if (!AddKey(key)) | ||
| 2361 | { | ||
| 2362 | RandomXDestroyMinerVM(rxvm); | ||
| 2363 | return false; | ||
| 2364 | } | ||
| 2365 | key.MakeNewKey(); | ||
| 2366 | |||
| 2367 | // Process this block the same as if we had received it from another node | ||
| 2368 | if (!ProcessBlock(NULL, pblock.release())) | ||
| 2369 | printf("ERROR in BitcoinMiner, ProcessBlock, block not accepted\n"); | ||
| 2370 | } | ||
| 2371 | SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST); | ||
| 2372 | |||
| 2373 | Sleep(500); | ||
| 2374 | break; | ||
| 2375 | } | ||
| 2376 | |||
| 2377 | // Check stop conditions periodically (RandomX is slow, so every | ||
| 2378 | // ~256 hashes is already plenty of time) | ||
| 2379 | if ((++pblock->nNonce & 0xff) == 0) | ||
| 2380 | { | ||
| 2381 | CheckForShutdown(3); | ||
| 2382 | if (pblock->nNonce == 0) | ||
| 2383 | break; | ||
| 2384 | if (pindexPrev != pindexBest) | ||
| 2385 | break; | ||
| 2386 | if (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60) | ||
| 2387 | break; | ||
| 2388 | if (!fGenerateBitcoins) | ||
| 2389 | break; | ||
| 2390 | pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); | ||
| 2391 | } | ||
| 2392 | } | ||
| 2393 | RandomXDestroyMinerVM(rxvm); | ||
| 2394 | } | ||
| 2395 | |||
| 2396 | return true; | ||
| 2397 | } | ||
| 2398 | |||
| 2399 | |||
| 2400 | |||
| 2401 | |||
| 2402 | |||
| 2403 | |||
| 2404 | |||
| 2405 | |||
| 2406 | |||
| 2407 | |||
| 2408 | |||
| 2409 | |||
| 2410 | |||
| 2411 | |||
| 2412 | |||
| 2413 | |||
| 2414 | |||
| 2415 | |||
| 2416 | ////////////////////////////////////////////////////////////////////////////// | ||
| 2417 | // | ||
| 2418 | // Actions | ||
| 2419 | // | ||
| 2420 | |||
| 2421 | |||
| 2422 | int64 GetBalance() | ||
| 2423 | { | ||
| 2424 | int64 nStart, nEnd; | ||
| 2425 | QueryPerformanceCounter((LARGE_INTEGER*)&nStart); | ||
| 2426 | |||
| 2427 | int64 nTotal = 0; | ||
| 2428 | CRITICAL_BLOCK(cs_mapWallet) | ||
| 2429 | { | ||
| 2430 | for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) | ||
| 2431 | { | ||
| 2432 | CWalletTx* pcoin = &(*it).second; | ||
| 2433 | if (!pcoin->IsFinal() || pcoin->fSpent) | ||
| 2434 | continue; | ||
| 2435 | nTotal += pcoin->GetCredit(); | ||
| 2436 | } | ||
| 2437 | } | ||
| 2438 | |||
| 2439 | QueryPerformanceCounter((LARGE_INTEGER*)&nEnd); | ||
| 2440 | ///printf(" GetBalance() time = %16I64d\n", nEnd - nStart); | ||
| 2441 | return nTotal; | ||
| 2442 | } | ||
| 2443 | |||
| 2444 | |||
| 2445 | |||
| 2446 | bool SelectCoins(int64 nTargetValue, set<CWalletTx*>& setCoinsRet) | ||
| 2447 | { | ||
| 2448 | setCoinsRet.clear(); | ||
| 2449 | |||
| 2450 | // List of values less than target | ||
| 2451 | int64 nLowestLarger = _I64_MAX; | ||
| 2452 | CWalletTx* pcoinLowestLarger = NULL; | ||
| 2453 | vector<pair<int64, CWalletTx*> > vValue; | ||
| 2454 | int64 nTotalLower = 0; | ||
| 2455 | |||
| 2456 | CRITICAL_BLOCK(cs_mapWallet) | ||
| 2457 | { | ||
| 2458 | for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) | ||
| 2459 | { | ||
| 2460 | CWalletTx* pcoin = &(*it).second; | ||
| 2461 | if (!pcoin->IsFinal() || pcoin->fSpent) | ||
| 2462 | continue; | ||
| 2463 | int64 n = pcoin->GetCredit(); | ||
| 2464 | if (n <= 0) | ||
| 2465 | continue; | ||
| 2466 | if (n < nTargetValue) | ||
| 2467 | { | ||
| 2468 | vValue.push_back(make_pair(n, pcoin)); | ||
| 2469 | nTotalLower += n; | ||
| 2470 | } | ||
| 2471 | else if (n == nTargetValue) | ||
| 2472 | { | ||
| 2473 | setCoinsRet.insert(pcoin); | ||
| 2474 | return true; | ||
| 2475 | } | ||
| 2476 | else if (n < nLowestLarger) | ||
| 2477 | { | ||
| 2478 | nLowestLarger = n; | ||
| 2479 | pcoinLowestLarger = pcoin; | ||
| 2480 | } | ||
| 2481 | } | ||
| 2482 | } | ||
| 2483 | |||
| 2484 | if (nTotalLower < nTargetValue) | ||
| 2485 | { | ||
| 2486 | if (pcoinLowestLarger == NULL) | ||
| 2487 | return false; | ||
| 2488 | setCoinsRet.insert(pcoinLowestLarger); | ||
| 2489 | return true; | ||
| 2490 | } | ||
| 2491 | |||
| 2492 | // Solve subset sum by stochastic approximation | ||
| 2493 | sort(vValue.rbegin(), vValue.rend()); | ||
| 2494 | vector<char> vfIncluded; | ||
| 2495 | vector<char> vfBest(vValue.size(), true); | ||
| 2496 | int64 nBest = nTotalLower; | ||
| 2497 | |||
| 2498 | for (int nRep = 0; nRep < 1000 && nBest != nTargetValue; nRep++) | ||
| 2499 | { | ||
| 2500 | vfIncluded.assign(vValue.size(), false); | ||
| 2501 | int64 nTotal = 0; | ||
| 2502 | bool fReachedTarget = false; | ||
| 2503 | for (int nPass = 0; nPass < 2 && !fReachedTarget; nPass++) | ||
| 2504 | { | ||
| 2505 | for (int i = 0; i < vValue.size(); i++) | ||
| 2506 | { | ||
| 2507 | if (nPass == 0 ? rand() % 2 : !vfIncluded[i]) | ||
| 2508 | { | ||
| 2509 | nTotal += vValue[i].first; | ||
| 2510 | vfIncluded[i] = true; | ||
| 2511 | if (nTotal >= nTargetValue) | ||
| 2512 | { | ||
| 2513 | fReachedTarget = true; | ||
| 2514 | if (nTotal < nBest) | ||
| 2515 | { | ||
| 2516 | nBest = nTotal; | ||
| 2517 | vfBest = vfIncluded; | ||
| 2518 | } | ||
| 2519 | nTotal -= vValue[i].first; | ||
| 2520 | vfIncluded[i] = false; | ||
| 2521 | } | ||
| 2522 | } | ||
| 2523 | } | ||
| 2524 | } | ||
| 2525 | } | ||
| 2526 | |||
| 2527 | // If the next larger is still closer, return it | ||
| 2528 | if (pcoinLowestLarger && nLowestLarger - nTargetValue <= nBest - nTargetValue) | ||
| 2529 | setCoinsRet.insert(pcoinLowestLarger); | ||
| 2530 | else | ||
| 2531 | { | ||
| 2532 | for (int i = 0; i < vValue.size(); i++) | ||
| 2533 | if (vfBest[i]) | ||
| 2534 | setCoinsRet.insert(vValue[i].second); | ||
| 2535 | |||
| 2536 | //// debug print | ||
| 2537 | printf("SelectCoins() best subset: "); | ||
| 2538 | for (int i = 0; i < vValue.size(); i++) | ||
| 2539 | if (vfBest[i]) | ||
| 2540 | printf("%s ", FormatMoney(vValue[i].first).c_str()); | ||
| 2541 | printf("total %s\n", FormatMoney(nBest).c_str()); | ||
| 2542 | } | ||
| 2543 | |||
| 2544 | return true; | ||
| 2545 | } | ||
| 2546 | |||
| 2547 | |||
| 2548 | |||
| 2549 | |||
| 2550 | bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, int64& nFeeRequiredRet) | ||
| 2551 | { | ||
| 2552 | nFeeRequiredRet = 0; | ||
| 2553 | CRITICAL_BLOCK(cs_main) | ||
| 2554 | { | ||
| 2555 | // txdb must be opened before the mapWallet lock | ||
| 2556 | CTxDB txdb("r"); | ||
| 2557 | CRITICAL_BLOCK(cs_mapWallet) | ||
| 2558 | { | ||
| 2559 | int64 nFee = nTransactionFee; | ||
| 2560 | loop | ||
| 2561 | { | ||
| 2562 | wtxNew.vin.clear(); | ||
| 2563 | wtxNew.vout.clear(); | ||
| 2564 | if (nValue < 0) | ||
| 2565 | return false; | ||
| 2566 | int64 nValueOut = nValue; | ||
| 2567 | nValue += nFee; | ||
| 2568 | |||
| 2569 | // Choose coins to use | ||
| 2570 | set<CWalletTx*> setCoins; | ||
| 2571 | if (!SelectCoins(nValue, setCoins)) | ||
| 2572 | return false; | ||
| 2573 | int64 nValueIn = 0; | ||
| 2574 | foreach(CWalletTx* pcoin, setCoins) | ||
| 2575 | nValueIn += pcoin->GetCredit(); | ||
| 2576 | |||
| 2577 | // Fill vout[0] to the payee | ||
| 2578 | wtxNew.vout.push_back(CTxOut(nValueOut, scriptPubKey)); | ||
| 2579 | |||
| 2580 | // Fill vout[1] back to self with any change | ||
| 2581 | if (nValueIn > nValue) | ||
| 2582 | { | ||
| 2583 | // Use the same key as one of the coins | ||
| 2584 | vector<unsigned char> vchPubKey; | ||
| 2585 | CTransaction& txFirst = *(*setCoins.begin()); | ||
| 2586 | foreach(const CTxOut& txout, txFirst.vout) | ||
| 2587 | if (txout.IsMine()) | ||
| 2588 | if (ExtractPubKey(txout.scriptPubKey, true, vchPubKey)) | ||
| 2589 | break; | ||
| 2590 | if (vchPubKey.empty()) | ||
| 2591 | return false; | ||
| 2592 | |||
| 2593 | // Fill vout[1] to ourself | ||
| 2594 | CScript scriptPubKey; | ||
| 2595 | scriptPubKey << vchPubKey << OP_CHECKSIG; | ||
| 2596 | wtxNew.vout.push_back(CTxOut(nValueIn - nValue, scriptPubKey)); | ||
| 2597 | } | ||
| 2598 | |||
| 2599 | // Fill vin | ||
| 2600 | foreach(CWalletTx* pcoin, setCoins) | ||
| 2601 | for (int nOut = 0; nOut < pcoin->vout.size(); nOut++) | ||
| 2602 | if (pcoin->vout[nOut].IsMine()) | ||
| 2603 | wtxNew.vin.push_back(CTxIn(pcoin->GetHash(), nOut)); | ||
| 2604 | |||
| 2605 | // Sign | ||
| 2606 | int nIn = 0; | ||
| 2607 | foreach(CWalletTx* pcoin, setCoins) | ||
| 2608 | for (int nOut = 0; nOut < pcoin->vout.size(); nOut++) | ||
| 2609 | if (pcoin->vout[nOut].IsMine()) | ||
| 2610 | SignSignature(*pcoin, wtxNew, nIn++); | ||
| 2611 | |||
| 2612 | // Check that enough fee is included | ||
| 2613 | if (nFee < wtxNew.GetMinFee(true)) | ||
| 2614 | { | ||
| 2615 | nFee = nFeeRequiredRet = wtxNew.GetMinFee(true); | ||
| 2616 | continue; | ||
| 2617 | } | ||
| 2618 | |||
| 2619 | // Fill vtxPrev by copying from previous transactions vtxPrev | ||
| 2620 | wtxNew.AddSupportingTransactions(txdb); | ||
| 2621 | wtxNew.fTimeReceivedIsTxTime = true; | ||
| 2622 | |||
| 2623 | break; | ||
| 2624 | } | ||
| 2625 | } | ||
| 2626 | } | ||
| 2627 | return true; | ||
| 2628 | } | ||
| 2629 | |||
| 2630 | // Call after CreateTransaction unless you want to abort | ||
| 2631 | bool CommitTransactionSpent(const CWalletTx& wtxNew) | ||
| 2632 | { | ||
| 2633 | CRITICAL_BLOCK(cs_main) | ||
| 2634 | CRITICAL_BLOCK(cs_mapWallet) | ||
| 2635 | { | ||
| 2636 | //// todo: make this transactional, never want to add a transaction | ||
| 2637 | //// without marking spent transactions | ||
| 2638 | |||
| 2639 | // Add tx to wallet, because if it has change it's also ours, | ||
| 2640 | // otherwise just for transaction history. | ||
| 2641 | AddToWallet(wtxNew); | ||
| 2642 | |||
| 2643 | // Mark old coins as spent | ||
| 2644 | set<CWalletTx*> setCoins; | ||
| 2645 | foreach(const CTxIn& txin, wtxNew.vin) | ||
| 2646 | setCoins.insert(&mapWallet[txin.prevout.hash]); | ||
| 2647 | foreach(CWalletTx* pcoin, setCoins) | ||
| 2648 | { | ||
| 2649 | pcoin->fSpent = true; | ||
| 2650 | pcoin->WriteToDisk(); | ||
| 2651 | vWalletUpdated.push_back(make_pair(pcoin->GetHash(), false)); | ||
| 2652 | } | ||
| 2653 | } | ||
| 2654 | MainFrameRepaint(); | ||
| 2655 | return true; | ||
| 2656 | } | ||
| 2657 | |||
| 2658 | |||
| 2659 | |||
| 2660 | |||
| 2661 | bool SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew) | ||
| 2662 | { | ||
| 2663 | CRITICAL_BLOCK(cs_main) | ||
| 2664 | { | ||
| 2665 | int64 nFeeRequired; | ||
| 2666 | if (!CreateTransaction(scriptPubKey, nValue, wtxNew, nFeeRequired)) | ||
| 2667 | { | ||
| 2668 | string strError; | ||
| 2669 | if (nValue + nFeeRequired > GetBalance()) | ||
| 2670 | strError = strprintf("Error: This is an oversized transaction that requires a transaction fee of %s ", FormatMoney(nFeeRequired).c_str()); | ||
| 2671 | else | ||
| 2672 | strError = "Error: Transaction creation failed "; | ||
| 2673 | wxMessageBox(strError, "Sending..."); | ||
| 2674 | return error("SendMoney() : %s\n", strError.c_str()); | ||
| 2675 | } | ||
| 2676 | if (!CommitTransactionSpent(wtxNew)) | ||
| 2677 | { | ||
| 2678 | wxMessageBox("Error finalizing transaction", "Sending..."); | ||
| 2679 | return error("SendMoney() : Error finalizing transaction"); | ||
| 2680 | } | ||
| 2681 | |||
| 2682 | printf("SendMoney: %s\n", wtxNew.GetHash().ToString().substr(0,6).c_str()); | ||
| 2683 | |||
| 2684 | // Broadcast | ||
| 2685 | if (!wtxNew.AcceptTransaction()) | ||
| 2686 | { | ||
| 2687 | // This must not fail. The transaction has already been signed and recorded. | ||
| 2688 | throw runtime_error("SendMoney() : wtxNew.AcceptTransaction() failed\n"); | ||
| 2689 | wxMessageBox("Error: Transaction not valid", "Sending..."); | ||
| 2690 | return error("SendMoney() : Error: Transaction not valid"); | ||
| 2691 | } | ||
| 2692 | wtxNew.RelayWalletTransaction(); | ||
| 2693 | } | ||
| 2694 | MainFrameRepaint(); | ||
| 2695 | return true; | ||
| 2696 | } | ||
diff --git a/src/main.h b/src/main.h new file mode 100644 index 0000000..a369476 --- /dev/null +++ b/src/main.h | |||
| @@ -0,0 +1,1361 @@ | |||
| 1 | // Copyright (c) 2009 Satoshi Nakamoto | ||
| 2 | // Distributed under the MIT/X11 software license, see the accompanying | ||
| 3 | // file license.txt or http://www.opensource.org/licenses/mit-license.php. | ||
| 4 | |||
| 5 | class COutPoint; | ||
| 6 | class CInPoint; | ||
| 7 | class CDiskTxPos; | ||
| 8 | class CCoinBase; | ||
| 9 | class CTxIn; | ||
| 10 | class CTxOut; | ||
| 11 | class CTransaction; | ||
| 12 | class CBlock; | ||
| 13 | class CBlockIndex; | ||
| 14 | class CWalletTx; | ||
| 15 | class CKeyItem; | ||
| 16 | |||
| 17 | static const unsigned int MAX_SIZE = 0x02000000; | ||
| 18 | static const int64 COIN = 100000000; | ||
| 19 | // Total Bitflash emission: identical to Bitcoin (21 million). | ||
| 20 | // MAX_MONEY guards against the value overflow bug (CVE-2010-5139), which in | ||
| 21 | // 2010 allowed creating 184 billion coins in a single transaction. | ||
| 22 | static const int64 MAX_MONEY = 21000000 * COIN; | ||
| 23 | inline bool MoneyRange(int64 nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); } | ||
| 24 | static const int64 CENT = 1000000; | ||
| 25 | static const int COINBASE_MATURITY = 100; | ||
| 26 | |||
| 27 | // Bitflash difficulty floor. The PoW is RandomX (memory-hard), ~1000x slower | ||
| 28 | // per hash than SHA-256d, so the target is much easier than Bitcoin's to let a | ||
| 29 | // CPU network start with little hashrate. Difficulty rises on its own (retarget | ||
| 30 | // toward 10-min blocks) as miners join. This does NOT affect emission | ||
| 31 | // (21 million, halving every 210,000 blocks). Tunable. | ||
| 32 | static const CBigNum bnProofOfWorkLimit(~uint256(0) >> 12); | ||
| 33 | |||
| 34 | |||
| 35 | |||
| 36 | |||
| 37 | |||
| 38 | |||
| 39 | extern CCriticalSection cs_main; | ||
| 40 | extern map<uint256, CBlockIndex*> mapBlockIndex; | ||
| 41 | extern uint256 hashGenesisBlock; | ||
| 42 | extern uint256 hashGenesisMerkleRoot; | ||
| 43 | extern unsigned int GENESIS_NONCE; | ||
| 44 | extern CBlockIndex* pindexGenesisBlock; | ||
| 45 | extern int nBestHeight; | ||
| 46 | extern uint256 hashBestChain; | ||
| 47 | extern CBlockIndex* pindexBest; | ||
| 48 | extern unsigned int nTransactionsUpdated; | ||
| 49 | extern string strSetDataDir; | ||
| 50 | extern int nDropMessagesTest; | ||
| 51 | extern bool fSoloMineTest; // /solomine: mine without requiring a peer (local test) | ||
| 52 | |||
| 53 | // Settings | ||
| 54 | extern int fGenerateBitcoins; | ||
| 55 | extern int64 nTransactionFee; | ||
| 56 | extern CAddress addrIncoming; | ||
| 57 | |||
| 58 | |||
| 59 | |||
| 60 | |||
| 61 | |||
| 62 | |||
| 63 | |||
| 64 | string GetAppDir(); | ||
| 65 | FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode="rb"); | ||
| 66 | FILE* AppendBlockFile(unsigned int& nFileRet); | ||
| 67 | bool AddKey(const CKey& key); | ||
| 68 | vector<unsigned char> GenerateNewKey(); | ||
| 69 | bool AddToWallet(const CWalletTx& wtxIn); | ||
| 70 | void ReacceptWalletTransactions(); | ||
| 71 | void RelayWalletTransactions(); | ||
| 72 | bool LoadBlockIndex(bool fAllowNew=true); | ||
| 73 | void PrintBlockTree(); | ||
| 74 | bool BitcoinMiner(); | ||
| 75 | bool ProcessMessages(CNode* pfrom); | ||
| 76 | bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv); | ||
| 77 | bool SendMessages(CNode* pto); | ||
| 78 | int64 GetBalance(); | ||
| 79 | bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& txNew, int64& nFeeRequiredRet); | ||
| 80 | bool CommitTransactionSpent(const CWalletTx& wtxNew); | ||
| 81 | bool SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew); | ||
| 82 | |||
| 83 | |||
| 84 | |||
| 85 | |||
| 86 | |||
| 87 | |||
| 88 | |||
| 89 | |||
| 90 | |||
| 91 | |||
| 92 | |||
| 93 | class CDiskTxPos | ||
| 94 | { | ||
| 95 | public: | ||
| 96 | unsigned int nFile; | ||
| 97 | unsigned int nBlockPos; | ||
| 98 | unsigned int nTxPos; | ||
| 99 | |||
| 100 | CDiskTxPos() | ||
| 101 | { | ||
| 102 | SetNull(); | ||
| 103 | } | ||
| 104 | |||
| 105 | CDiskTxPos(unsigned int nFileIn, unsigned int nBlockPosIn, unsigned int nTxPosIn) | ||
| 106 | { | ||
| 107 | nFile = nFileIn; | ||
| 108 | nBlockPos = nBlockPosIn; | ||
| 109 | nTxPos = nTxPosIn; | ||
| 110 | } | ||
| 111 | |||
| 112 | IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); ) | ||
| 113 | void SetNull() { nFile = -1; nBlockPos = 0; nTxPos = 0; } | ||
| 114 | bool IsNull() const { return (nFile == -1); } | ||
| 115 | |||
| 116 | friend bool operator==(const CDiskTxPos& a, const CDiskTxPos& b) | ||
| 117 | { | ||
| 118 | return (a.nFile == b.nFile && | ||
| 119 | a.nBlockPos == b.nBlockPos && | ||
| 120 | a.nTxPos == b.nTxPos); | ||
| 121 | } | ||
| 122 | |||
| 123 | friend bool operator!=(const CDiskTxPos& a, const CDiskTxPos& b) | ||
| 124 | { | ||
| 125 | return !(a == b); | ||
| 126 | } | ||
| 127 | |||
| 128 | string ToString() const | ||
| 129 | { | ||
| 130 | if (IsNull()) | ||
| 131 | return strprintf("null"); | ||
| 132 | else | ||
| 133 | return strprintf("(nFile=%d, nBlockPos=%d, nTxPos=%d)", nFile, nBlockPos, nTxPos); | ||
| 134 | } | ||
| 135 | |||
| 136 | void print() const | ||
| 137 | { | ||
| 138 | printf("%s", ToString().c_str()); | ||
| 139 | } | ||
| 140 | }; | ||
| 141 | |||
| 142 | |||
| 143 | |||
| 144 | |||
| 145 | class CInPoint | ||
| 146 | { | ||
| 147 | public: | ||
| 148 | CTransaction* ptx; | ||
| 149 | unsigned int n; | ||
| 150 | |||
| 151 | CInPoint() { SetNull(); } | ||
| 152 | CInPoint(CTransaction* ptxIn, unsigned int nIn) { ptx = ptxIn; n = nIn; } | ||
| 153 | void SetNull() { ptx = NULL; n = -1; } | ||
| 154 | bool IsNull() const { return (ptx == NULL && n == -1); } | ||
| 155 | }; | ||
| 156 | |||
| 157 | |||
| 158 | |||
| 159 | |||
| 160 | class COutPoint | ||
| 161 | { | ||
| 162 | public: | ||
| 163 | uint256 hash; | ||
| 164 | unsigned int n; | ||
| 165 | |||
| 166 | COutPoint() { SetNull(); } | ||
| 167 | COutPoint(uint256 hashIn, unsigned int nIn) { hash = hashIn; n = nIn; } | ||
| 168 | IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); ) | ||
| 169 | void SetNull() { hash = 0; n = -1; } | ||
| 170 | bool IsNull() const { return (hash == 0 && n == -1); } | ||
| 171 | |||
| 172 | friend bool operator<(const COutPoint& a, const COutPoint& b) | ||
| 173 | { | ||
| 174 | return (a.hash < b.hash || (a.hash == b.hash && a.n < b.n)); | ||
| 175 | } | ||
| 176 | |||
| 177 | friend bool operator==(const COutPoint& a, const COutPoint& b) | ||
| 178 | { | ||
| 179 | return (a.hash == b.hash && a.n == b.n); | ||
| 180 | } | ||
| 181 | |||
| 182 | friend bool operator!=(const COutPoint& a, const COutPoint& b) | ||
| 183 | { | ||
| 184 | return !(a == b); | ||
| 185 | } | ||
| 186 | |||
| 187 | string ToString() const | ||
| 188 | { | ||
| 189 | return strprintf("COutPoint(%s, %d)", hash.ToString().substr(0,6).c_str(), n); | ||
| 190 | } | ||
| 191 | |||
| 192 | void print() const | ||
| 193 | { | ||
| 194 | printf("%s\n", ToString().c_str()); | ||
| 195 | } | ||
| 196 | }; | ||
| 197 | |||
| 198 | |||
| 199 | |||
| 200 | |||
| 201 | // | ||
| 202 | // An input of a transaction. It contains the location of the previous | ||
| 203 | // transaction's output that it claims and a signature that matches the | ||
| 204 | // output's public key. | ||
| 205 | // | ||
| 206 | class CTxIn | ||
| 207 | { | ||
| 208 | public: | ||
| 209 | COutPoint prevout; | ||
| 210 | CScript scriptSig; | ||
| 211 | unsigned int nSequence; | ||
| 212 | |||
| 213 | CTxIn() | ||
| 214 | { | ||
| 215 | nSequence = UINT_MAX; | ||
| 216 | } | ||
| 217 | |||
| 218 | explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=UINT_MAX) | ||
| 219 | { | ||
| 220 | prevout = prevoutIn; | ||
| 221 | scriptSig = scriptSigIn; | ||
| 222 | nSequence = nSequenceIn; | ||
| 223 | } | ||
| 224 | |||
| 225 | CTxIn(uint256 hashPrevTx, unsigned int nOut, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=UINT_MAX) | ||
| 226 | { | ||
| 227 | prevout = COutPoint(hashPrevTx, nOut); | ||
| 228 | scriptSig = scriptSigIn; | ||
| 229 | nSequence = nSequenceIn; | ||
| 230 | } | ||
| 231 | |||
| 232 | IMPLEMENT_SERIALIZE | ||
| 233 | ( | ||
| 234 | READWRITE(prevout); | ||
| 235 | READWRITE(scriptSig); | ||
| 236 | READWRITE(nSequence); | ||
| 237 | ) | ||
| 238 | |||
| 239 | bool IsFinal() const | ||
| 240 | { | ||
| 241 | return (nSequence == UINT_MAX); | ||
| 242 | } | ||
| 243 | |||
| 244 | friend bool operator==(const CTxIn& a, const CTxIn& b) | ||
| 245 | { | ||
| 246 | return (a.prevout == b.prevout && | ||
| 247 | a.scriptSig == b.scriptSig && | ||
| 248 | a.nSequence == b.nSequence); | ||
| 249 | } | ||
| 250 | |||
| 251 | friend bool operator!=(const CTxIn& a, const CTxIn& b) | ||
| 252 | { | ||
| 253 | return !(a == b); | ||
| 254 | } | ||
| 255 | |||
| 256 | string ToString() const | ||
| 257 | { | ||
| 258 | string str; | ||
| 259 | str += strprintf("CTxIn("); | ||
| 260 | str += prevout.ToString(); | ||
| 261 | if (prevout.IsNull()) | ||
| 262 | str += strprintf(", coinbase %s", HexStr(scriptSig.begin(), scriptSig.end(), false).c_str()); | ||
| 263 | else | ||
| 264 | str += strprintf(", scriptSig=%s", scriptSig.ToString().substr(0,24).c_str()); | ||
| 265 | if (nSequence != UINT_MAX) | ||
| 266 | str += strprintf(", nSequence=%u", nSequence); | ||
| 267 | str += ")"; | ||
| 268 | return str; | ||
| 269 | } | ||
| 270 | |||
| 271 | void print() const | ||
| 272 | { | ||
| 273 | printf("%s\n", ToString().c_str()); | ||
| 274 | } | ||
| 275 | |||
| 276 | bool IsMine() const; | ||
| 277 | int64 GetDebit() const; | ||
| 278 | }; | ||
| 279 | |||
| 280 | |||
| 281 | |||
| 282 | |||
| 283 | // | ||
| 284 | // An output of a transaction. It contains the public key that the next input | ||
| 285 | // must be able to sign with to claim it. | ||
| 286 | // | ||
| 287 | class CTxOut | ||
| 288 | { | ||
| 289 | public: | ||
| 290 | int64 nValue; | ||
| 291 | CScript scriptPubKey; | ||
| 292 | |||
| 293 | public: | ||
| 294 | CTxOut() | ||
| 295 | { | ||
| 296 | SetNull(); | ||
| 297 | } | ||
| 298 | |||
| 299 | CTxOut(int64 nValueIn, CScript scriptPubKeyIn) | ||
| 300 | { | ||
| 301 | nValue = nValueIn; | ||
| 302 | scriptPubKey = scriptPubKeyIn; | ||
| 303 | } | ||
| 304 | |||
| 305 | IMPLEMENT_SERIALIZE | ||
| 306 | ( | ||
| 307 | READWRITE(nValue); | ||
| 308 | READWRITE(scriptPubKey); | ||
| 309 | ) | ||
| 310 | |||
| 311 | void SetNull() | ||
| 312 | { | ||
| 313 | nValue = -1; | ||
| 314 | scriptPubKey.clear(); | ||
| 315 | } | ||
| 316 | |||
| 317 | bool IsNull() | ||
| 318 | { | ||
| 319 | return (nValue == -1); | ||
| 320 | } | ||
| 321 | |||
| 322 | uint256 GetHash() const | ||
| 323 | { | ||
| 324 | return SerializeHash(*this); | ||
| 325 | } | ||
| 326 | |||
| 327 | bool IsMine() const | ||
| 328 | { | ||
| 329 | return ::IsMine(scriptPubKey); | ||
| 330 | } | ||
| 331 | |||
| 332 | int64 GetCredit() const | ||
| 333 | { | ||
| 334 | if (IsMine()) | ||
| 335 | return nValue; | ||
| 336 | return 0; | ||
| 337 | } | ||
| 338 | |||
| 339 | friend bool operator==(const CTxOut& a, const CTxOut& b) | ||
| 340 | { | ||
| 341 | return (a.nValue == b.nValue && | ||
| 342 | a.scriptPubKey == b.scriptPubKey); | ||
| 343 | } | ||
| 344 | |||
| 345 | friend bool operator!=(const CTxOut& a, const CTxOut& b) | ||
| 346 | { | ||
| 347 | return !(a == b); | ||
| 348 | } | ||
| 349 | |||
| 350 | string ToString() const | ||
| 351 | { | ||
| 352 | if (scriptPubKey.size() < 6) | ||
| 353 | return "CTxOut(error)"; | ||
| 354 | return strprintf("CTxOut(nValue=%I64d.%08I64d, scriptPubKey=%s)", nValue / COIN, nValue % COIN, scriptPubKey.ToString().substr(0,24).c_str()); | ||
| 355 | } | ||
| 356 | |||
| 357 | void print() const | ||
| 358 | { | ||
| 359 | printf("%s\n", ToString().c_str()); | ||
| 360 | } | ||
| 361 | }; | ||
| 362 | |||
| 363 | |||
| 364 | |||
| 365 | |||
| 366 | // | ||
| 367 | // The basic transaction that is broadcasted on the network and contained in | ||
| 368 | // blocks. A transaction can contain multiple inputs and outputs. | ||
| 369 | // | ||
| 370 | class CTransaction | ||
| 371 | { | ||
| 372 | public: | ||
| 373 | int nVersion; | ||
| 374 | vector<CTxIn> vin; | ||
| 375 | vector<CTxOut> vout; | ||
| 376 | int nLockTime; | ||
| 377 | |||
| 378 | |||
| 379 | CTransaction() | ||
| 380 | { | ||
| 381 | SetNull(); | ||
| 382 | } | ||
| 383 | |||
| 384 | IMPLEMENT_SERIALIZE | ||
| 385 | ( | ||
| 386 | READWRITE(this->nVersion); | ||
| 387 | nVersion = this->nVersion; | ||
| 388 | READWRITE(vin); | ||
| 389 | READWRITE(vout); | ||
| 390 | READWRITE(nLockTime); | ||
| 391 | ) | ||
| 392 | |||
| 393 | void SetNull() | ||
| 394 | { | ||
| 395 | nVersion = 1; | ||
| 396 | vin.clear(); | ||
| 397 | vout.clear(); | ||
| 398 | nLockTime = 0; | ||
| 399 | } | ||
| 400 | |||
| 401 | bool IsNull() const | ||
| 402 | { | ||
| 403 | return (vin.empty() && vout.empty()); | ||
| 404 | } | ||
| 405 | |||
| 406 | uint256 GetHash() const | ||
| 407 | { | ||
| 408 | return SerializeHash(*this); | ||
| 409 | } | ||
| 410 | |||
| 411 | bool IsFinal() const | ||
| 412 | { | ||
| 413 | if (nLockTime == 0 || nLockTime < nBestHeight) | ||
| 414 | return true; | ||
| 415 | foreach(const CTxIn& txin, vin) | ||
| 416 | if (!txin.IsFinal()) | ||
| 417 | return false; | ||
| 418 | return true; | ||
| 419 | } | ||
| 420 | |||
| 421 | bool IsNewerThan(const CTransaction& old) const | ||
| 422 | { | ||
| 423 | if (vin.size() != old.vin.size()) | ||
| 424 | return false; | ||
| 425 | for (int i = 0; i < vin.size(); i++) | ||
| 426 | if (vin[i].prevout != old.vin[i].prevout) | ||
| 427 | return false; | ||
| 428 | |||
| 429 | bool fNewer = false; | ||
| 430 | unsigned int nLowest = UINT_MAX; | ||
| 431 | for (int i = 0; i < vin.size(); i++) | ||
| 432 | { | ||
| 433 | if (vin[i].nSequence != old.vin[i].nSequence) | ||
| 434 | { | ||
| 435 | if (vin[i].nSequence <= nLowest) | ||
| 436 | { | ||
| 437 | fNewer = false; | ||
| 438 | nLowest = vin[i].nSequence; | ||
| 439 | } | ||
| 440 | if (old.vin[i].nSequence < nLowest) | ||
| 441 | { | ||
| 442 | fNewer = true; | ||
| 443 | nLowest = old.vin[i].nSequence; | ||
| 444 | } | ||
| 445 | } | ||
| 446 | } | ||
| 447 | return fNewer; | ||
| 448 | } | ||
| 449 | |||
| 450 | bool IsCoinBase() const | ||
| 451 | { | ||
| 452 | return (vin.size() == 1 && vin[0].prevout.IsNull()); | ||
| 453 | } | ||
| 454 | |||
| 455 | bool CheckTransaction() const | ||
| 456 | { | ||
| 457 | // Basic checks that don't depend on any context | ||
| 458 | if (vin.empty() || vout.empty()) | ||
| 459 | return error("CTransaction::CheckTransaction() : vin or vout empty"); | ||
| 460 | |||
| 461 | // Check for negative or overflow output values (CVE-2010-5139) | ||
| 462 | int64 nValueOut = 0; | ||
| 463 | foreach(const CTxOut& txout, vout) | ||
| 464 | { | ||
| 465 | if (txout.nValue < 0) | ||
| 466 | return error("CTransaction::CheckTransaction() : txout.nValue negative"); | ||
| 467 | if (txout.nValue > MAX_MONEY) | ||
| 468 | return error("CTransaction::CheckTransaction() : txout.nValue too high"); | ||
| 469 | nValueOut += txout.nValue; | ||
| 470 | if (!MoneyRange(nValueOut)) | ||
| 471 | return error("CTransaction::CheckTransaction() : txout total out of range"); | ||
| 472 | } | ||
| 473 | |||
| 474 | if (IsCoinBase()) | ||
| 475 | { | ||
| 476 | if (vin[0].scriptSig.size() < 2 || vin[0].scriptSig.size() > 100) | ||
| 477 | return error("CTransaction::CheckTransaction() : coinbase script size"); | ||
| 478 | } | ||
| 479 | else | ||
| 480 | { | ||
| 481 | foreach(const CTxIn& txin, vin) | ||
| 482 | if (txin.prevout.IsNull()) | ||
| 483 | return error("CTransaction::CheckTransaction() : prevout is null"); | ||
| 484 | } | ||
| 485 | |||
| 486 | // Check for duplicate inputs (a tx spending the same output twice) | ||
| 487 | set<COutPoint> vInOutPoints; | ||
| 488 | foreach(const CTxIn& txin, vin) | ||
| 489 | { | ||
| 490 | if (vInOutPoints.count(txin.prevout)) | ||
| 491 | return error("CTransaction::CheckTransaction() : duplicate inputs"); | ||
| 492 | vInOutPoints.insert(txin.prevout); | ||
| 493 | } | ||
| 494 | |||
| 495 | return true; | ||
| 496 | } | ||
| 497 | |||
| 498 | bool IsMine() const | ||
| 499 | { | ||
| 500 | foreach(const CTxOut& txout, vout) | ||
| 501 | if (txout.IsMine()) | ||
| 502 | return true; | ||
| 503 | return false; | ||
| 504 | } | ||
| 505 | |||
| 506 | int64 GetDebit() const | ||
| 507 | { | ||
| 508 | int64 nDebit = 0; | ||
| 509 | foreach(const CTxIn& txin, vin) | ||
| 510 | nDebit += txin.GetDebit(); | ||
| 511 | return nDebit; | ||
| 512 | } | ||
| 513 | |||
| 514 | int64 GetCredit() const | ||
| 515 | { | ||
| 516 | int64 nCredit = 0; | ||
| 517 | foreach(const CTxOut& txout, vout) | ||
| 518 | nCredit += txout.GetCredit(); | ||
| 519 | return nCredit; | ||
| 520 | } | ||
| 521 | |||
| 522 | int64 GetValueOut() const | ||
| 523 | { | ||
| 524 | int64 nValueOut = 0; | ||
| 525 | foreach(const CTxOut& txout, vout) | ||
| 526 | { | ||
| 527 | if (txout.nValue < 0) | ||
| 528 | throw runtime_error("CTransaction::GetValueOut() : negative value"); | ||
| 529 | if (txout.nValue > MAX_MONEY) | ||
| 530 | throw runtime_error("CTransaction::GetValueOut() : value too high"); | ||
| 531 | nValueOut += txout.nValue; | ||
| 532 | if (!MoneyRange(nValueOut)) | ||
| 533 | throw runtime_error("CTransaction::GetValueOut() : total out of range"); | ||
| 534 | } | ||
| 535 | return nValueOut; | ||
| 536 | } | ||
| 537 | |||
| 538 | int64 GetMinFee(bool fDiscount=false) const | ||
| 539 | { | ||
| 540 | unsigned int nBytes = ::GetSerializeSize(*this, SER_NETWORK); | ||
| 541 | if (fDiscount && nBytes < 10000) | ||
| 542 | return 0; | ||
| 543 | return (1 + (int64)nBytes / 1000) * CENT; | ||
| 544 | } | ||
| 545 | |||
| 546 | |||
| 547 | |||
| 548 | bool ReadFromDisk(CDiskTxPos pos, FILE** pfileRet=NULL) | ||
| 549 | { | ||
| 550 | CAutoFile filein = OpenBlockFile(pos.nFile, 0, pfileRet ? "rb+" : "rb"); | ||
| 551 | if (!filein) | ||
| 552 | return error("CTransaction::ReadFromDisk() : OpenBlockFile failed"); | ||
| 553 | |||
| 554 | // Read transaction | ||
| 555 | if (fseek(filein, pos.nTxPos, SEEK_SET) != 0) | ||
| 556 | return error("CTransaction::ReadFromDisk() : fseek failed"); | ||
| 557 | filein >> *this; | ||
| 558 | |||
| 559 | // Return file pointer | ||
| 560 | if (pfileRet) | ||
| 561 | { | ||
| 562 | if (fseek(filein, pos.nTxPos, SEEK_SET) != 0) | ||
| 563 | return error("CTransaction::ReadFromDisk() : second fseek failed"); | ||
| 564 | *pfileRet = filein.release(); | ||
| 565 | } | ||
| 566 | return true; | ||
| 567 | } | ||
| 568 | |||
| 569 | |||
| 570 | friend bool operator==(const CTransaction& a, const CTransaction& b) | ||
| 571 | { | ||
| 572 | return (a.nVersion == b.nVersion && | ||
| 573 | a.vin == b.vin && | ||
| 574 | a.vout == b.vout && | ||
| 575 | a.nLockTime == b.nLockTime); | ||
| 576 | } | ||
| 577 | |||
| 578 | friend bool operator!=(const CTransaction& a, const CTransaction& b) | ||
| 579 | { | ||
| 580 | return !(a == b); | ||
| 581 | } | ||
| 582 | |||
| 583 | |||
| 584 | string ToString() const | ||
| 585 | { | ||
| 586 | string str; | ||
| 587 | str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%d, vout.size=%d, nLockTime=%d)\n", | ||
| 588 | GetHash().ToString().substr(0,6).c_str(), | ||
| 589 | nVersion, | ||
| 590 | vin.size(), | ||
| 591 | vout.size(), | ||
| 592 | nLockTime); | ||
| 593 | for (int i = 0; i < vin.size(); i++) | ||
| 594 | str += " " + vin[i].ToString() + "\n"; | ||
| 595 | for (int i = 0; i < vout.size(); i++) | ||
| 596 | str += " " + vout[i].ToString() + "\n"; | ||
| 597 | return str; | ||
| 598 | } | ||
| 599 | |||
| 600 | void print() const | ||
| 601 | { | ||
| 602 | printf("%s", ToString().c_str()); | ||
| 603 | } | ||
| 604 | |||
| 605 | |||
| 606 | |||
| 607 | bool DisconnectInputs(CTxDB& txdb); | ||
| 608 | bool ConnectInputs(CTxDB& txdb, map<uint256, CTxIndex>& mapTestPool, CDiskTxPos posThisTx, int nHeight, int64& nFees, bool fBlock, bool fMiner, int64 nMinFee=0); | ||
| 609 | bool ClientConnectInputs(); | ||
| 610 | |||
| 611 | bool AcceptTransaction(CTxDB& txdb, bool fCheckInputs=true, bool* pfMissingInputs=NULL); | ||
| 612 | |||
| 613 | bool AcceptTransaction(bool fCheckInputs=true, bool* pfMissingInputs=NULL) | ||
| 614 | { | ||
| 615 | CTxDB txdb("r"); | ||
| 616 | return AcceptTransaction(txdb, fCheckInputs, pfMissingInputs); | ||
| 617 | } | ||
| 618 | |||
| 619 | protected: | ||
| 620 | bool AddToMemoryPool(); | ||
| 621 | public: | ||
| 622 | bool RemoveFromMemoryPool(); | ||
| 623 | }; | ||
| 624 | |||
| 625 | |||
| 626 | |||
| 627 | |||
| 628 | |||
| 629 | // | ||
| 630 | // A transaction with a merkle branch linking it to the block chain | ||
| 631 | // | ||
| 632 | class CMerkleTx : public CTransaction | ||
| 633 | { | ||
| 634 | public: | ||
| 635 | uint256 hashBlock; | ||
| 636 | vector<uint256> vMerkleBranch; | ||
| 637 | int nIndex; | ||
| 638 | |||
| 639 | // memory only | ||
| 640 | mutable bool fMerkleVerified; | ||
| 641 | |||
| 642 | |||
| 643 | CMerkleTx() | ||
| 644 | { | ||
| 645 | Init(); | ||
| 646 | } | ||
| 647 | |||
| 648 | CMerkleTx(const CTransaction& txIn) : CTransaction(txIn) | ||
| 649 | { | ||
| 650 | Init(); | ||
| 651 | } | ||
| 652 | |||
| 653 | void Init() | ||
| 654 | { | ||
| 655 | hashBlock = 0; | ||
| 656 | nIndex = -1; | ||
| 657 | fMerkleVerified = false; | ||
| 658 | } | ||
| 659 | |||
| 660 | int64 GetCredit() const | ||
| 661 | { | ||
| 662 | // Must wait until coinbase is safely deep enough in the chain before valuing it | ||
| 663 | if (IsCoinBase() && GetBlocksToMaturity() > 0) | ||
| 664 | return 0; | ||
| 665 | return CTransaction::GetCredit(); | ||
| 666 | } | ||
| 667 | |||
| 668 | IMPLEMENT_SERIALIZE | ||
| 669 | ( | ||
| 670 | nSerSize += SerReadWrite(s, *(CTransaction*)this, nType, nVersion, ser_action); | ||
| 671 | nVersion = this->nVersion; | ||
| 672 | READWRITE(hashBlock); | ||
| 673 | READWRITE(vMerkleBranch); | ||
| 674 | READWRITE(nIndex); | ||
| 675 | ) | ||
| 676 | |||
| 677 | |||
| 678 | int SetMerkleBranch(const CBlock* pblock=NULL); | ||
| 679 | int GetDepthInMainChain() const; | ||
| 680 | bool IsInMainChain() const { return GetDepthInMainChain() > 0; } | ||
| 681 | int GetBlocksToMaturity() const; | ||
| 682 | bool AcceptTransaction(CTxDB& txdb, bool fCheckInputs=true); | ||
| 683 | bool AcceptTransaction() { CTxDB txdb("r"); return AcceptTransaction(txdb); } | ||
| 684 | }; | ||
| 685 | |||
| 686 | |||
| 687 | |||
| 688 | |||
| 689 | // | ||
| 690 | // A transaction with a bunch of additional info that only the owner cares | ||
| 691 | // about. It includes any unrecorded transactions needed to link it back | ||
| 692 | // to the block chain. | ||
| 693 | // | ||
| 694 | class CWalletTx : public CMerkleTx | ||
| 695 | { | ||
| 696 | public: | ||
| 697 | vector<CMerkleTx> vtxPrev; | ||
| 698 | map<string, string> mapValue; | ||
| 699 | vector<pair<string, string> > vOrderForm; | ||
| 700 | unsigned int fTimeReceivedIsTxTime; | ||
| 701 | unsigned int nTimeReceived; // time received by this node | ||
| 702 | char fFromMe; | ||
| 703 | char fSpent; | ||
| 704 | //// probably need to sign the order info so know it came from payer | ||
| 705 | |||
| 706 | // memory only | ||
| 707 | mutable unsigned int nTimeDisplayed; | ||
| 708 | |||
| 709 | |||
| 710 | CWalletTx() | ||
| 711 | { | ||
| 712 | Init(); | ||
| 713 | } | ||
| 714 | |||
| 715 | CWalletTx(const CMerkleTx& txIn) : CMerkleTx(txIn) | ||
| 716 | { | ||
| 717 | Init(); | ||
| 718 | } | ||
| 719 | |||
| 720 | CWalletTx(const CTransaction& txIn) : CMerkleTx(txIn) | ||
| 721 | { | ||
| 722 | Init(); | ||
| 723 | } | ||
| 724 | |||
| 725 | void Init() | ||
| 726 | { | ||
| 727 | fTimeReceivedIsTxTime = false; | ||
| 728 | nTimeReceived = 0; | ||
| 729 | fFromMe = false; | ||
| 730 | fSpent = false; | ||
| 731 | nTimeDisplayed = 0; | ||
| 732 | } | ||
| 733 | |||
| 734 | IMPLEMENT_SERIALIZE | ||
| 735 | ( | ||
| 736 | nSerSize += SerReadWrite(s, *(CMerkleTx*)this, nType, nVersion, ser_action); | ||
| 737 | nVersion = this->nVersion; | ||
| 738 | READWRITE(vtxPrev); | ||
| 739 | READWRITE(mapValue); | ||
| 740 | READWRITE(vOrderForm); | ||
| 741 | READWRITE(fTimeReceivedIsTxTime); | ||
| 742 | READWRITE(nTimeReceived); | ||
| 743 | READWRITE(fFromMe); | ||
| 744 | READWRITE(fSpent); | ||
| 745 | ) | ||
| 746 | |||
| 747 | bool WriteToDisk() | ||
| 748 | { | ||
| 749 | return CWalletDB().WriteTx(GetHash(), *this); | ||
| 750 | } | ||
| 751 | |||
| 752 | |||
| 753 | int64 GetTxTime() const; | ||
| 754 | |||
| 755 | void AddSupportingTransactions(CTxDB& txdb); | ||
| 756 | |||
| 757 | bool AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs=true); | ||
| 758 | bool AcceptWalletTransaction() { CTxDB txdb("r"); return AcceptWalletTransaction(txdb); } | ||
| 759 | |||
| 760 | void RelayWalletTransaction(CTxDB& txdb); | ||
| 761 | void RelayWalletTransaction() { CTxDB txdb("r"); RelayWalletTransaction(txdb); } | ||
| 762 | }; | ||
| 763 | |||
| 764 | |||
| 765 | |||
| 766 | |||
| 767 | // | ||
| 768 | // A txdb record that contains the disk location of a transaction and the | ||
| 769 | // locations of transactions that spend its outputs. vSpent is really only | ||
| 770 | // used as a flag, but having the location is very helpful for debugging. | ||
| 771 | // | ||
| 772 | class CTxIndex | ||
| 773 | { | ||
| 774 | public: | ||
| 775 | CDiskTxPos pos; | ||
| 776 | vector<CDiskTxPos> vSpent; | ||
| 777 | |||
| 778 | CTxIndex() | ||
| 779 | { | ||
| 780 | SetNull(); | ||
| 781 | } | ||
| 782 | |||
| 783 | CTxIndex(const CDiskTxPos& posIn, unsigned int nOutputs) | ||
| 784 | { | ||
| 785 | pos = posIn; | ||
| 786 | vSpent.resize(nOutputs); | ||
| 787 | } | ||
| 788 | |||
| 789 | IMPLEMENT_SERIALIZE | ||
| 790 | ( | ||
| 791 | if (!(nType & SER_GETHASH)) | ||
| 792 | READWRITE(nVersion); | ||
| 793 | READWRITE(pos); | ||
| 794 | READWRITE(vSpent); | ||
| 795 | ) | ||
| 796 | |||
| 797 | void SetNull() | ||
| 798 | { | ||
| 799 | pos.SetNull(); | ||
| 800 | vSpent.clear(); | ||
| 801 | } | ||
| 802 | |||
| 803 | bool IsNull() | ||
| 804 | { | ||
| 805 | return pos.IsNull(); | ||
| 806 | } | ||
| 807 | |||
| 808 | friend bool operator==(const CTxIndex& a, const CTxIndex& b) | ||
| 809 | { | ||
| 810 | if (a.pos != b.pos || a.vSpent.size() != b.vSpent.size()) | ||
| 811 | return false; | ||
| 812 | for (int i = 0; i < a.vSpent.size(); i++) | ||
| 813 | if (a.vSpent[i] != b.vSpent[i]) | ||
| 814 | return false; | ||
| 815 | return true; | ||
| 816 | } | ||
| 817 | |||
| 818 | friend bool operator!=(const CTxIndex& a, const CTxIndex& b) | ||
| 819 | { | ||
| 820 | return !(a == b); | ||
| 821 | } | ||
| 822 | }; | ||
| 823 | |||
| 824 | |||
| 825 | |||
| 826 | |||
| 827 | |||
| 828 | // | ||
| 829 | // Nodes collect new transactions into a block, hash them into a hash tree, | ||
| 830 | // and scan through nonce values to make the block's hash satisfy proof-of-work | ||
| 831 | // requirements. When they solve the proof-of-work, they broadcast the block | ||
| 832 | // to everyone and the block is added to the block chain. The first transaction | ||
| 833 | // in the block is a special one that creates a new coin owned by the creator | ||
| 834 | // of the block. | ||
| 835 | // | ||
| 836 | // Blocks are appended to blk0001.dat files on disk. Their location on disk | ||
| 837 | // is indexed by CBlockIndex objects in memory. | ||
| 838 | // | ||
| 839 | class CBlock | ||
| 840 | { | ||
| 841 | public: | ||
| 842 | // header | ||
| 843 | int nVersion; | ||
| 844 | uint256 hashPrevBlock; | ||
| 845 | uint256 hashMerkleRoot; | ||
| 846 | unsigned int nTime; | ||
| 847 | unsigned int nBits; | ||
| 848 | unsigned int nNonce; | ||
| 849 | |||
| 850 | // network and disk | ||
| 851 | vector<CTransaction> vtx; | ||
| 852 | |||
| 853 | // memory only | ||
| 854 | mutable vector<uint256> vMerkleTree; | ||
| 855 | |||
| 856 | |||
| 857 | CBlock() | ||
| 858 | { | ||
| 859 | SetNull(); | ||
| 860 | } | ||
| 861 | |||
| 862 | IMPLEMENT_SERIALIZE | ||
| 863 | ( | ||
| 864 | READWRITE(this->nVersion); | ||
| 865 | nVersion = this->nVersion; | ||
| 866 | READWRITE(hashPrevBlock); | ||
| 867 | READWRITE(hashMerkleRoot); | ||
| 868 | READWRITE(nTime); | ||
| 869 | READWRITE(nBits); | ||
| 870 | READWRITE(nNonce); | ||
| 871 | |||
| 872 | // ConnectBlock depends on vtx being last so it can calculate offset | ||
| 873 | if (!(nType & (SER_GETHASH|SER_BLOCKHEADERONLY))) | ||
| 874 | READWRITE(vtx); | ||
| 875 | else if (fRead) | ||
| 876 | const_cast<CBlock*>(this)->vtx.clear(); | ||
| 877 | ) | ||
| 878 | |||
| 879 | void SetNull() | ||
| 880 | { | ||
| 881 | nVersion = 1; | ||
| 882 | hashPrevBlock = 0; | ||
| 883 | hashMerkleRoot = 0; | ||
| 884 | nTime = 0; | ||
| 885 | nBits = 0; | ||
| 886 | nNonce = 0; | ||
| 887 | vtx.clear(); | ||
| 888 | vMerkleTree.clear(); | ||
| 889 | } | ||
| 890 | |||
| 891 | bool IsNull() const | ||
| 892 | { | ||
| 893 | return (nBits == 0); | ||
| 894 | } | ||
| 895 | |||
| 896 | uint256 GetHash() const | ||
| 897 | { | ||
| 898 | // Block IDENTITY hash (SHA-256d), used for indexing. | ||
| 899 | return Hash(BEGIN(nVersion), END(nNonce)); | ||
| 900 | } | ||
| 901 | |||
| 902 | uint256 GetPoWHash() const | ||
| 903 | { | ||
| 904 | // Memory-hard PROOF-OF-WORK hash (RandomX) over the 80-byte header. | ||
| 905 | // This is the one that must be <= target (nBits). | ||
| 906 | return RandomXPoWHash((const void*)BEGIN(nVersion), END(nNonce) - BEGIN(nVersion)); | ||
| 907 | } | ||
| 908 | |||
| 909 | |||
| 910 | uint256 BuildMerkleTree() const | ||
| 911 | { | ||
| 912 | vMerkleTree.clear(); | ||
| 913 | foreach(const CTransaction& tx, vtx) | ||
| 914 | vMerkleTree.push_back(tx.GetHash()); | ||
| 915 | int j = 0; | ||
| 916 | for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2) | ||
| 917 | { | ||
| 918 | for (int i = 0; i < nSize; i += 2) | ||
| 919 | { | ||
| 920 | int i2 = min(i+1, nSize-1); | ||
| 921 | vMerkleTree.push_back(Hash(BEGIN(vMerkleTree[j+i]), END(vMerkleTree[j+i]), | ||
| 922 | BEGIN(vMerkleTree[j+i2]), END(vMerkleTree[j+i2]))); | ||
| 923 | } | ||
| 924 | j += nSize; | ||
| 925 | } | ||
| 926 | return (vMerkleTree.empty() ? 0 : vMerkleTree.back()); | ||
| 927 | } | ||
| 928 | |||
| 929 | vector<uint256> GetMerkleBranch(int nIndex) const | ||
| 930 | { | ||
| 931 | if (vMerkleTree.empty()) | ||
| 932 | BuildMerkleTree(); | ||
| 933 | vector<uint256> vMerkleBranch; | ||
| 934 | int j = 0; | ||
| 935 | for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2) | ||
| 936 | { | ||
| 937 | int i = min(nIndex^1, nSize-1); | ||
| 938 | vMerkleBranch.push_back(vMerkleTree[j+i]); | ||
| 939 | nIndex >>= 1; | ||
| 940 | j += nSize; | ||
| 941 | } | ||
| 942 | return vMerkleBranch; | ||
| 943 | } | ||
| 944 | |||
| 945 | static uint256 CheckMerkleBranch(uint256 hash, const vector<uint256>& vMerkleBranch, int nIndex) | ||
| 946 | { | ||
| 947 | if (nIndex == -1) | ||
| 948 | return 0; | ||
| 949 | foreach(const uint256& otherside, vMerkleBranch) | ||
| 950 | { | ||
| 951 | if (nIndex & 1) | ||
| 952 | hash = Hash(BEGIN(otherside), END(otherside), BEGIN(hash), END(hash)); | ||
| 953 | else | ||
| 954 | hash = Hash(BEGIN(hash), END(hash), BEGIN(otherside), END(otherside)); | ||
| 955 | nIndex >>= 1; | ||
| 956 | } | ||
| 957 | return hash; | ||
| 958 | } | ||
| 959 | |||
| 960 | |||
| 961 | bool WriteToDisk(bool fWriteTransactions, unsigned int& nFileRet, unsigned int& nBlockPosRet) | ||
| 962 | { | ||
| 963 | // Open history file to append | ||
| 964 | CAutoFile fileout = AppendBlockFile(nFileRet); | ||
| 965 | if (!fileout) | ||
| 966 | return error("CBlock::WriteToDisk() : AppendBlockFile failed"); | ||
| 967 | if (!fWriteTransactions) | ||
| 968 | fileout.nType |= SER_BLOCKHEADERONLY; | ||
| 969 | |||
| 970 | // Write index header | ||
| 971 | unsigned int nSize = fileout.GetSerializeSize(*this); | ||
| 972 | fileout << FLATDATA(pchMessageStart) << nSize; | ||
| 973 | |||
| 974 | // Write block | ||
| 975 | nBlockPosRet = ftell(fileout); | ||
| 976 | if (nBlockPosRet == -1) | ||
| 977 | return error("CBlock::WriteToDisk() : ftell failed"); | ||
| 978 | fileout << *this; | ||
| 979 | |||
| 980 | return true; | ||
| 981 | } | ||
| 982 | |||
| 983 | bool ReadFromDisk(unsigned int nFile, unsigned int nBlockPos, bool fReadTransactions) | ||
| 984 | { | ||
| 985 | SetNull(); | ||
| 986 | |||
| 987 | // Open history file to read | ||
| 988 | CAutoFile filein = OpenBlockFile(nFile, nBlockPos, "rb"); | ||
| 989 | if (!filein) | ||
| 990 | return error("CBlock::ReadFromDisk() : OpenBlockFile failed"); | ||
| 991 | if (!fReadTransactions) | ||
| 992 | filein.nType |= SER_BLOCKHEADERONLY; | ||
| 993 | |||
| 994 | // Read block | ||
| 995 | filein >> *this; | ||
| 996 | |||
| 997 | // Check the header | ||
| 998 | if (CBigNum().SetCompact(nBits) > bnProofOfWorkLimit) | ||
| 999 | return error("CBlock::ReadFromDisk() : nBits errors in block header"); | ||
| 1000 | // NOTE: the proof of work is RandomX (GetPoWHash), validated once by | ||
| 1001 | // CheckBlock when the block is accepted. Re-checking it on every disk | ||
| 1002 | // read would be prohibitively slow, and checking the SHA-256d GetHash() | ||
| 1003 | // here (a leftover from Bitcoin) is simply wrong for a RandomX chain. | ||
| 1004 | |||
| 1005 | return true; | ||
| 1006 | } | ||
| 1007 | |||
| 1008 | |||
| 1009 | |||
| 1010 | void print() const | ||
| 1011 | { | ||
| 1012 | printf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%d)\n", | ||
| 1013 | GetHash().ToString().substr(0,14).c_str(), | ||
| 1014 | nVersion, | ||
| 1015 | hashPrevBlock.ToString().substr(0,14).c_str(), | ||
| 1016 | hashMerkleRoot.ToString().substr(0,6).c_str(), | ||
| 1017 | nTime, nBits, nNonce, | ||
| 1018 | vtx.size()); | ||
| 1019 | for (int i = 0; i < vtx.size(); i++) | ||
| 1020 | { | ||
| 1021 | printf(" "); | ||
| 1022 | vtx[i].print(); | ||
| 1023 | } | ||
| 1024 | printf(" vMerkleTree: "); | ||
| 1025 | for (int i = 0; i < vMerkleTree.size(); i++) | ||
| 1026 | printf("%s ", vMerkleTree[i].ToString().substr(0,6).c_str()); | ||
| 1027 | printf("\n"); | ||
| 1028 | } | ||
| 1029 | |||
| 1030 | |||
| 1031 | int64 GetBlockValue(int64 nFees) const; | ||
| 1032 | bool DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex); | ||
| 1033 | bool ConnectBlock(CTxDB& txdb, CBlockIndex* pindex); | ||
| 1034 | bool ReadFromDisk(const CBlockIndex* blockindex, bool fReadTransactions); | ||
| 1035 | bool AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos); | ||
| 1036 | bool CheckBlock() const; | ||
| 1037 | bool AcceptBlock(); | ||
| 1038 | }; | ||
| 1039 | |||
| 1040 | |||
| 1041 | |||
| 1042 | |||
| 1043 | |||
| 1044 | |||
| 1045 | // | ||
| 1046 | // The block chain is a tree shaped structure starting with the | ||
| 1047 | // genesis block at the root, with each block potentially having multiple | ||
| 1048 | // candidates to be the next block. pprev and pnext link a path through the | ||
| 1049 | // main/longest chain. A blockindex may have multiple pprev pointing back | ||
| 1050 | // to it, but pnext will only point forward to the longest branch, or will | ||
| 1051 | // be null if the block is not part of the longest chain. | ||
| 1052 | // | ||
| 1053 | class CBlockIndex | ||
| 1054 | { | ||
| 1055 | public: | ||
| 1056 | const uint256* phashBlock; | ||
| 1057 | CBlockIndex* pprev; | ||
| 1058 | CBlockIndex* pnext; | ||
| 1059 | unsigned int nFile; | ||
| 1060 | unsigned int nBlockPos; | ||
| 1061 | int nHeight; | ||
| 1062 | |||
| 1063 | // block header | ||
| 1064 | int nVersion; | ||
| 1065 | uint256 hashMerkleRoot; | ||
| 1066 | unsigned int nTime; | ||
| 1067 | unsigned int nBits; | ||
| 1068 | unsigned int nNonce; | ||
| 1069 | |||
| 1070 | |||
| 1071 | CBlockIndex() | ||
| 1072 | { | ||
| 1073 | phashBlock = NULL; | ||
| 1074 | pprev = NULL; | ||
| 1075 | pnext = NULL; | ||
| 1076 | nFile = 0; | ||
| 1077 | nBlockPos = 0; | ||
| 1078 | nHeight = 0; | ||
| 1079 | |||
| 1080 | nVersion = 0; | ||
| 1081 | hashMerkleRoot = 0; | ||
| 1082 | nTime = 0; | ||
| 1083 | nBits = 0; | ||
| 1084 | nNonce = 0; | ||
| 1085 | } | ||
| 1086 | |||
| 1087 | CBlockIndex(unsigned int nFileIn, unsigned int nBlockPosIn, CBlock& block) | ||
| 1088 | { | ||
| 1089 | phashBlock = NULL; | ||
| 1090 | pprev = NULL; | ||
| 1091 | pnext = NULL; | ||
| 1092 | nFile = nFileIn; | ||
| 1093 | nBlockPos = nBlockPosIn; | ||
| 1094 | nHeight = 0; | ||
| 1095 | |||
| 1096 | nVersion = block.nVersion; | ||
| 1097 | hashMerkleRoot = block.hashMerkleRoot; | ||
| 1098 | nTime = block.nTime; | ||
| 1099 | nBits = block.nBits; | ||
| 1100 | nNonce = block.nNonce; | ||
| 1101 | } | ||
| 1102 | |||
| 1103 | uint256 GetBlockHash() const | ||
| 1104 | { | ||
| 1105 | return *phashBlock; | ||
| 1106 | } | ||
| 1107 | |||
| 1108 | bool IsInMainChain() const | ||
| 1109 | { | ||
| 1110 | return (pnext || this == pindexBest); | ||
| 1111 | } | ||
| 1112 | |||
| 1113 | bool EraseBlockFromDisk() | ||
| 1114 | { | ||
| 1115 | // Open history file | ||
| 1116 | CAutoFile fileout = OpenBlockFile(nFile, nBlockPos, "rb+"); | ||
| 1117 | if (!fileout) | ||
| 1118 | return false; | ||
| 1119 | |||
| 1120 | // Overwrite with empty null block | ||
| 1121 | CBlock block; | ||
| 1122 | block.SetNull(); | ||
| 1123 | fileout << block; | ||
| 1124 | |||
| 1125 | return true; | ||
| 1126 | } | ||
| 1127 | |||
| 1128 | enum { nMedianTimeSpan=11 }; | ||
| 1129 | |||
| 1130 | int64 GetMedianTimePast() const | ||
| 1131 | { | ||
| 1132 | unsigned int pmedian[nMedianTimeSpan]; | ||
| 1133 | unsigned int* pbegin = &pmedian[nMedianTimeSpan]; | ||
| 1134 | unsigned int* pend = &pmedian[nMedianTimeSpan]; | ||
| 1135 | |||
| 1136 | const CBlockIndex* pindex = this; | ||
| 1137 | for (int i = 0; i < nMedianTimeSpan && pindex; i++, pindex = pindex->pprev) | ||
| 1138 | *(--pbegin) = pindex->nTime; | ||
| 1139 | |||
| 1140 | sort(pbegin, pend); | ||
| 1141 | return pbegin[(pend - pbegin)/2]; | ||
| 1142 | } | ||
| 1143 | |||
| 1144 | int64 GetMedianTime() const | ||
| 1145 | { | ||
| 1146 | const CBlockIndex* pindex = this; | ||
| 1147 | for (int i = 0; i < nMedianTimeSpan/2; i++) | ||
| 1148 | { | ||
| 1149 | if (!pindex->pnext) | ||
| 1150 | return nTime; | ||
| 1151 | pindex = pindex->pnext; | ||
| 1152 | } | ||
| 1153 | return pindex->GetMedianTimePast(); | ||
| 1154 | } | ||
| 1155 | |||
| 1156 | |||
| 1157 | |||
| 1158 | string ToString() const | ||
| 1159 | { | ||
| 1160 | return strprintf("CBlockIndex(nprev=%08x, pnext=%08x, nFile=%d, nBlockPos=%-6d nHeight=%d, merkle=%s, hashBlock=%s)", | ||
| 1161 | pprev, pnext, nFile, nBlockPos, nHeight, | ||
| 1162 | hashMerkleRoot.ToString().substr(0,6).c_str(), | ||
| 1163 | GetBlockHash().ToString().substr(0,14).c_str()); | ||
| 1164 | } | ||
| 1165 | |||
| 1166 | void print() const | ||
| 1167 | { | ||
| 1168 | printf("%s\n", ToString().c_str()); | ||
| 1169 | } | ||
| 1170 | }; | ||
| 1171 | |||
| 1172 | |||
| 1173 | |||
| 1174 | // | ||
| 1175 | // Used to marshal pointers into hashes for db storage. | ||
| 1176 | // | ||
| 1177 | class CDiskBlockIndex : public CBlockIndex | ||
| 1178 | { | ||
| 1179 | public: | ||
| 1180 | uint256 hashPrev; | ||
| 1181 | uint256 hashNext; | ||
| 1182 | |||
| 1183 | CDiskBlockIndex() | ||
| 1184 | { | ||
| 1185 | hashPrev = 0; | ||
| 1186 | hashNext = 0; | ||
| 1187 | } | ||
| 1188 | |||
| 1189 | explicit CDiskBlockIndex(CBlockIndex* pindex) : CBlockIndex(*pindex) | ||
| 1190 | { | ||
| 1191 | hashPrev = (pprev ? pprev->GetBlockHash() : 0); | ||
| 1192 | hashNext = (pnext ? pnext->GetBlockHash() : 0); | ||
| 1193 | } | ||
| 1194 | |||
| 1195 | IMPLEMENT_SERIALIZE | ||
| 1196 | ( | ||
| 1197 | if (!(nType & SER_GETHASH)) | ||
| 1198 | READWRITE(nVersion); | ||
| 1199 | |||
| 1200 | READWRITE(hashNext); | ||
| 1201 | READWRITE(nFile); | ||
| 1202 | READWRITE(nBlockPos); | ||
| 1203 | READWRITE(nHeight); | ||
| 1204 | |||
| 1205 | // block header | ||
| 1206 | READWRITE(this->nVersion); | ||
| 1207 | READWRITE(hashPrev); | ||
| 1208 | READWRITE(hashMerkleRoot); | ||
| 1209 | READWRITE(nTime); | ||
| 1210 | READWRITE(nBits); | ||
| 1211 | READWRITE(nNonce); | ||
| 1212 | ) | ||
| 1213 | |||
| 1214 | uint256 GetBlockHash() const | ||
| 1215 | { | ||
| 1216 | CBlock block; | ||
| 1217 | block.nVersion = nVersion; | ||
| 1218 | block.hashPrevBlock = hashPrev; | ||
| 1219 | block.hashMerkleRoot = hashMerkleRoot; | ||
| 1220 | block.nTime = nTime; | ||
| 1221 | block.nBits = nBits; | ||
| 1222 | block.nNonce = nNonce; | ||
| 1223 | return block.GetHash(); | ||
| 1224 | } | ||
| 1225 | |||
| 1226 | |||
| 1227 | string ToString() const | ||
| 1228 | { | ||
| 1229 | string str = "CDiskBlockIndex("; | ||
| 1230 | str += CBlockIndex::ToString(); | ||
| 1231 | str += strprintf("\n hashBlock=%s, hashPrev=%s, hashNext=%s)", | ||
| 1232 | GetBlockHash().ToString().c_str(), | ||
| 1233 | hashPrev.ToString().substr(0,14).c_str(), | ||
| 1234 | hashNext.ToString().substr(0,14).c_str()); | ||
| 1235 | return str; | ||
| 1236 | } | ||
| 1237 | |||
| 1238 | void print() const | ||
| 1239 | { | ||
| 1240 | printf("%s\n", ToString().c_str()); | ||
| 1241 | } | ||
| 1242 | }; | ||
| 1243 | |||
| 1244 | |||
| 1245 | |||
| 1246 | |||
| 1247 | |||
| 1248 | |||
| 1249 | |||
| 1250 | |||
| 1251 | // | ||
| 1252 | // Describes a place in the block chain to another node such that if the | ||
| 1253 | // other node doesn't have the same branch, it can find a recent common trunk. | ||
| 1254 | // The further back it is, the further before the fork it may be. | ||
| 1255 | // | ||
| 1256 | class CBlockLocator | ||
| 1257 | { | ||
| 1258 | protected: | ||
| 1259 | vector<uint256> vHave; | ||
| 1260 | public: | ||
| 1261 | |||
| 1262 | CBlockLocator() | ||
| 1263 | { | ||
| 1264 | } | ||
| 1265 | |||
| 1266 | explicit CBlockLocator(const CBlockIndex* pindex) | ||
| 1267 | { | ||
| 1268 | Set(pindex); | ||
| 1269 | } | ||
| 1270 | |||
| 1271 | explicit CBlockLocator(uint256 hashBlock) | ||
| 1272 | { | ||
| 1273 | map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock); | ||
| 1274 | if (mi != mapBlockIndex.end()) | ||
| 1275 | Set((*mi).second); | ||
| 1276 | } | ||
| 1277 | |||
| 1278 | IMPLEMENT_SERIALIZE | ||
| 1279 | ( | ||
| 1280 | if (!(nType & SER_GETHASH)) | ||
| 1281 | READWRITE(nVersion); | ||
| 1282 | READWRITE(vHave); | ||
| 1283 | ) | ||
| 1284 | |||
| 1285 | void Set(const CBlockIndex* pindex) | ||
| 1286 | { | ||
| 1287 | vHave.clear(); | ||
| 1288 | int nStep = 1; | ||
| 1289 | while (pindex) | ||
| 1290 | { | ||
| 1291 | vHave.push_back(pindex->GetBlockHash()); | ||
| 1292 | |||
| 1293 | // Exponentially larger steps back | ||
| 1294 | for (int i = 0; pindex && i < nStep; i++) | ||
| 1295 | pindex = pindex->pprev; | ||
| 1296 | if (vHave.size() > 10) | ||
| 1297 | nStep *= 2; | ||
| 1298 | } | ||
| 1299 | vHave.push_back(hashGenesisBlock); | ||
| 1300 | } | ||
| 1301 | |||
| 1302 | CBlockIndex* GetBlockIndex() | ||
| 1303 | { | ||
| 1304 | // Find the first block the caller has in the main chain | ||
| 1305 | foreach(const uint256& hash, vHave) | ||
| 1306 | { | ||
| 1307 | map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash); | ||
| 1308 | if (mi != mapBlockIndex.end()) | ||
| 1309 | { | ||
| 1310 | CBlockIndex* pindex = (*mi).second; | ||
| 1311 | if (pindex->IsInMainChain()) | ||
| 1312 | return pindex; | ||
| 1313 | } | ||
| 1314 | } | ||
| 1315 | return pindexGenesisBlock; | ||
| 1316 | } | ||
| 1317 | |||
| 1318 | uint256 GetBlockHash() | ||
| 1319 | { | ||
| 1320 | // Find the first block the caller has in the main chain | ||
| 1321 | foreach(const uint256& hash, vHave) | ||
| 1322 | { | ||
| 1323 | map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash); | ||
| 1324 | if (mi != mapBlockIndex.end()) | ||
| 1325 | { | ||
| 1326 | CBlockIndex* pindex = (*mi).second; | ||
| 1327 | if (pindex->IsInMainChain()) | ||
| 1328 | return hash; | ||
| 1329 | } | ||
| 1330 | } | ||
| 1331 | return hashGenesisBlock; | ||
| 1332 | } | ||
| 1333 | |||
| 1334 | int GetHeight() | ||
| 1335 | { | ||
| 1336 | CBlockIndex* pindex = GetBlockIndex(); | ||
| 1337 | if (!pindex) | ||
| 1338 | return 0; | ||
| 1339 | return pindex->nHeight; | ||
| 1340 | } | ||
| 1341 | }; | ||
| 1342 | |||
| 1343 | |||
| 1344 | |||
| 1345 | |||
| 1346 | |||
| 1347 | |||
| 1348 | |||
| 1349 | |||
| 1350 | |||
| 1351 | |||
| 1352 | |||
| 1353 | |||
| 1354 | extern map<uint256, CTransaction> mapTransactions; | ||
| 1355 | extern map<uint256, CWalletTx> mapWallet; | ||
| 1356 | extern vector<pair<uint256, bool> > vWalletUpdated; | ||
| 1357 | extern CCriticalSection cs_mapWallet; | ||
| 1358 | extern map<vector<unsigned char>, CPrivKey> mapKeys; | ||
| 1359 | extern map<uint160, vector<unsigned char> > mapPubKeys; | ||
| 1360 | extern CCriticalSection cs_mapKeys; | ||
| 1361 | extern CKey keyUser; | ||
diff --git a/src/makefile b/src/makefile new file mode 100644 index 0000000..941a262 --- /dev/null +++ b/src/makefile | |||
| @@ -0,0 +1,83 @@ | |||
| 1 | # Copyright (c) 2009 Satoshi Nakamoto | ||
| 2 | # Distributed under the MIT/X11 software license, see the accompanying | ||
| 3 | # file license.txt or http://www.opensource.org/licenses/mit-license.php. | ||
| 4 | |||
| 5 | |||
| 6 | ifneq "$(BUILD)" "debug" | ||
| 7 | ifneq "$(BUILD)" "release" | ||
| 8 | BUILD=debug | ||
| 9 | endif | ||
| 10 | endif | ||
| 11 | ifeq "$(BUILD)" "debug" | ||
| 12 | D=d | ||
| 13 | # note: gcc 3.x profile doesn't work | ||
| 14 | #DEBUGFLAGS=-O0 -g -pg -D__WXDEBUG__ | ||
| 15 | DEBUGFLAGS=-g -D__WXDEBUG__ | ||
| 16 | endif | ||
| 17 | |||
| 18 | |||
| 19 | |||
| 20 | INCLUDEPATHS=-I"/boost" -I"/DB/build_unix" -I"/OpenSSL/include" -I"/wxWidgets/lib/vc_lib/mswd" -I"/wxWidgets/include" | ||
| 21 | LIBPATHS=-L"/DB/build_unix" -L"/OpenSSL/out" -L"/wxWidgets/lib/gcc_lib" | ||
| 22 | LIBS= \ | ||
| 23 | -l db_cxx \ | ||
| 24 | -l eay32 \ | ||
| 25 | -l wxmsw28$(D)_richtext -l wxmsw28$(D)_html -l wxmsw28$(D)_core -l wxbase28$(D) -l wxtiff$(D) -l wxjpeg$(D) -l wxpng$(D) -l wxzlib$(D) -l wxregex$(D) -l wxexpat$(D) \ | ||
| 26 | -l kernel32 -l user32 -l gdi32 -l comdlg32 -l winspool -l winmm -l shell32 -l comctl32 -l ole32 -l oleaut32 -l uuid -l rpcrt4 -l advapi32 -l ws2_32 | ||
| 27 | WXDEFS=-DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH | ||
| 28 | CFLAGS=-mthreads -O0 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) | ||
| 29 | HEADERS=headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h | ||
| 30 | |||
| 31 | |||
| 32 | |||
| 33 | all: bitcoin.exe | ||
| 34 | |||
| 35 | |||
| 36 | headers.h.gch: headers.h $(HEADERS) net.h irc.h market.h uibase.h ui.h | ||
| 37 | g++ -c $(CFLAGS) -o $@ $< | ||
| 38 | |||
| 39 | obj/util.o: util.cpp $(HEADERS) | ||
| 40 | g++ -c $(CFLAGS) -o $@ $< | ||
| 41 | |||
| 42 | obj/script.o: script.cpp $(HEADERS) | ||
| 43 | g++ -c $(CFLAGS) -o $@ $< | ||
| 44 | |||
| 45 | obj/db.o: db.cpp $(HEADERS) market.h | ||
| 46 | g++ -c $(CFLAGS) -o $@ $< | ||
| 47 | |||
| 48 | obj/net.o: net.cpp $(HEADERS) net.h | ||
| 49 | g++ -c $(CFLAGS) -o $@ $< | ||
| 50 | |||
| 51 | obj/main.o: main.cpp $(HEADERS) net.h market.h sha.h | ||
| 52 | g++ -c $(CFLAGS) -o $@ $< | ||
| 53 | |||
| 54 | obj/market.o: market.cpp $(HEADERS) market.h | ||
| 55 | g++ -c $(CFLAGS) -o $@ $< | ||
| 56 | |||
| 57 | obj/ui.o: ui.cpp $(HEADERS) net.h uibase.h ui.h market.h | ||
| 58 | g++ -c $(CFLAGS) -o $@ $< | ||
| 59 | |||
| 60 | obj/uibase.o: uibase.cpp uibase.h | ||
| 61 | g++ -c $(CFLAGS) -o $@ $< | ||
| 62 | |||
| 63 | obj/sha.o: sha.cpp sha.h | ||
| 64 | g++ -c $(CFLAGS) -O3 -o $@ $< | ||
| 65 | |||
| 66 | obj/irc.o: irc.cpp $(HEADERS) | ||
| 67 | g++ -c $(CFLAGS) -o $@ $< | ||
| 68 | |||
| 69 | obj/ui_res.o: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp | ||
| 70 | windres $(WXDEFS) $(INCLUDEPATHS) -o $@ -i $< | ||
| 71 | |||
| 72 | |||
| 73 | |||
| 74 | OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \ | ||
| 75 | obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/ui_res.o | ||
| 76 | |||
| 77 | bitcoin.exe: headers.h.gch $(OBJS) | ||
| 78 | -kill /f bitcoin.exe | ||
| 79 | g++ $(CFLAGS) -mwindows -Wl,--subsystem,windows -o $@ $(LIBPATHS) $(OBJS) $(LIBS) | ||
| 80 | |||
| 81 | clean: | ||
| 82 | -del /Q obj\* | ||
| 83 | -del /Q headers.h.gch | ||
diff --git a/src/makefile.linux b/src/makefile.linux new file mode 100644 index 0000000..682c597 --- /dev/null +++ b/src/makefile.linux | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | # Bitflash headless node/miner -- Linux build (no wxWidgets, no GUI). | ||
| 2 | # Produces `bitflash-node`: loads the chain + wallet, runs the P2P/Nostr node | ||
| 3 | # with anonymous .btf auto-discovery, and mines with RandomX (-gen). | ||
| 4 | # | ||
| 5 | # Deps are set up by ../build-linux.sh. Override paths on the make line if your | ||
| 6 | # secp256k1 / RandomX live elsewhere: | ||
| 7 | # make -f makefile.linux SECP_INC=... SECP_LIB=... RANDOMX_DIR=... | ||
| 8 | |||
| 9 | CXX ?= g++ | ||
| 10 | |||
| 11 | # secp256k1 (schnorrsig + extrakeys), installed by build-linux.sh | ||
| 12 | SECP_INC ?= /usr/local/include | ||
| 13 | SECP_LIB ?= /usr/local/lib | ||
| 14 | # RandomX source tree (headers in src/, static lib in build/) | ||
| 15 | RANDOMX_DIR ?= $(HOME)/RandomX | ||
| 16 | |||
| 17 | CXXFLAGS = -std=gnu++14 -O2 -w -fpermissive -pthread \ | ||
| 18 | -DSECP256K1_STATIC \ | ||
| 19 | -I$(SECP_INC) -I$(RANDOMX_DIR)/src | ||
| 20 | |||
| 21 | LIBS = -L$(SECP_LIB) -lsecp256k1 \ | ||
| 22 | -L$(RANDOMX_DIR)/build -lrandomx \ | ||
| 23 | -lsodium -lssl -lcrypto -ldb_cxx -lpthread | ||
| 24 | |||
| 25 | HEADERS = headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h \ | ||
| 26 | db.h base58.h net.h irc.h nostr.h randomx_pow.h btfaddr.h btfchan.h \ | ||
| 27 | btfrv.h btftunnel.h market.h compat.h | ||
| 28 | |||
| 29 | OBJS = obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \ | ||
| 30 | obj/sha.o obj/irc.o obj/nostr.o obj/randomx_pow.o \ | ||
| 31 | obj/btfaddr.o obj/btfchan.o obj/btfrv.o obj/btftunnel.o obj/headless.o | ||
| 32 | |||
| 33 | all: bitflash-node | ||
| 34 | |||
| 35 | obj/%.o: %.cpp $(HEADERS) | ||
| 36 | @mkdir -p obj | ||
| 37 | $(CXX) -c $(CXXFLAGS) -o $@ $< | ||
| 38 | |||
| 39 | # sha gets -O3 like the Windows makefile | ||
| 40 | obj/sha.o: sha.cpp sha.h | ||
| 41 | @mkdir -p obj | ||
| 42 | $(CXX) -c $(CXXFLAGS) -O3 -o $@ $< | ||
| 43 | |||
| 44 | bitflash-node: $(OBJS) | ||
| 45 | $(CXX) $(CXXFLAGS) -o $@ $(OBJS) $(LIBS) | ||
| 46 | |||
| 47 | clean: | ||
| 48 | rm -rf obj bitflash-node | ||
diff --git a/src/makefile.mingw b/src/makefile.mingw new file mode 100644 index 0000000..0ffac3f --- /dev/null +++ b/src/makefile.mingw | |||
| @@ -0,0 +1,44 @@ | |||
| 1 | # Bitflash -- build for MSYS2 UCRT64 (modern g++ + wxWidgets 3.2 + OpenSSL 3 + Berkeley DB 6) | ||
| 2 | # Based on Satoshi Nakamoto's original 2009 makefile (MIT/X11) | ||
| 3 | # Usage: (UCRT64 shell) mingw32-make -f makefile.mingw | ||
| 4 | |||
| 5 | CXX = g++ | ||
| 6 | WXCXXFLAGS := $(shell wx-config --cxxflags) | ||
| 7 | WXLIBS := $(shell wx-config --libs std,richtext,html) | ||
| 8 | WXRCFLAGS := $(filter -I%,$(shell wx-config --cxxflags)) $(filter -D%,$(shell wx-config --cxxflags)) | ||
| 9 | |||
| 10 | DEFS = -DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH | ||
| 11 | # Path to the project's built dependencies (libsecp256k1 with Schnorr, RandomX) | ||
| 12 | DEPS = ../deps | ||
| 13 | RANDOMX = ../RandomX | ||
| 14 | CXXFLAGS = -std=gnu++14 -O2 -w -fpermissive -Wno-deprecated-declarations -pthread $(DEFS) -I$(DEPS)/include -I$(RANDOMX)/src $(WXCXXFLAGS) | ||
| 15 | HEADERS = headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h net.h irc.h nostr.h randomx_pow.h btfaddr.h btfchan.h btfrv.h btftunnel.h market.h uibase.h ui.h | ||
| 16 | |||
| 17 | LIBS = \ | ||
| 18 | -ldb_cxx \ | ||
| 19 | -L$(DEPS)/lib -lsecp256k1 \ | ||
| 20 | -L$(RANDOMX)/build -lrandomx \ | ||
| 21 | -lsodium \ | ||
| 22 | -lssl -lcrypto \ | ||
| 23 | -lkernel32 -luser32 -lgdi32 -lcomdlg32 -lwinspool -lwinmm -lshell32 -lcomctl32 \ | ||
| 24 | -lole32 -loleaut32 -luuid -lrpcrt4 -ladvapi32 -lws2_32 -lmswsock -lcrypt32 -pthread | ||
| 25 | |||
| 26 | OBJS = obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \ | ||
| 27 | obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/nostr.o obj/randomx_pow.o obj/btfaddr.o obj/btfchan.o obj/btfrv.o obj/btftunnel.o obj/ui_res.o | ||
| 28 | |||
| 29 | all: bitflash.exe | ||
| 30 | |||
| 31 | obj/%.o: %.cpp $(HEADERS) | ||
| 32 | $(CXX) -c $(CXXFLAGS) -o $@ $< | ||
| 33 | |||
| 34 | obj/sha.o: sha.cpp sha.h | ||
| 35 | $(CXX) -c $(CXXFLAGS) -O3 -o $@ $< | ||
| 36 | |||
| 37 | obj/ui_res.o: ui.rc rc/bitcoin.ico rc/check.ico | ||
| 38 | windres $(DEFS) $(WXRCFLAGS) -o $@ -i $< | ||
| 39 | |||
| 40 | bitflash.exe: $(OBJS) | ||
| 41 | $(CXX) $(CXXFLAGS) -mwindows -Wl,--subsystem,windows -o $@ $(OBJS) $(WXLIBS) $(LIBS) | ||
| 42 | |||
| 43 | clean: | ||
| 44 | rm -f obj/*.o bitflash.exe | ||
diff --git a/src/makefile.vc b/src/makefile.vc new file mode 100644 index 0000000..60dca78 --- /dev/null +++ b/src/makefile.vc | |||
| @@ -0,0 +1,77 @@ | |||
| 1 | # Copyright (c) 2009 Satoshi Nakamoto | ||
| 2 | # Distributed under the MIT/X11 software license, see the accompanying | ||
| 3 | # file license.txt or http://www.opensource.org/licenses/mit-license.php. | ||
| 4 | |||
| 5 | |||
| 6 | !IF "$(BUILD)" != "debug" && "$(BUILD)" != "release" | ||
| 7 | BUILD=debug | ||
| 8 | !ENDIF | ||
| 9 | !IF "$(BUILD)" == "debug" | ||
| 10 | D=d | ||
| 11 | DEBUGFLAGS=/Zi /Od /D__WXDEBUG__ | ||
| 12 | !ENDIF | ||
| 13 | |||
| 14 | |||
| 15 | |||
| 16 | INCLUDEPATHS=/I"/boost" /I"/DB/build_windows" /I"/OpenSSL/include" /I"/wxWidgets/lib/vc_lib/mswd" /I"/wxWidgets/include" | ||
| 17 | LIBPATHS=/LIBPATH:"/DB/build_windows/$(BUILD)" /LIBPATH:"/OpenSSL/out" /LIBPATH:"/wxWidgets/lib/vc_lib" | ||
| 18 | LIBS= \ | ||
| 19 | libdb47s$(D).lib \ | ||
| 20 | libeay32.lib \ | ||
| 21 | wxmsw28$(D)_richtext.lib wxmsw28$(D)_html.lib wxmsw28$(D)_core.lib wxbase28$(D).lib wxtiff$(D).lib wxjpeg$(D).lib wxpng$(D).lib wxzlib$(D).lib wxregex$(D).lib wxexpat$(D).lib \ | ||
| 22 | kernel32.lib user32.lib gdi32.lib comdlg32.lib winspool.lib winmm.lib shell32.lib comctl32.lib ole32.lib oleaut32.lib uuid.lib rpcrt4.lib advapi32.lib ws2_32.lib | ||
| 23 | WXDEFS=/DWIN32 /D__WXMSW__ /D_WINDOWS /DNOPCH | ||
| 24 | CFLAGS=/c /nologo /Ob0 /MD$(D) /EHsc /GR /Zm300 /YX /Fpobj/headers.pch $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) | ||
| 25 | HEADERS=headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h | ||
| 26 | |||
| 27 | |||
| 28 | |||
| 29 | all: bitcoin.exe | ||
| 30 | |||
| 31 | |||
| 32 | obj\util.obj: util.cpp $(HEADERS) | ||
| 33 | cl $(CFLAGS) /Fo$@ %s | ||
| 34 | |||
| 35 | obj\script.obj: script.cpp $(HEADERS) | ||
| 36 | cl $(CFLAGS) /Fo$@ %s | ||
| 37 | |||
| 38 | obj\db.obj: db.cpp $(HEADERS) market.h | ||
| 39 | cl $(CFLAGS) /Fo$@ %s | ||
| 40 | |||
| 41 | obj\net.obj: net.cpp $(HEADERS) net.h | ||
| 42 | cl $(CFLAGS) /Fo$@ %s | ||
| 43 | |||
| 44 | obj\main.obj: main.cpp $(HEADERS) net.h market.h | ||
| 45 | cl $(CFLAGS) /Fo$@ %s | ||
| 46 | |||
| 47 | obj\market.obj: market.cpp $(HEADERS) market.h | ||
| 48 | cl $(CFLAGS) /Fo$@ %s | ||
| 49 | |||
| 50 | obj\ui.obj: ui.cpp $(HEADERS) net.h uibase.h ui.h market.h | ||
| 51 | cl $(CFLAGS) /Fo$@ %s | ||
| 52 | |||
| 53 | obj\uibase.obj: uibase.cpp uibase.h | ||
| 54 | cl $(CFLAGS) /Fo$@ %s | ||
| 55 | |||
| 56 | obj\sha.obj: sha.cpp sha.h | ||
| 57 | cl $(CFLAGS) /O2 /Fo$@ %s | ||
| 58 | |||
| 59 | obj\irc.obj: irc.cpp $(HEADERS) | ||
| 60 | cl $(CFLAGS) /Fo$@ %s | ||
| 61 | |||
| 62 | obj\ui.res: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp | ||
| 63 | rc $(INCLUDEPATHS) $(WXDEFS) /Fo$@ %s | ||
| 64 | |||
| 65 | |||
| 66 | |||
| 67 | OBJS=obj\util.obj obj\script.obj obj\db.obj obj\net.obj obj\main.obj obj\market.obj \ | ||
| 68 | obj\ui.obj obj\uibase.obj obj\sha.obj obj\irc.obj obj\ui.res | ||
| 69 | |||
| 70 | bitcoin.exe: $(OBJS) | ||
| 71 | -kill /f bitcoin.exe & sleep 1 | ||
| 72 | link /nologo /DEBUG /SUBSYSTEM:WINDOWS /OUT:$@ $(LIBPATHS) $** $(LIBS) | ||
| 73 | |||
| 74 | clean: | ||
| 75 | -del /Q obj\* | ||
| 76 | -del *.ilk | ||
| 77 | -del *.pdb | ||
diff --git a/src/market.cpp b/src/market.cpp new file mode 100644 index 0000000..e5d34f4 --- /dev/null +++ b/src/market.cpp | |||
| @@ -0,0 +1,264 @@ | |||
| 1 | // Copyright (c) 2009 Satoshi Nakamoto | ||
| 2 | // Distributed under the MIT/X11 software license, see the accompanying | ||
| 3 | // file license.txt or http://www.opensource.org/licenses/mit-license.php. | ||
| 4 | |||
| 5 | #include "headers.h" | ||
| 6 | |||
| 7 | |||
| 8 | |||
| 9 | |||
| 10 | |||
| 11 | |||
| 12 | |||
| 13 | |||
| 14 | |||
| 15 | |||
| 16 | // | ||
| 17 | // Global state variables | ||
| 18 | // | ||
| 19 | |||
| 20 | //// later figure out how these are persisted | ||
| 21 | map<uint256, CProduct> mapMyProducts; | ||
| 22 | |||
| 23 | |||
| 24 | |||
| 25 | |||
| 26 | map<uint256, CProduct> mapProducts; | ||
| 27 | CCriticalSection cs_mapProducts; | ||
| 28 | |||
| 29 | bool AdvertInsert(const CProduct& product) | ||
| 30 | { | ||
| 31 | uint256 hash = product.GetHash(); | ||
| 32 | bool fNew = false; | ||
| 33 | bool fUpdated = false; | ||
| 34 | |||
| 35 | CRITICAL_BLOCK(cs_mapProducts) | ||
| 36 | { | ||
| 37 | // Insert or find existing product | ||
| 38 | pair<map<uint256, CProduct>::iterator, bool> item = mapProducts.insert(make_pair(hash, product)); | ||
| 39 | CProduct* pproduct = &(*(item.first)).second; | ||
| 40 | fNew = item.second; | ||
| 41 | |||
| 42 | // Update if newer | ||
| 43 | if (product.nSequence > pproduct->nSequence) | ||
| 44 | { | ||
| 45 | *pproduct = product; | ||
| 46 | fUpdated = true; | ||
| 47 | } | ||
| 48 | } | ||
| 49 | |||
| 50 | //if (fNew) | ||
| 51 | // NotifyProductAdded(hash); | ||
| 52 | //else if (fUpdated) | ||
| 53 | // NotifyProductUpdated(hash); | ||
| 54 | |||
| 55 | return (fNew || fUpdated); | ||
| 56 | } | ||
| 57 | |||
| 58 | void AdvertErase(const CProduct& product) | ||
| 59 | { | ||
| 60 | uint256 hash = product.GetHash(); | ||
| 61 | CRITICAL_BLOCK(cs_mapProducts) | ||
| 62 | mapProducts.erase(hash); | ||
| 63 | //NotifyProductDeleted(hash); | ||
| 64 | } | ||
| 65 | |||
| 66 | |||
| 67 | |||
| 68 | |||
| 69 | |||
| 70 | |||
| 71 | |||
| 72 | |||
| 73 | |||
| 74 | |||
| 75 | |||
| 76 | |||
| 77 | |||
| 78 | |||
| 79 | |||
| 80 | |||
| 81 | |||
| 82 | |||
| 83 | |||
| 84 | template<typename T> | ||
| 85 | unsigned int Union(T& v1, T& v2) | ||
| 86 | { | ||
| 87 | // v1 = v1 union v2 | ||
| 88 | // v1 and v2 must be sorted | ||
| 89 | // returns the number of elements added to v1 | ||
| 90 | |||
| 91 | ///// need to check that this is equivalent, then delete this comment | ||
| 92 | //vector<unsigned short> vUnion(v1.size() + v2.size()); | ||
| 93 | //vUnion.erase(set_union(v1.begin(), v1.end(), | ||
| 94 | // v2.begin(), v2.end(), | ||
| 95 | // vUnion.begin()), | ||
| 96 | // vUnion.end()); | ||
| 97 | |||
| 98 | T vUnion; | ||
| 99 | vUnion.reserve(v1.size() + v2.size()); | ||
| 100 | set_union(v1.begin(), v1.end(), | ||
| 101 | v2.begin(), v2.end(), | ||
| 102 | back_inserter(vUnion)); | ||
| 103 | unsigned int nAdded = vUnion.size() - v1.size(); | ||
| 104 | if (nAdded > 0) | ||
| 105 | v1 = vUnion; | ||
| 106 | return nAdded; | ||
| 107 | } | ||
| 108 | |||
| 109 | void CUser::AddAtom(unsigned short nAtom, bool fOrigin) | ||
| 110 | { | ||
| 111 | // Ignore duplicates | ||
| 112 | if (binary_search(vAtomsIn.begin(), vAtomsIn.end(), nAtom) || | ||
| 113 | find(vAtomsNew.begin(), vAtomsNew.end(), nAtom) != vAtomsNew.end()) | ||
| 114 | return; | ||
| 115 | |||
| 116 | //// instead of zero atom, should change to free atom that propagates, | ||
| 117 | //// limited to lower than a certain value like 5 so conflicts quickly | ||
| 118 | // The zero atom never propagates, | ||
| 119 | // new atoms always propagate through the user that created them | ||
| 120 | if (nAtom == 0 || fOrigin) | ||
| 121 | { | ||
| 122 | vector<unsigned short> vTmp(1, nAtom); | ||
| 123 | Union(vAtomsIn, vTmp); | ||
| 124 | if (fOrigin) | ||
| 125 | vAtomsOut.push_back(nAtom); | ||
| 126 | return; | ||
| 127 | } | ||
| 128 | |||
| 129 | vAtomsNew.push_back(nAtom); | ||
| 130 | |||
| 131 | if (vAtomsNew.size() >= nFlowthroughRate || vAtomsOut.empty()) | ||
| 132 | { | ||
| 133 | // Select atom to flow through to vAtomsOut | ||
| 134 | vAtomsOut.push_back(vAtomsNew[GetRand(vAtomsNew.size())]); | ||
| 135 | |||
| 136 | // Merge vAtomsNew into vAtomsIn | ||
| 137 | sort(vAtomsNew.begin(), vAtomsNew.end()); | ||
| 138 | Union(vAtomsIn, vAtomsNew); | ||
| 139 | vAtomsNew.clear(); | ||
| 140 | } | ||
| 141 | } | ||
| 142 | |||
| 143 | bool AddAtomsAndPropagate(uint256 hashUserStart, const vector<unsigned short>& vAtoms, bool fOrigin) | ||
| 144 | { | ||
| 145 | CReviewDB reviewdb; | ||
| 146 | map<uint256, vector<unsigned short> > pmapPropagate[2]; | ||
| 147 | pmapPropagate[0][hashUserStart] = vAtoms; | ||
| 148 | |||
| 149 | for (int side = 0; !pmapPropagate[side].empty(); side = 1 - side) | ||
| 150 | { | ||
| 151 | map<uint256, vector<unsigned short> >& mapFrom = pmapPropagate[side]; | ||
| 152 | map<uint256, vector<unsigned short> >& mapTo = pmapPropagate[1 - side]; | ||
| 153 | |||
| 154 | for (map<uint256, vector<unsigned short> >::iterator mi = mapFrom.begin(); mi != mapFrom.end(); ++mi) | ||
| 155 | { | ||
| 156 | const uint256& hashUser = (*mi).first; | ||
| 157 | const vector<unsigned short>& vReceived = (*mi).second; | ||
| 158 | |||
| 159 | ///// this would be a lot easier on the database if it put the new atom at the beginning of the list, | ||
| 160 | ///// so the change would be right next to the vector size. | ||
| 161 | |||
| 162 | // Read user | ||
| 163 | CUser user; | ||
| 164 | reviewdb.ReadUser(hashUser, user); | ||
| 165 | unsigned int nIn = user.vAtomsIn.size(); | ||
| 166 | unsigned int nNew = user.vAtomsNew.size(); | ||
| 167 | unsigned int nOut = user.vAtomsOut.size(); | ||
| 168 | |||
| 169 | // Add atoms received | ||
| 170 | foreach(unsigned short nAtom, vReceived) | ||
| 171 | user.AddAtom(nAtom, fOrigin); | ||
| 172 | fOrigin = false; | ||
| 173 | |||
| 174 | // Don't bother writing to disk if no changes | ||
| 175 | if (user.vAtomsIn.size() == nIn && user.vAtomsNew.size() == nNew) | ||
| 176 | continue; | ||
| 177 | |||
| 178 | // Propagate | ||
| 179 | if (user.vAtomsOut.size() > nOut) | ||
| 180 | foreach(const uint256& hash, user.vLinksOut) | ||
| 181 | mapTo[hash].insert(mapTo[hash].end(), user.vAtomsOut.begin() + nOut, user.vAtomsOut.end()); | ||
| 182 | |||
| 183 | // Write back | ||
| 184 | if (!reviewdb.WriteUser(hashUser, user)) | ||
| 185 | return false; | ||
| 186 | } | ||
| 187 | mapFrom.clear(); | ||
| 188 | } | ||
| 189 | return true; | ||
| 190 | } | ||
| 191 | |||
| 192 | |||
| 193 | |||
| 194 | |||
| 195 | |||
| 196 | |||
| 197 | bool CReview::AcceptReview() | ||
| 198 | { | ||
| 199 | // Timestamp | ||
| 200 | nTime = GetTime(); | ||
| 201 | |||
| 202 | // Check signature | ||
| 203 | if (!CKey::Verify(vchPubKeyFrom, GetSigHash(), vchSig)) | ||
| 204 | return false; | ||
| 205 | |||
| 206 | CReviewDB reviewdb; | ||
| 207 | |||
| 208 | // Add review text to recipient | ||
| 209 | vector<CReview> vReviews; | ||
| 210 | reviewdb.ReadReviews(hashTo, vReviews); | ||
| 211 | vReviews.push_back(*this); | ||
| 212 | if (!reviewdb.WriteReviews(hashTo, vReviews)) | ||
| 213 | return false; | ||
| 214 | |||
| 215 | // Add link from sender | ||
| 216 | CUser user; | ||
| 217 | uint256 hashFrom = Hash(vchPubKeyFrom.begin(), vchPubKeyFrom.end()); | ||
| 218 | reviewdb.ReadUser(hashFrom, user); | ||
| 219 | user.vLinksOut.push_back(hashTo); | ||
| 220 | if (!reviewdb.WriteUser(hashFrom, user)) | ||
| 221 | return false; | ||
| 222 | |||
| 223 | reviewdb.Close(); | ||
| 224 | |||
| 225 | // Propagate atoms to recipient | ||
| 226 | vector<unsigned short> vZeroAtom(1, 0); | ||
| 227 | if (!AddAtomsAndPropagate(hashTo, user.vAtomsOut.size() ? user.vAtomsOut : vZeroAtom, false)) | ||
| 228 | return false; | ||
| 229 | |||
| 230 | return true; | ||
| 231 | } | ||
| 232 | |||
| 233 | |||
| 234 | |||
| 235 | |||
| 236 | |||
| 237 | bool CProduct::CheckSignature() | ||
| 238 | { | ||
| 239 | return (CKey::Verify(vchPubKeyFrom, GetSigHash(), vchSig)); | ||
| 240 | } | ||
| 241 | |||
| 242 | bool CProduct::CheckProduct() | ||
| 243 | { | ||
| 244 | if (!CheckSignature()) | ||
| 245 | return false; | ||
| 246 | |||
| 247 | // Make sure it's a summary product | ||
| 248 | if (!mapDetails.empty() || !vOrderForm.empty()) | ||
| 249 | return false; | ||
| 250 | |||
| 251 | // Look up seller's atom count | ||
| 252 | CReviewDB reviewdb("r"); | ||
| 253 | CUser user; | ||
| 254 | reviewdb.ReadUser(GetUserHash(), user); | ||
| 255 | nAtoms = user.GetAtomCount(); | ||
| 256 | reviewdb.Close(); | ||
| 257 | |||
| 258 | ////// delme, this is now done by AdvertInsert | ||
| 259 | //// Store to memory | ||
| 260 | //CRITICAL_BLOCK(cs_mapProducts) | ||
| 261 | // mapProducts[GetHash()] = *this; | ||
| 262 | |||
| 263 | return true; | ||
| 264 | } | ||
diff --git a/src/market.h b/src/market.h new file mode 100644 index 0000000..b5c8b3b --- /dev/null +++ b/src/market.h | |||
| @@ -0,0 +1,182 @@ | |||
| 1 | // Copyright (c) 2009 Satoshi Nakamoto | ||
| 2 | // Distributed under the MIT/X11 software license, see the accompanying | ||
| 3 | // file license.txt or http://www.opensource.org/licenses/mit-license.php. | ||
| 4 | |||
| 5 | class CUser; | ||
| 6 | class CReview; | ||
| 7 | class CProduct; | ||
| 8 | |||
| 9 | static const unsigned int nFlowthroughRate = 2; | ||
| 10 | |||
| 11 | |||
| 12 | |||
| 13 | |||
| 14 | bool AdvertInsert(const CProduct& product); | ||
| 15 | void AdvertErase(const CProduct& product); | ||
| 16 | bool AddAtomsAndPropagate(uint256 hashUserStart, const vector<unsigned short>& vAtoms, bool fOrigin); | ||
| 17 | |||
| 18 | |||
| 19 | |||
| 20 | |||
| 21 | |||
| 22 | |||
| 23 | |||
| 24 | |||
| 25 | class CUser | ||
| 26 | { | ||
| 27 | public: | ||
| 28 | vector<unsigned short> vAtomsIn; | ||
| 29 | vector<unsigned short> vAtomsNew; | ||
| 30 | vector<unsigned short> vAtomsOut; | ||
| 31 | vector<uint256> vLinksOut; | ||
| 32 | |||
| 33 | CUser() | ||
| 34 | { | ||
| 35 | } | ||
| 36 | |||
| 37 | IMPLEMENT_SERIALIZE | ||
| 38 | ( | ||
| 39 | if (!(nType & SER_GETHASH)) | ||
| 40 | READWRITE(nVersion); | ||
| 41 | READWRITE(vAtomsIn); | ||
| 42 | READWRITE(vAtomsNew); | ||
| 43 | READWRITE(vAtomsOut); | ||
| 44 | READWRITE(vLinksOut); | ||
| 45 | ) | ||
| 46 | |||
| 47 | void SetNull() | ||
| 48 | { | ||
| 49 | vAtomsIn.clear(); | ||
| 50 | vAtomsNew.clear(); | ||
| 51 | vAtomsOut.clear(); | ||
| 52 | vLinksOut.clear(); | ||
| 53 | } | ||
| 54 | |||
| 55 | uint256 GetHash() const { return SerializeHash(*this); } | ||
| 56 | |||
| 57 | |||
| 58 | int GetAtomCount() const | ||
| 59 | { | ||
| 60 | return (vAtomsIn.size() + vAtomsNew.size()); | ||
| 61 | } | ||
| 62 | |||
| 63 | void AddAtom(unsigned short nAtom, bool fOrigin); | ||
| 64 | }; | ||
| 65 | |||
| 66 | |||
| 67 | |||
| 68 | |||
| 69 | |||
| 70 | |||
| 71 | |||
| 72 | class CReview | ||
| 73 | { | ||
| 74 | public: | ||
| 75 | int nVersion; | ||
| 76 | uint256 hashTo; | ||
| 77 | map<string, string> mapValue; | ||
| 78 | vector<unsigned char> vchPubKeyFrom; | ||
| 79 | vector<unsigned char> vchSig; | ||
| 80 | |||
| 81 | // memory only | ||
| 82 | unsigned int nTime; | ||
| 83 | int nAtoms; | ||
| 84 | |||
| 85 | |||
| 86 | CReview() | ||
| 87 | { | ||
| 88 | nVersion = 1; | ||
| 89 | hashTo = 0; | ||
| 90 | nTime = 0; | ||
| 91 | nAtoms = 0; | ||
| 92 | } | ||
| 93 | |||
| 94 | IMPLEMENT_SERIALIZE | ||
| 95 | ( | ||
| 96 | READWRITE(this->nVersion); | ||
| 97 | nVersion = this->nVersion; | ||
| 98 | if (!(nType & SER_DISK)) | ||
| 99 | READWRITE(hashTo); | ||
| 100 | READWRITE(mapValue); | ||
| 101 | READWRITE(vchPubKeyFrom); | ||
| 102 | if (!(nType & SER_GETHASH)) | ||
| 103 | READWRITE(vchSig); | ||
| 104 | ) | ||
| 105 | |||
| 106 | uint256 GetHash() const { return SerializeHash(*this); } | ||
| 107 | uint256 GetSigHash() const { return SerializeHash(*this, SER_GETHASH|SER_SKIPSIG); } | ||
| 108 | uint256 GetUserHash() const { return Hash(vchPubKeyFrom.begin(), vchPubKeyFrom.end()); } | ||
| 109 | |||
| 110 | |||
| 111 | bool AcceptReview(); | ||
| 112 | }; | ||
| 113 | |||
| 114 | |||
| 115 | |||
| 116 | |||
| 117 | |||
| 118 | |||
| 119 | |||
| 120 | class CProduct | ||
| 121 | { | ||
| 122 | public: | ||
| 123 | int nVersion; | ||
| 124 | CAddress addr; | ||
| 125 | map<string, string> mapValue; | ||
| 126 | map<string, string> mapDetails; | ||
| 127 | vector<pair<string, string> > vOrderForm; | ||
| 128 | unsigned int nSequence; | ||
| 129 | vector<unsigned char> vchPubKeyFrom; | ||
| 130 | vector<unsigned char> vchSig; | ||
| 131 | |||
| 132 | // disk only | ||
| 133 | int nAtoms; | ||
| 134 | |||
| 135 | // memory only | ||
| 136 | set<unsigned int> setSources; | ||
| 137 | |||
| 138 | CProduct() | ||
| 139 | { | ||
| 140 | nVersion = 1; | ||
| 141 | nAtoms = 0; | ||
| 142 | nSequence = 0; | ||
| 143 | } | ||
| 144 | |||
| 145 | IMPLEMENT_SERIALIZE | ||
| 146 | ( | ||
| 147 | READWRITE(this->nVersion); | ||
| 148 | nVersion = this->nVersion; | ||
| 149 | READWRITE(addr); | ||
| 150 | READWRITE(mapValue); | ||
| 151 | if (!(nType & SER_GETHASH)) | ||
| 152 | { | ||
| 153 | READWRITE(mapDetails); | ||
| 154 | READWRITE(vOrderForm); | ||
| 155 | READWRITE(nSequence); | ||
| 156 | } | ||
| 157 | READWRITE(vchPubKeyFrom); | ||
| 158 | if (!(nType & SER_GETHASH)) | ||
| 159 | READWRITE(vchSig); | ||
| 160 | if (nType & SER_DISK) | ||
| 161 | READWRITE(nAtoms); | ||
| 162 | ) | ||
| 163 | |||
| 164 | uint256 GetHash() const { return SerializeHash(*this); } | ||
| 165 | uint256 GetSigHash() const { return SerializeHash(*this, SER_GETHASH|SER_SKIPSIG); } | ||
| 166 | uint256 GetUserHash() const { return Hash(vchPubKeyFrom.begin(), vchPubKeyFrom.end()); } | ||
| 167 | |||
| 168 | |||
| 169 | bool CheckSignature(); | ||
| 170 | bool CheckProduct(); | ||
| 171 | }; | ||
| 172 | |||
| 173 | |||
| 174 | |||
| 175 | |||
| 176 | |||
| 177 | |||
| 178 | |||
| 179 | |||
| 180 | extern map<uint256, CProduct> mapProducts; | ||
| 181 | extern CCriticalSection cs_mapProducts; | ||
| 182 | extern map<uint256, CProduct> mapMyProducts; | ||
diff --git a/src/net.cpp b/src/net.cpp new file mode 100644 index 0000000..8ab9ccc --- /dev/null +++ b/src/net.cpp | |||
| @@ -0,0 +1,1207 @@ | |||
| 1 | // Copyright (c) 2009 Satoshi Nakamoto | ||
| 2 | // Distributed under the MIT/X11 software license, see the accompanying | ||
| 3 | // file license.txt or http://www.opensource.org/licenses/mit-license.php. | ||
| 4 | |||
| 5 | #include "headers.h" | ||
| 6 | #ifdef _WIN32 | ||
| 7 | #include <winsock2.h> | ||
| 8 | #endif | ||
| 9 | #include <openssl/rand.h> | ||
| 10 | #include "btfaddr.h" | ||
| 11 | #include "btftunnel.h" | ||
| 12 | |||
| 13 | void ThreadMessageHandler2(void* parg); | ||
| 14 | void ThreadSocketHandler2(void* parg); | ||
| 15 | void ThreadOpenConnections2(void* parg); | ||
| 16 | |||
| 17 | |||
| 18 | |||
| 19 | |||
| 20 | |||
| 21 | |||
| 22 | // | ||
| 23 | // Global state variables | ||
| 24 | // | ||
| 25 | bool fClient = false; | ||
| 26 | uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK); | ||
| 27 | CAddress addrLocalHost(0, DEFAULT_PORT, nLocalServices); | ||
| 28 | unsigned short nListenPort = DEFAULT_PORT; // local P2P port (tunable via /port) | ||
| 29 | CNode nodeLocalHost(INVALID_SOCKET, CAddress("127.0.0.1", nLocalServices)); | ||
| 30 | CNode* pnodeLocalHost = &nodeLocalHost; | ||
| 31 | bool fShutdown = false; | ||
| 32 | array<bool, 10> vfThreadRunning; | ||
| 33 | vector<CNode*> vNodes; | ||
| 34 | CCriticalSection cs_vNodes; | ||
| 35 | map<vector<unsigned char>, CAddress> mapAddresses; | ||
| 36 | CCriticalSection cs_mapAddresses; | ||
| 37 | map<CInv, CDataStream> mapRelay; | ||
| 38 | deque<pair<int64, CInv> > vRelayExpiration; | ||
| 39 | CCriticalSection cs_mapRelay; | ||
| 40 | map<CInv, int64> mapAlreadyAskedFor; | ||
| 41 | string strBtfConnect; // .btf peer to keep connected to (from /connectbtf) | ||
| 42 | |||
| 43 | |||
| 44 | |||
| 45 | CAddress addrProxy; | ||
| 46 | |||
| 47 | bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet) | ||
| 48 | { | ||
| 49 | hSocketRet = INVALID_SOCKET; | ||
| 50 | |||
| 51 | SOCKET hSocket = socket(AF_INET, SOCK_STREAM, 0); | ||
| 52 | if (hSocket == INVALID_SOCKET) | ||
| 53 | return false; | ||
| 54 | |||
| 55 | bool fRoutable = !(addrConnect.GetByte(3) == 10 || (addrConnect.GetByte(3) == 192 && addrConnect.GetByte(2) == 168)); | ||
| 56 | bool fProxy = (addrProxy.ip && fRoutable); | ||
| 57 | struct sockaddr_in sockaddr = (fProxy ? addrProxy.GetSockAddr() : addrConnect.GetSockAddr()); | ||
| 58 | |||
| 59 | if (connect(hSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR) | ||
| 60 | { | ||
| 61 | closesocket(hSocket); | ||
| 62 | return false; | ||
| 63 | } | ||
| 64 | |||
| 65 | if (fProxy) | ||
| 66 | { | ||
| 67 | printf("Proxy connecting to %s\n", addrConnect.ToString().c_str()); | ||
| 68 | char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user"; | ||
| 69 | memcpy(pszSocks4IP + 2, &addrConnect.port, 2); | ||
| 70 | memcpy(pszSocks4IP + 4, &addrConnect.ip, 4); | ||
| 71 | char* pszSocks4 = pszSocks4IP; | ||
| 72 | int nSize = sizeof(pszSocks4IP); | ||
| 73 | |||
| 74 | int ret = send(hSocket, pszSocks4, nSize, 0); | ||
| 75 | if (ret != nSize) | ||
| 76 | { | ||
| 77 | closesocket(hSocket); | ||
| 78 | return error("Error sending to proxy\n"); | ||
| 79 | } | ||
| 80 | char pchRet[8]; | ||
| 81 | if (recv(hSocket, pchRet, 8, 0) != 8) | ||
| 82 | { | ||
| 83 | closesocket(hSocket); | ||
| 84 | return error("Error reading proxy response\n"); | ||
| 85 | } | ||
| 86 | if (pchRet[1] != 0x5a) | ||
| 87 | { | ||
| 88 | closesocket(hSocket); | ||
| 89 | return error("Proxy returned error %d\n", pchRet[1]); | ||
| 90 | } | ||
| 91 | printf("Proxy connection established %s\n", addrConnect.ToString().c_str()); | ||
| 92 | } | ||
| 93 | |||
| 94 | hSocketRet = hSocket; | ||
| 95 | return true; | ||
| 96 | } | ||
| 97 | |||
| 98 | |||
| 99 | bool GetMyExternalIP(unsigned int& ipRet) | ||
| 100 | { | ||
| 101 | // The 2009 whatismyip.com service (fixed IP) no longer exists; this avoids | ||
| 102 | // stalling startup on TCP timeouts. The external IP may come from Nostr | ||
| 103 | // relays in the future. | ||
| 104 | return false; | ||
| 105 | |||
| 106 | CAddress addrConnect("72.233.89.199:80"); // whatismyip.com 198-200 | ||
| 107 | |||
| 108 | SOCKET hSocket; | ||
| 109 | if (!ConnectSocket(addrConnect, hSocket)) | ||
| 110 | return error("GetMyExternalIP() : connection to %s failed\n", addrConnect.ToString().c_str()); | ||
| 111 | |||
| 112 | char* pszGet = | ||
| 113 | "GET /automation/n09230945.asp HTTP/1.1\r\n" | ||
| 114 | "Host: www.whatismyip.com\r\n" | ||
| 115 | "User-Agent: Bitcoin/0.1\r\n" | ||
| 116 | "Connection: close\r\n" | ||
| 117 | "\r\n"; | ||
| 118 | send(hSocket, pszGet, strlen(pszGet), 0); | ||
| 119 | |||
| 120 | string strLine; | ||
| 121 | while (RecvLine(hSocket, strLine)) | ||
| 122 | { | ||
| 123 | if (strLine.empty()) | ||
| 124 | { | ||
| 125 | if (!RecvLine(hSocket, strLine)) | ||
| 126 | { | ||
| 127 | closesocket(hSocket); | ||
| 128 | return false; | ||
| 129 | } | ||
| 130 | closesocket(hSocket); | ||
| 131 | CAddress addr(strLine.c_str()); | ||
| 132 | printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str()); | ||
| 133 | if (addr.ip == 0) | ||
| 134 | return false; | ||
| 135 | ipRet = addr.ip; | ||
| 136 | return true; | ||
| 137 | } | ||
| 138 | } | ||
| 139 | closesocket(hSocket); | ||
| 140 | return error("GetMyExternalIP() : connection closed\n"); | ||
| 141 | } | ||
| 142 | |||
| 143 | |||
| 144 | |||
| 145 | |||
| 146 | |||
| 147 | |||
| 148 | bool AddAddress(CAddrDB& addrdb, const CAddress& addr) | ||
| 149 | { | ||
| 150 | if (!addr.IsRoutable()) | ||
| 151 | return false; | ||
| 152 | if (addr.ip == addrLocalHost.ip) | ||
| 153 | return false; | ||
| 154 | CRITICAL_BLOCK(cs_mapAddresses) | ||
| 155 | { | ||
| 156 | map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey()); | ||
| 157 | if (it == mapAddresses.end()) | ||
| 158 | { | ||
| 159 | // New address | ||
| 160 | mapAddresses.insert(make_pair(addr.GetKey(), addr)); | ||
| 161 | addrdb.WriteAddress(addr); | ||
| 162 | return true; | ||
| 163 | } | ||
| 164 | else | ||
| 165 | { | ||
| 166 | CAddress& addrFound = (*it).second; | ||
| 167 | if ((addrFound.nServices | addr.nServices) != addrFound.nServices) | ||
| 168 | { | ||
| 169 | // Services have been added | ||
| 170 | addrFound.nServices |= addr.nServices; | ||
| 171 | addrdb.WriteAddress(addrFound); | ||
| 172 | return true; | ||
| 173 | } | ||
| 174 | } | ||
| 175 | } | ||
| 176 | return false; | ||
| 177 | } | ||
| 178 | |||
| 179 | |||
| 180 | |||
| 181 | |||
| 182 | |||
| 183 | void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1) | ||
| 184 | { | ||
| 185 | // If the dialog might get closed before the reply comes back, | ||
| 186 | // call this in the destructor so it doesn't get called after it's deleted. | ||
| 187 | CRITICAL_BLOCK(cs_vNodes) | ||
| 188 | { | ||
| 189 | foreach(CNode* pnode, vNodes) | ||
| 190 | { | ||
| 191 | CRITICAL_BLOCK(pnode->cs_mapRequests) | ||
| 192 | { | ||
| 193 | for (map<uint256, CRequestTracker>::iterator mi = pnode->mapRequests.begin(); mi != pnode->mapRequests.end();) | ||
| 194 | { | ||
| 195 | CRequestTracker& tracker = (*mi).second; | ||
| 196 | if (tracker.fn == fn && tracker.param1 == param1) | ||
| 197 | pnode->mapRequests.erase(mi++); | ||
| 198 | else | ||
| 199 | mi++; | ||
| 200 | } | ||
| 201 | } | ||
| 202 | } | ||
| 203 | } | ||
| 204 | } | ||
| 205 | |||
| 206 | |||
| 207 | |||
| 208 | |||
| 209 | |||
| 210 | |||
| 211 | |||
| 212 | // | ||
| 213 | // Subscription methods for the broadcast and subscription system. | ||
| 214 | // Channel numbers are message numbers, i.e. MSG_TABLE and MSG_PRODUCT. | ||
| 215 | // | ||
| 216 | // The subscription system uses a meet-in-the-middle strategy. | ||
| 217 | // With 100,000 nodes, if senders broadcast to 1000 random nodes and receivers | ||
| 218 | // subscribe to 1000 random nodes, 99.995% (1 - 0.99^1000) of messages will get through. | ||
| 219 | // | ||
| 220 | |||
| 221 | bool AnySubscribed(unsigned int nChannel) | ||
| 222 | { | ||
| 223 | if (pnodeLocalHost->IsSubscribed(nChannel)) | ||
| 224 | return true; | ||
| 225 | CRITICAL_BLOCK(cs_vNodes) | ||
| 226 | foreach(CNode* pnode, vNodes) | ||
| 227 | if (pnode->IsSubscribed(nChannel)) | ||
| 228 | return true; | ||
| 229 | return false; | ||
| 230 | } | ||
| 231 | |||
| 232 | bool CNode::IsSubscribed(unsigned int nChannel) | ||
| 233 | { | ||
| 234 | if (nChannel >= vfSubscribe.size()) | ||
| 235 | return false; | ||
| 236 | return vfSubscribe[nChannel]; | ||
| 237 | } | ||
| 238 | |||
| 239 | void CNode::Subscribe(unsigned int nChannel, unsigned int nHops) | ||
| 240 | { | ||
| 241 | if (nChannel >= vfSubscribe.size()) | ||
| 242 | return; | ||
| 243 | |||
| 244 | if (!AnySubscribed(nChannel)) | ||
| 245 | { | ||
| 246 | // Relay subscribe | ||
| 247 | CRITICAL_BLOCK(cs_vNodes) | ||
| 248 | foreach(CNode* pnode, vNodes) | ||
| 249 | if (pnode != this) | ||
| 250 | pnode->PushMessage("subscribe", nChannel, nHops); | ||
| 251 | } | ||
| 252 | |||
| 253 | vfSubscribe[nChannel] = true; | ||
| 254 | } | ||
| 255 | |||
| 256 | void CNode::CancelSubscribe(unsigned int nChannel) | ||
| 257 | { | ||
| 258 | if (nChannel >= vfSubscribe.size()) | ||
| 259 | return; | ||
| 260 | |||
| 261 | // Prevent from relaying cancel if wasn't subscribed | ||
| 262 | if (!vfSubscribe[nChannel]) | ||
| 263 | return; | ||
| 264 | vfSubscribe[nChannel] = false; | ||
| 265 | |||
| 266 | if (!AnySubscribed(nChannel)) | ||
| 267 | { | ||
| 268 | // Relay subscription cancel | ||
| 269 | CRITICAL_BLOCK(cs_vNodes) | ||
| 270 | foreach(CNode* pnode, vNodes) | ||
| 271 | if (pnode != this) | ||
| 272 | pnode->PushMessage("sub-cancel", nChannel); | ||
| 273 | |||
| 274 | // Clear memory, no longer subscribed | ||
| 275 | if (nChannel == MSG_PRODUCT) | ||
| 276 | CRITICAL_BLOCK(cs_mapProducts) | ||
| 277 | mapProducts.clear(); | ||
| 278 | } | ||
| 279 | } | ||
| 280 | |||
| 281 | |||
| 282 | |||
| 283 | |||
| 284 | |||
| 285 | |||
| 286 | |||
| 287 | |||
| 288 | |||
| 289 | CNode* FindNode(unsigned int ip) | ||
| 290 | { | ||
| 291 | CRITICAL_BLOCK(cs_vNodes) | ||
| 292 | { | ||
| 293 | foreach(CNode* pnode, vNodes) | ||
| 294 | if (pnode->addr.ip == ip) | ||
| 295 | return (pnode); | ||
| 296 | } | ||
| 297 | return NULL; | ||
| 298 | } | ||
| 299 | |||
| 300 | CNode* FindNode(CAddress addr) | ||
| 301 | { | ||
| 302 | CRITICAL_BLOCK(cs_vNodes) | ||
| 303 | { | ||
| 304 | foreach(CNode* pnode, vNodes) | ||
| 305 | if (pnode->addr == addr) | ||
| 306 | return (pnode); | ||
| 307 | } | ||
| 308 | return NULL; | ||
| 309 | } | ||
| 310 | |||
| 311 | CNode* ConnectNode(CAddress addrConnect, int64 nTimeout) | ||
| 312 | { | ||
| 313 | if (addrConnect.ip == addrLocalHost.ip) | ||
| 314 | return NULL; | ||
| 315 | |||
| 316 | // Look for an existing connection | ||
| 317 | CNode* pnode = FindNode(addrConnect.ip); | ||
| 318 | if (pnode) | ||
| 319 | { | ||
| 320 | if (nTimeout != 0) | ||
| 321 | pnode->AddRef(nTimeout); | ||
| 322 | else | ||
| 323 | pnode->AddRef(); | ||
| 324 | return pnode; | ||
| 325 | } | ||
| 326 | |||
| 327 | /// debug print | ||
| 328 | printf("trying %s\n", addrConnect.ToString().c_str()); | ||
| 329 | |||
| 330 | // Connect | ||
| 331 | SOCKET hSocket; | ||
| 332 | if (ConnectSocket(addrConnect, hSocket)) | ||
| 333 | { | ||
| 334 | /// debug print | ||
| 335 | printf("connected %s\n", addrConnect.ToString().c_str()); | ||
| 336 | |||
| 337 | // Add node | ||
| 338 | CNode* pnode = new CNode(hSocket, addrConnect, false); | ||
| 339 | if (nTimeout != 0) | ||
| 340 | pnode->AddRef(nTimeout); | ||
| 341 | else | ||
| 342 | pnode->AddRef(); | ||
| 343 | CRITICAL_BLOCK(cs_vNodes) | ||
| 344 | vNodes.push_back(pnode); | ||
| 345 | |||
| 346 | CRITICAL_BLOCK(cs_mapAddresses) | ||
| 347 | mapAddresses[addrConnect.GetKey()].nLastFailed = 0; | ||
| 348 | return pnode; | ||
| 349 | } | ||
| 350 | else | ||
| 351 | { | ||
| 352 | CRITICAL_BLOCK(cs_mapAddresses) | ||
| 353 | mapAddresses[addrConnect.GetKey()].nLastFailed = GetTime(); | ||
| 354 | return NULL; | ||
| 355 | } | ||
| 356 | } | ||
| 357 | |||
| 358 | // Synthetic marker address for a tunneled `.btf` peer. The real endpoint is | ||
| 359 | // unknown by design (the tunnel hides it), so tag the CNode with a non-routable | ||
| 360 | // 10.x.x.x address (fails IsRoutable, so it is never gossiped as a real peer) | ||
| 361 | // that is stable per identity, keeping FindNode and the duplicate check working. | ||
| 362 | static CAddress BtfMarkerAddr(const unsigned char b5[5]) | ||
| 363 | { | ||
| 364 | unsigned int ip; | ||
| 365 | unsigned char b[4] = { 10, b5[0], b5[1], b5[2] }; | ||
| 366 | memcpy(&ip, b, 4); | ||
| 367 | unsigned short port = htons((unsigned short)((b5[3] << 8) | b5[4])); | ||
| 368 | return CAddress(ip, port, nLocalServices); | ||
| 369 | } | ||
| 370 | |||
| 371 | // Connect to a peer by its `.btf` address: resolve the self-certified | ||
| 372 | // descriptor over Nostr, then tunnel through its meeting node with the | ||
| 373 | // end-to-end channel. Neither side ever learns the other's IP. | ||
| 374 | CNode* ConnectNodeBtf(const string& strBtfAddr) | ||
| 375 | { | ||
| 376 | unsigned char pk[32]; | ||
| 377 | if (!btf::ParseAddress(strBtfAddr, pk)) | ||
| 378 | { | ||
| 379 | printf("ConnectNodeBtf: invalid address %s\n", strBtfAddr.c_str()); | ||
| 380 | return NULL; | ||
| 381 | } | ||
| 382 | if (BtfLocalAddress() == strBtfAddr) | ||
| 383 | return NULL; // ourselves | ||
| 384 | |||
| 385 | CAddress addr = BtfMarkerAddr(pk); | ||
| 386 | CNode* pnode = FindNode(addr.ip); | ||
| 387 | if (pnode) | ||
| 388 | { | ||
| 389 | pnode->AddRef(); | ||
| 390 | return pnode; | ||
| 391 | } | ||
| 392 | |||
| 393 | /// debug print | ||
| 394 | printf("trying %s\n", strBtfAddr.c_str()); | ||
| 395 | |||
| 396 | string strMeeting; | ||
| 397 | unsigned char enc_pub[32]; | ||
| 398 | if (!BtfResolve(strBtfAddr, strMeeting, enc_pub)) | ||
| 399 | { | ||
| 400 | printf("ConnectNodeBtf: could not resolve a descriptor for %s\n", strBtfAddr.c_str()); | ||
| 401 | return NULL; | ||
| 402 | } | ||
| 403 | size_t colon = strMeeting.rfind(':'); | ||
| 404 | if (colon == string::npos) | ||
| 405 | return NULL; | ||
| 406 | string strHost = strMeeting.substr(0, colon); | ||
| 407 | int nPort = atoi(strMeeting.substr(colon + 1).c_str()); | ||
| 408 | if (nPort <= 0 || nPort > 65535) | ||
| 409 | return NULL; | ||
| 410 | |||
| 411 | btf_socket_t hSocket = btf::BtfClientTunnel(strHost.c_str(), (unsigned short)nPort, pk, enc_pub); | ||
| 412 | if (hSocket == INVALID_SOCKET) | ||
| 413 | { | ||
| 414 | printf("ConnectNodeBtf: tunnel to %s via %s failed\n", strBtfAddr.c_str(), strMeeting.c_str()); | ||
| 415 | return NULL; | ||
| 416 | } | ||
| 417 | |||
| 418 | /// debug print | ||
| 419 | printf("connected %s via rendezvous %s\n", strBtfAddr.c_str(), strMeeting.c_str()); | ||
| 420 | |||
| 421 | // Add node | ||
| 422 | pnode = new CNode(hSocket, addr, false); | ||
| 423 | pnode->AddRef(); | ||
| 424 | CRITICAL_BLOCK(cs_vNodes) | ||
| 425 | vNodes.push_back(pnode); | ||
| 426 | return pnode; | ||
| 427 | } | ||
| 428 | |||
| 429 | // Anonymous inbound listener (this node's `.btf` hidden service). Registers at | ||
| 430 | // the meeting relay and blocks until a client dials our address; each pairing | ||
| 431 | // becomes a normal inbound CNode riding the end-to-end channel, then we | ||
| 432 | // register again for the next caller. | ||
| 433 | void ThreadBtfAccept(void* parg) | ||
| 434 | { | ||
| 435 | printf("ThreadBtfAccept started\n"); | ||
| 436 | unsigned char pk[32]; | ||
| 437 | unsigned char sk[32]; | ||
| 438 | while (!BtfGetIdentity(pk, sk)) | ||
| 439 | { | ||
| 440 | if (fShutdown) | ||
| 441 | return; | ||
| 442 | Sleep(5000); | ||
| 443 | } | ||
| 444 | loop | ||
| 445 | { | ||
| 446 | if (fShutdown) | ||
| 447 | return; | ||
| 448 | string strMeeting = strBtfMeetingRelay; | ||
| 449 | size_t colon = strMeeting.rfind(':'); | ||
| 450 | if (colon == string::npos) | ||
| 451 | { | ||
| 452 | Sleep(10000); // no meeting relay configured | ||
| 453 | continue; | ||
| 454 | } | ||
| 455 | string strHost = strMeeting.substr(0, colon); | ||
| 456 | int nPort = atoi(strMeeting.substr(colon + 1).c_str()); | ||
| 457 | |||
| 458 | // Blocks until a client is paired to us (or the relay drops us) | ||
| 459 | btf::RvSocket rv = btf::RvServiceRegister(strHost.c_str(), (unsigned short)nPort, pk); | ||
| 460 | if (fShutdown) | ||
| 461 | { | ||
| 462 | if (rv != btf::RV_INVALID) | ||
| 463 | btf::RvClose(rv); | ||
| 464 | return; | ||
| 465 | } | ||
| 466 | if (rv == btf::RV_INVALID) | ||
| 467 | { | ||
| 468 | Sleep(10000); // relay unreachable; retry | ||
| 469 | continue; | ||
| 470 | } | ||
| 471 | btf_socket_t hSocket = btf::BtfServiceWrap(rv, sk); | ||
| 472 | if (hSocket == INVALID_SOCKET) | ||
| 473 | continue; | ||
| 474 | |||
| 475 | // The dialer is anonymous (its pubkey never reaches us), so tag the | ||
| 476 | // connection with a random marker address. | ||
| 477 | unsigned char rnd[5]; | ||
| 478 | RAND_bytes(rnd, sizeof(rnd)); | ||
| 479 | CAddress addr = BtfMarkerAddr(rnd); | ||
| 480 | |||
| 481 | printf("accepted .btf connection via rendezvous %s\n", strMeeting.c_str()); | ||
| 482 | CNode* pnode = new CNode(hSocket, addr, true); | ||
| 483 | pnode->AddRef(); | ||
| 484 | CRITICAL_BLOCK(cs_vNodes) | ||
| 485 | vNodes.push_back(pnode); | ||
| 486 | } | ||
| 487 | } | ||
| 488 | |||
| 489 | // Keep an outbound connection to a specific `.btf` peer (from /connectbtf) -- | ||
| 490 | // the rendezvous analogue of addnode. Retries until connected, reconnects if | ||
| 491 | // the tunnel drops. | ||
| 492 | void ThreadBtfConnect(void* parg) | ||
| 493 | { | ||
| 494 | printf("ThreadBtfConnect started\n"); | ||
| 495 | string strAddr = *(string*)parg; | ||
| 496 | delete (string*)parg; | ||
| 497 | loop | ||
| 498 | { | ||
| 499 | if (fShutdown) | ||
| 500 | return; | ||
| 501 | try | ||
| 502 | { | ||
| 503 | CNode* pnode = ConnectNodeBtf(strAddr); | ||
| 504 | if (pnode) | ||
| 505 | { | ||
| 506 | if (!pnode->fNetworkNode) | ||
| 507 | pnode->fNetworkNode = true; // keep the ref from ConnectNodeBtf | ||
| 508 | else | ||
| 509 | pnode->Release(); // already pinned; drop the extra ref | ||
| 510 | } | ||
| 511 | } | ||
| 512 | CATCH_PRINT_EXCEPTION("ThreadBtfConnect") | ||
| 513 | for (int i = 0; i < 30 && !fShutdown; i++) | ||
| 514 | Sleep(1000); | ||
| 515 | } | ||
| 516 | } | ||
| 517 | |||
| 518 | void CNode::Disconnect() | ||
| 519 | { | ||
| 520 | printf("disconnecting node %s\n", addr.ToString().c_str()); | ||
| 521 | |||
| 522 | closesocket(hSocket); | ||
| 523 | |||
| 524 | // All of a nodes broadcasts and subscriptions are automatically torn down | ||
| 525 | // when it goes down, so a node has to stay up to keep its broadcast going. | ||
| 526 | |||
| 527 | CRITICAL_BLOCK(cs_mapProducts) | ||
| 528 | for (map<uint256, CProduct>::iterator mi = mapProducts.begin(); mi != mapProducts.end();) | ||
| 529 | AdvertRemoveSource(this, MSG_PRODUCT, 0, (*(mi++)).second); | ||
| 530 | |||
| 531 | // Cancel subscriptions | ||
| 532 | for (unsigned int nChannel = 0; nChannel < vfSubscribe.size(); nChannel++) | ||
| 533 | if (vfSubscribe[nChannel]) | ||
| 534 | CancelSubscribe(nChannel); | ||
| 535 | } | ||
| 536 | |||
| 537 | |||
| 538 | |||
| 539 | |||
| 540 | |||
| 541 | |||
| 542 | |||
| 543 | |||
| 544 | |||
| 545 | |||
| 546 | |||
| 547 | |||
| 548 | |||
| 549 | void ThreadSocketHandler(void* parg) | ||
| 550 | { | ||
| 551 | IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg)); | ||
| 552 | |||
| 553 | loop | ||
| 554 | { | ||
| 555 | vfThreadRunning[0] = true; | ||
| 556 | CheckForShutdown(0); | ||
| 557 | try | ||
| 558 | { | ||
| 559 | ThreadSocketHandler2(parg); | ||
| 560 | } | ||
| 561 | CATCH_PRINT_EXCEPTION("ThreadSocketHandler()") | ||
| 562 | vfThreadRunning[0] = false; | ||
| 563 | Sleep(5000); | ||
| 564 | } | ||
| 565 | } | ||
| 566 | |||
| 567 | void ThreadSocketHandler2(void* parg) | ||
| 568 | { | ||
| 569 | printf("ThreadSocketHandler started\n"); | ||
| 570 | SOCKET hListenSocket = *(SOCKET*)parg; | ||
| 571 | list<CNode*> vNodesDisconnected; | ||
| 572 | int nPrevNodeCount = 0; | ||
| 573 | |||
| 574 | loop | ||
| 575 | { | ||
| 576 | // | ||
| 577 | // Disconnect nodes | ||
| 578 | // | ||
| 579 | CRITICAL_BLOCK(cs_vNodes) | ||
| 580 | { | ||
| 581 | // Disconnect duplicate connections | ||
| 582 | map<unsigned int, CNode*> mapFirst; | ||
| 583 | foreach(CNode* pnode, vNodes) | ||
| 584 | { | ||
| 585 | if (pnode->fDisconnect) | ||
| 586 | continue; | ||
| 587 | unsigned int ip = pnode->addr.ip; | ||
| 588 | if (mapFirst.count(ip) && addrLocalHost.ip < ip) | ||
| 589 | { | ||
| 590 | // In case two nodes connect to each other at once, | ||
| 591 | // the lower ip disconnects its outbound connection | ||
| 592 | CNode* pnodeExtra = mapFirst[ip]; | ||
| 593 | |||
| 594 | if (pnodeExtra->GetRefCount() > (pnodeExtra->fNetworkNode ? 1 : 0)) | ||
| 595 | swap(pnodeExtra, pnode); | ||
| 596 | |||
| 597 | if (pnodeExtra->GetRefCount() <= (pnodeExtra->fNetworkNode ? 1 : 0)) | ||
| 598 | { | ||
| 599 | printf("(%d nodes) disconnecting duplicate: %s\n", vNodes.size(), pnodeExtra->addr.ToString().c_str()); | ||
| 600 | if (pnodeExtra->fNetworkNode && !pnode->fNetworkNode) | ||
| 601 | { | ||
| 602 | pnode->AddRef(); | ||
| 603 | swap(pnodeExtra->fNetworkNode, pnode->fNetworkNode); | ||
| 604 | pnodeExtra->Release(); | ||
| 605 | } | ||
| 606 | pnodeExtra->fDisconnect = true; | ||
| 607 | } | ||
| 608 | } | ||
| 609 | mapFirst[ip] = pnode; | ||
| 610 | } | ||
| 611 | |||
| 612 | // Disconnect unused nodes | ||
| 613 | vector<CNode*> vNodesCopy = vNodes; | ||
| 614 | foreach(CNode* pnode, vNodesCopy) | ||
| 615 | { | ||
| 616 | if (pnode->ReadyToDisconnect() && pnode->vRecv.empty() && pnode->vSend.empty()) | ||
| 617 | { | ||
| 618 | // remove from vNodes | ||
| 619 | vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end()); | ||
| 620 | pnode->Disconnect(); | ||
| 621 | |||
| 622 | // hold in disconnected pool until all refs are released | ||
| 623 | pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 5 * 60); | ||
| 624 | if (pnode->fNetworkNode) | ||
| 625 | pnode->Release(); | ||
| 626 | vNodesDisconnected.push_back(pnode); | ||
| 627 | } | ||
| 628 | } | ||
| 629 | |||
| 630 | // Delete disconnected nodes | ||
| 631 | list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected; | ||
| 632 | foreach(CNode* pnode, vNodesDisconnectedCopy) | ||
| 633 | { | ||
| 634 | // wait until threads are done using it | ||
| 635 | if (pnode->GetRefCount() <= 0) | ||
| 636 | { | ||
| 637 | bool fDelete = false; | ||
| 638 | TRY_CRITICAL_BLOCK(pnode->cs_vSend) | ||
| 639 | TRY_CRITICAL_BLOCK(pnode->cs_vRecv) | ||
| 640 | TRY_CRITICAL_BLOCK(pnode->cs_mapRequests) | ||
| 641 | TRY_CRITICAL_BLOCK(pnode->cs_inventory) | ||
| 642 | fDelete = true; | ||
| 643 | if (fDelete) | ||
| 644 | { | ||
| 645 | vNodesDisconnected.remove(pnode); | ||
| 646 | delete pnode; | ||
| 647 | } | ||
| 648 | } | ||
| 649 | } | ||
| 650 | } | ||
| 651 | if (vNodes.size() != nPrevNodeCount) | ||
| 652 | { | ||
| 653 | nPrevNodeCount = vNodes.size(); | ||
| 654 | MainFrameRepaint(); | ||
| 655 | } | ||
| 656 | |||
| 657 | |||
| 658 | // | ||
| 659 | // Find which sockets have data to receive | ||
| 660 | // | ||
| 661 | struct timeval timeout; | ||
| 662 | timeout.tv_sec = 0; | ||
| 663 | timeout.tv_usec = 50000; // frequency to poll pnode->vSend | ||
| 664 | |||
| 665 | fd_set fdsetRecv; | ||
| 666 | fd_set fdsetSend; | ||
| 667 | FD_ZERO(&fdsetRecv); | ||
| 668 | FD_ZERO(&fdsetSend); | ||
| 669 | SOCKET hSocketMax = 0; | ||
| 670 | FD_SET(hListenSocket, &fdsetRecv); | ||
| 671 | hSocketMax = max(hSocketMax, hListenSocket); | ||
| 672 | CRITICAL_BLOCK(cs_vNodes) | ||
| 673 | { | ||
| 674 | foreach(CNode* pnode, vNodes) | ||
| 675 | { | ||
| 676 | FD_SET(pnode->hSocket, &fdsetRecv); | ||
| 677 | hSocketMax = max(hSocketMax, pnode->hSocket); | ||
| 678 | TRY_CRITICAL_BLOCK(pnode->cs_vSend) | ||
| 679 | if (!pnode->vSend.empty()) | ||
| 680 | FD_SET(pnode->hSocket, &fdsetSend); | ||
| 681 | } | ||
| 682 | } | ||
| 683 | |||
| 684 | vfThreadRunning[0] = false; | ||
| 685 | int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, NULL, &timeout); | ||
| 686 | vfThreadRunning[0] = true; | ||
| 687 | CheckForShutdown(0); | ||
| 688 | if (nSelect == SOCKET_ERROR) | ||
| 689 | { | ||
| 690 | int nErr = WSAGetLastError(); | ||
| 691 | printf("select failed: %d\n", nErr); | ||
| 692 | for (int i = 0; i <= hSocketMax; i++) | ||
| 693 | { | ||
| 694 | FD_SET(i, &fdsetRecv); | ||
| 695 | FD_SET(i, &fdsetSend); | ||
| 696 | } | ||
| 697 | Sleep(timeout.tv_usec/1000); | ||
| 698 | } | ||
| 699 | RandAddSeed(); | ||
| 700 | |||
| 701 | //// debug print | ||
| 702 | //foreach(CNode* pnode, vNodes) | ||
| 703 | //{ | ||
| 704 | // printf("vRecv = %-5d ", pnode->vRecv.size()); | ||
| 705 | // printf("vSend = %-5d ", pnode->vSend.size()); | ||
| 706 | //} | ||
| 707 | //printf("\n"); | ||
| 708 | |||
| 709 | |||
| 710 | // | ||
| 711 | // Accept new connections | ||
| 712 | // | ||
| 713 | if (FD_ISSET(hListenSocket, &fdsetRecv)) | ||
| 714 | { | ||
| 715 | struct sockaddr_in sockaddr; | ||
| 716 | #ifdef _WIN32 | ||
| 717 | int len = sizeof(sockaddr); | ||
| 718 | #else | ||
| 719 | socklen_t len = sizeof(sockaddr); | ||
| 720 | #endif | ||
| 721 | SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len); | ||
| 722 | CAddress addr(sockaddr); | ||
| 723 | if (hSocket == INVALID_SOCKET) | ||
| 724 | { | ||
| 725 | if (WSAGetLastError() != WSAEWOULDBLOCK) | ||
| 726 | printf("ERROR ThreadSocketHandler accept failed: %d\n", WSAGetLastError()); | ||
| 727 | } | ||
| 728 | else | ||
| 729 | { | ||
| 730 | printf("accepted connection from %s\n", addr.ToString().c_str()); | ||
| 731 | CNode* pnode = new CNode(hSocket, addr, true); | ||
| 732 | pnode->AddRef(); | ||
| 733 | CRITICAL_BLOCK(cs_vNodes) | ||
| 734 | vNodes.push_back(pnode); | ||
| 735 | } | ||
| 736 | } | ||
| 737 | |||
| 738 | |||
| 739 | // | ||
| 740 | // Service each socket | ||
| 741 | // | ||
| 742 | vector<CNode*> vNodesCopy; | ||
| 743 | CRITICAL_BLOCK(cs_vNodes) | ||
| 744 | vNodesCopy = vNodes; | ||
| 745 | foreach(CNode* pnode, vNodesCopy) | ||
| 746 | { | ||
| 747 | CheckForShutdown(0); | ||
| 748 | SOCKET hSocket = pnode->hSocket; | ||
| 749 | |||
| 750 | // | ||
| 751 | // Receive | ||
| 752 | // | ||
| 753 | if (FD_ISSET(hSocket, &fdsetRecv)) | ||
| 754 | { | ||
| 755 | TRY_CRITICAL_BLOCK(pnode->cs_vRecv) | ||
| 756 | { | ||
| 757 | CDataStream& vRecv = pnode->vRecv; | ||
| 758 | unsigned int nPos = vRecv.size(); | ||
| 759 | |||
| 760 | // typical socket buffer is 8K-64K | ||
| 761 | const unsigned int nBufSize = 0x10000; | ||
| 762 | vRecv.resize(nPos + nBufSize); | ||
| 763 | int nBytes = recv(hSocket, &vRecv[nPos], nBufSize, 0); | ||
| 764 | vRecv.resize(nPos + max(nBytes, 0)); | ||
| 765 | if (nBytes == 0) | ||
| 766 | { | ||
| 767 | // socket closed gracefully | ||
| 768 | if (!pnode->fDisconnect) | ||
| 769 | printf("recv: socket closed\n"); | ||
| 770 | pnode->fDisconnect = true; | ||
| 771 | } | ||
| 772 | else if (nBytes < 0) | ||
| 773 | { | ||
| 774 | // socket error | ||
| 775 | int nErr = WSAGetLastError(); | ||
| 776 | if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS) | ||
| 777 | { | ||
| 778 | if (!pnode->fDisconnect) | ||
| 779 | printf("recv failed: %d\n", nErr); | ||
| 780 | pnode->fDisconnect = true; | ||
| 781 | } | ||
| 782 | } | ||
| 783 | } | ||
| 784 | } | ||
| 785 | |||
| 786 | // | ||
| 787 | // Send | ||
| 788 | // | ||
| 789 | if (FD_ISSET(hSocket, &fdsetSend)) | ||
| 790 | { | ||
| 791 | TRY_CRITICAL_BLOCK(pnode->cs_vSend) | ||
| 792 | { | ||
| 793 | CDataStream& vSend = pnode->vSend; | ||
| 794 | if (!vSend.empty()) | ||
| 795 | { | ||
| 796 | int nBytes = send(hSocket, &vSend[0], vSend.size(), 0); | ||
| 797 | if (nBytes > 0) | ||
| 798 | { | ||
| 799 | vSend.erase(vSend.begin(), vSend.begin() + nBytes); | ||
| 800 | } | ||
| 801 | else if (nBytes == 0) | ||
| 802 | { | ||
| 803 | if (pnode->ReadyToDisconnect()) | ||
| 804 | pnode->vSend.clear(); | ||
| 805 | } | ||
| 806 | else | ||
| 807 | { | ||
| 808 | printf("send error %d\n", nBytes); | ||
| 809 | if (pnode->ReadyToDisconnect()) | ||
| 810 | pnode->vSend.clear(); | ||
| 811 | } | ||
| 812 | } | ||
| 813 | } | ||
| 814 | } | ||
| 815 | } | ||
| 816 | |||
| 817 | |||
| 818 | Sleep(10); | ||
| 819 | } | ||
| 820 | } | ||
| 821 | |||
| 822 | |||
| 823 | |||
| 824 | |||
| 825 | |||
| 826 | |||
| 827 | |||
| 828 | |||
| 829 | |||
| 830 | |||
| 831 | void ThreadOpenConnections(void* parg) | ||
| 832 | { | ||
| 833 | IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg)); | ||
| 834 | |||
| 835 | loop | ||
| 836 | { | ||
| 837 | vfThreadRunning[1] = true; | ||
| 838 | CheckForShutdown(1); | ||
| 839 | try | ||
| 840 | { | ||
| 841 | ThreadOpenConnections2(parg); | ||
| 842 | } | ||
| 843 | CATCH_PRINT_EXCEPTION("ThreadOpenConnections()") | ||
| 844 | vfThreadRunning[1] = false; | ||
| 845 | Sleep(5000); | ||
| 846 | } | ||
| 847 | } | ||
| 848 | |||
| 849 | void ThreadOpenConnections2(void* parg) | ||
| 850 | { | ||
| 851 | printf("ThreadOpenConnections started\n"); | ||
| 852 | |||
| 853 | // Initiate network connections | ||
| 854 | const int nMaxConnections = 15; | ||
| 855 | loop | ||
| 856 | { | ||
| 857 | // Wait | ||
| 858 | vfThreadRunning[1] = false; | ||
| 859 | Sleep(500); | ||
| 860 | while (vNodes.size() >= nMaxConnections || vNodes.size() >= mapAddresses.size()) | ||
| 861 | { | ||
| 862 | CheckForShutdown(1); | ||
| 863 | Sleep(2000); | ||
| 864 | } | ||
| 865 | vfThreadRunning[1] = true; | ||
| 866 | CheckForShutdown(1); | ||
| 867 | |||
| 868 | |||
| 869 | // Make a list of unique class C's | ||
| 870 | unsigned char pchIPCMask[4] = { 0xff, 0xff, 0xff, 0x00 }; | ||
| 871 | unsigned int nIPCMask = *(unsigned int*)pchIPCMask; | ||
| 872 | vector<unsigned int> vIPC; | ||
| 873 | CRITICAL_BLOCK(cs_mapAddresses) | ||
| 874 | { | ||
| 875 | vIPC.reserve(mapAddresses.size()); | ||
| 876 | unsigned int nPrev = 0; | ||
| 877 | foreach(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses) | ||
| 878 | { | ||
| 879 | const CAddress& addr = item.second; | ||
| 880 | if (!addr.IsIPv4()) | ||
| 881 | continue; | ||
| 882 | |||
| 883 | // Taking advantage of mapAddresses being in sorted order, | ||
| 884 | // with IPs of the same class C grouped together. | ||
| 885 | unsigned int ipC = addr.ip & nIPCMask; | ||
| 886 | if (ipC != nPrev) | ||
| 887 | vIPC.push_back(nPrev = ipC); | ||
| 888 | } | ||
| 889 | } | ||
| 890 | |||
| 891 | // | ||
| 892 | // The IP selection process is designed to limit vulnerability to address flooding. | ||
| 893 | // Any class C (a.b.c.?) has an equal chance of being chosen, then an IP is | ||
| 894 | // chosen within the class C. An attacker may be able to allocate many IPs, but | ||
| 895 | // they would normally be concentrated in blocks of class C's. They can hog the | ||
| 896 | // attention within their class C, but not the whole IP address space overall. | ||
| 897 | // A lone node in a class C will get as much attention as someone holding all 255 | ||
| 898 | // IPs in another class C. | ||
| 899 | // | ||
| 900 | bool fSuccess = false; | ||
| 901 | int nLimit = vIPC.size(); | ||
| 902 | while (!fSuccess && nLimit-- > 0) | ||
| 903 | { | ||
| 904 | // Choose a random class C | ||
| 905 | unsigned int ipC = vIPC[GetRand(vIPC.size())]; | ||
| 906 | |||
| 907 | // Organize all addresses in the class C by IP | ||
| 908 | map<unsigned int, vector<CAddress> > mapIP; | ||
| 909 | CRITICAL_BLOCK(cs_mapAddresses) | ||
| 910 | { | ||
| 911 | unsigned int nDelay = ((30 * 60) << vNodes.size()); | ||
| 912 | if (nDelay > 8 * 60 * 60) | ||
| 913 | nDelay = 8 * 60 * 60; | ||
| 914 | for (map<vector<unsigned char>, CAddress>::iterator mi = mapAddresses.lower_bound(CAddress(ipC, 0).GetKey()); | ||
| 915 | mi != mapAddresses.upper_bound(CAddress(ipC | ~nIPCMask, 0xffff).GetKey()); | ||
| 916 | ++mi) | ||
| 917 | { | ||
| 918 | const CAddress& addr = (*mi).second; | ||
| 919 | unsigned int nRandomizer = (addr.nLastFailed * addr.ip * 7777U) % 20000; | ||
| 920 | if (GetTime() - addr.nLastFailed > nDelay * nRandomizer / 10000) | ||
| 921 | mapIP[addr.ip].push_back(addr); | ||
| 922 | } | ||
| 923 | } | ||
| 924 | if (mapIP.empty()) | ||
| 925 | break; | ||
| 926 | |||
| 927 | // Choose a random IP in the class C | ||
| 928 | map<unsigned int, vector<CAddress> >::iterator mi = mapIP.begin(); | ||
| 929 | advance(mi, GetRand(mapIP.size())); | ||
| 930 | |||
| 931 | // Once we've chosen an IP, we'll try every given port before moving on | ||
| 932 | foreach(const CAddress& addrConnect, (*mi).second) | ||
| 933 | { | ||
| 934 | if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip)) | ||
| 935 | continue; | ||
| 936 | |||
| 937 | CNode* pnode = ConnectNode(addrConnect); | ||
| 938 | if (!pnode) | ||
| 939 | continue; | ||
| 940 | pnode->fNetworkNode = true; | ||
| 941 | |||
| 942 | if (addrLocalHost.IsRoutable()) | ||
| 943 | { | ||
| 944 | // Advertise our address | ||
| 945 | vector<CAddress> vAddrToSend; | ||
| 946 | vAddrToSend.push_back(addrLocalHost); | ||
| 947 | pnode->PushMessage("addr", vAddrToSend); | ||
| 948 | } | ||
| 949 | |||
| 950 | // Get as many addresses as we can | ||
| 951 | pnode->PushMessage("getaddr"); | ||
| 952 | |||
| 953 | ////// should the one on the receiving end do this too? | ||
| 954 | // Subscribe our local subscription list | ||
| 955 | const unsigned int nHops = 0; | ||
| 956 | for (unsigned int nChannel = 0; nChannel < pnodeLocalHost->vfSubscribe.size(); nChannel++) | ||
| 957 | if (pnodeLocalHost->vfSubscribe[nChannel]) | ||
| 958 | pnode->PushMessage("subscribe", nChannel, nHops); | ||
| 959 | |||
| 960 | fSuccess = true; | ||
| 961 | break; | ||
| 962 | } | ||
| 963 | } | ||
| 964 | } | ||
| 965 | } | ||
| 966 | |||
| 967 | |||
| 968 | |||
| 969 | |||
| 970 | |||
| 971 | |||
| 972 | |||
| 973 | |||
| 974 | void ThreadMessageHandler(void* parg) | ||
| 975 | { | ||
| 976 | IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg)); | ||
| 977 | |||
| 978 | loop | ||
| 979 | { | ||
| 980 | vfThreadRunning[2] = true; | ||
| 981 | CheckForShutdown(2); | ||
| 982 | try | ||
| 983 | { | ||
| 984 | ThreadMessageHandler2(parg); | ||
| 985 | } | ||
| 986 | CATCH_PRINT_EXCEPTION("ThreadMessageHandler()") | ||
| 987 | vfThreadRunning[2] = false; | ||
| 988 | Sleep(5000); | ||
| 989 | } | ||
| 990 | } | ||
| 991 | |||
| 992 | void ThreadMessageHandler2(void* parg) | ||
| 993 | { | ||
| 994 | printf("ThreadMessageHandler started\n"); | ||
| 995 | SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL); | ||
| 996 | loop | ||
| 997 | { | ||
| 998 | // Poll the connected nodes for messages | ||
| 999 | vector<CNode*> vNodesCopy; | ||
| 1000 | CRITICAL_BLOCK(cs_vNodes) | ||
| 1001 | vNodesCopy = vNodes; | ||
| 1002 | foreach(CNode* pnode, vNodesCopy) | ||
| 1003 | { | ||
| 1004 | pnode->AddRef(); | ||
| 1005 | |||
| 1006 | // Receive messages | ||
| 1007 | TRY_CRITICAL_BLOCK(pnode->cs_vRecv) | ||
| 1008 | ProcessMessages(pnode); | ||
| 1009 | |||
| 1010 | // Send messages | ||
| 1011 | TRY_CRITICAL_BLOCK(pnode->cs_vSend) | ||
| 1012 | SendMessages(pnode); | ||
| 1013 | |||
| 1014 | pnode->Release(); | ||
| 1015 | } | ||
| 1016 | |||
| 1017 | // Wait and allow messages to bunch up | ||
| 1018 | vfThreadRunning[2] = false; | ||
| 1019 | Sleep(100); | ||
| 1020 | vfThreadRunning[2] = true; | ||
| 1021 | CheckForShutdown(2); | ||
| 1022 | } | ||
| 1023 | } | ||
| 1024 | |||
| 1025 | |||
| 1026 | |||
| 1027 | |||
| 1028 | |||
| 1029 | |||
| 1030 | |||
| 1031 | |||
| 1032 | |||
| 1033 | //// todo: start one thread per processor, use getenv("NUMBER_OF_PROCESSORS") | ||
| 1034 | void ThreadBitcoinMiner(void* parg) | ||
| 1035 | { | ||
| 1036 | vfThreadRunning[3] = true; | ||
| 1037 | CheckForShutdown(3); | ||
| 1038 | try | ||
| 1039 | { | ||
| 1040 | bool fRet = BitcoinMiner(); | ||
| 1041 | printf("BitcoinMiner returned %s\n\n\n", fRet ? "true" : "false"); | ||
| 1042 | } | ||
| 1043 | CATCH_PRINT_EXCEPTION("BitcoinMiner()") | ||
| 1044 | vfThreadRunning[3] = false; | ||
| 1045 | } | ||
| 1046 | |||
| 1047 | |||
| 1048 | |||
| 1049 | |||
| 1050 | |||
| 1051 | |||
| 1052 | |||
| 1053 | |||
| 1054 | |||
| 1055 | |||
| 1056 | |||
| 1057 | bool StartNode(string& strError) | ||
| 1058 | { | ||
| 1059 | strError = ""; | ||
| 1060 | |||
| 1061 | // Sockets startup | ||
| 1062 | WSADATA wsadata; | ||
| 1063 | int ret = WSAStartup(MAKEWORD(2,2), &wsadata); | ||
| 1064 | if (ret != NO_ERROR) | ||
| 1065 | { | ||
| 1066 | strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret); | ||
| 1067 | printf("%s\n", strError.c_str()); | ||
| 1068 | return false; | ||
| 1069 | } | ||
| 1070 | |||
| 1071 | // Get local host ip | ||
| 1072 | char pszHostName[255]; | ||
| 1073 | if (gethostname(pszHostName, 255) == SOCKET_ERROR) | ||
| 1074 | { | ||
| 1075 | strError = strprintf("Error: Unable to get IP address of this computer (gethostname returned error %d)", WSAGetLastError()); | ||
| 1076 | printf("%s\n", strError.c_str()); | ||
| 1077 | return false; | ||
| 1078 | } | ||
| 1079 | struct hostent* pHostEnt = gethostbyname(pszHostName); | ||
| 1080 | if (!pHostEnt) | ||
| 1081 | { | ||
| 1082 | strError = strprintf("Error: Unable to get IP address of this computer (gethostbyname returned error %d)", WSAGetLastError()); | ||
| 1083 | printf("%s\n", strError.c_str()); | ||
| 1084 | return false; | ||
| 1085 | } | ||
| 1086 | addrLocalHost = CAddress(*(long*)(pHostEnt->h_addr_list[0]), | ||
| 1087 | nListenPort, | ||
| 1088 | nLocalServices); | ||
| 1089 | printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str()); | ||
| 1090 | |||
| 1091 | // Create socket for listening for incoming connections | ||
| 1092 | SOCKET hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); | ||
| 1093 | if (hListenSocket == INVALID_SOCKET) | ||
| 1094 | { | ||
| 1095 | strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError()); | ||
| 1096 | printf("%s\n", strError.c_str()); | ||
| 1097 | return false; | ||
| 1098 | } | ||
| 1099 | |||
| 1100 | // Set to nonblocking, incoming connections will also inherit this | ||
| 1101 | u_long nOne = 1; | ||
| 1102 | if (ioctlsocket(hListenSocket, FIONBIO, &nOne) == SOCKET_ERROR) | ||
| 1103 | { | ||
| 1104 | strError = strprintf("Error: Couldn't set properties on socket for incoming connections (ioctlsocket returned error %d)", WSAGetLastError()); | ||
| 1105 | printf("%s\n", strError.c_str()); | ||
| 1106 | return false; | ||
| 1107 | } | ||
| 1108 | |||
| 1109 | // The sockaddr_in structure specifies the address family, | ||
| 1110 | // IP address, and port for the socket that is being bound | ||
| 1111 | int nRetryLimit = 15; | ||
| 1112 | struct sockaddr_in sockaddr = addrLocalHost.GetSockAddr(); | ||
| 1113 | if (bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR) | ||
| 1114 | { | ||
| 1115 | int nErr = WSAGetLastError(); | ||
| 1116 | if (nErr == WSAEADDRINUSE) | ||
| 1117 | strError = strprintf("Error: Unable to bind to port %s on this computer. The program is probably already running.", addrLocalHost.ToString().c_str()); | ||
| 1118 | else | ||
| 1119 | strError = strprintf("Error: Unable to bind to port %s on this computer (bind returned error %d)", addrLocalHost.ToString().c_str(), nErr); | ||
| 1120 | printf("%s\n", strError.c_str()); | ||
| 1121 | return false; | ||
| 1122 | } | ||
| 1123 | printf("bound to addrLocalHost = %s\n\n", addrLocalHost.ToString().c_str()); | ||
| 1124 | |||
| 1125 | // Listen for incoming connections | ||
| 1126 | if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR) | ||
| 1127 | { | ||
| 1128 | strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError()); | ||
| 1129 | printf("%s\n", strError.c_str()); | ||
| 1130 | return false; | ||
| 1131 | } | ||
| 1132 | |||
| 1133 | // Get our external IP address for incoming connections | ||
| 1134 | if (addrIncoming.ip) | ||
| 1135 | addrLocalHost.ip = addrIncoming.ip; | ||
| 1136 | |||
| 1137 | if (GetMyExternalIP(addrLocalHost.ip)) | ||
| 1138 | { | ||
| 1139 | addrIncoming = addrLocalHost; | ||
| 1140 | CWalletDB().WriteSetting("addrIncoming", addrIncoming); | ||
| 1141 | } | ||
| 1142 | |||
| 1143 | // Peer discovery over Nostr relays (replaces the old IRC seed) | ||
| 1144 | if (_beginthread(ThreadNostrSeed, 0, NULL) == -1) | ||
| 1145 | printf("Error: _beginthread(ThreadNostrSeed) failed\n"); | ||
| 1146 | |||
| 1147 | // Anonymous inbound: this node's .btf hidden service, reachable through the | ||
| 1148 | // meeting relay without exposing our IP or needing a public port. | ||
| 1149 | if (!strBtfMeetingRelay.empty()) | ||
| 1150 | if (_beginthread(ThreadBtfAccept, 0, NULL) == -1) | ||
| 1151 | printf("Error: _beginthread(ThreadBtfAccept) failed\n"); | ||
| 1152 | |||
| 1153 | // Anonymous outbound: keep a connection to a specific .btf peer, if asked. | ||
| 1154 | if (!strBtfConnect.empty()) | ||
| 1155 | if (_beginthread(ThreadBtfConnect, 0, new string(strBtfConnect)) == -1) | ||
| 1156 | printf("Error: _beginthread(ThreadBtfConnect) failed\n"); | ||
| 1157 | |||
| 1158 | // | ||
| 1159 | // Start threads | ||
| 1160 | // | ||
| 1161 | if (_beginthread(ThreadSocketHandler, 0, new SOCKET(hListenSocket)) == -1) | ||
| 1162 | { | ||
| 1163 | strError = "Error: _beginthread(ThreadSocketHandler) failed"; | ||
| 1164 | printf("%s\n", strError.c_str()); | ||
| 1165 | return false; | ||
| 1166 | } | ||
| 1167 | |||
| 1168 | if (_beginthread(ThreadOpenConnections, 0, NULL) == -1) | ||
| 1169 | { | ||
| 1170 | strError = "Error: _beginthread(ThreadOpenConnections) failed"; | ||
| 1171 | printf("%s\n", strError.c_str()); | ||
| 1172 | return false; | ||
| 1173 | } | ||
| 1174 | |||
| 1175 | if (_beginthread(ThreadMessageHandler, 0, NULL) == -1) | ||
| 1176 | { | ||
| 1177 | strError = "Error: _beginthread(ThreadMessageHandler) failed"; | ||
| 1178 | printf("%s\n", strError.c_str()); | ||
| 1179 | return false; | ||
| 1180 | } | ||
| 1181 | |||
| 1182 | return true; | ||
| 1183 | } | ||
| 1184 | |||
| 1185 | bool StopNode() | ||
| 1186 | { | ||
| 1187 | printf("StopNode()\n"); | ||
| 1188 | fShutdown = true; | ||
| 1189 | nTransactionsUpdated++; | ||
| 1190 | while (count(vfThreadRunning.begin(), vfThreadRunning.end(), true)) | ||
| 1191 | Sleep(10); | ||
| 1192 | Sleep(50); | ||
| 1193 | |||
| 1194 | // Sockets shutdown | ||
| 1195 | WSACleanup(); | ||
| 1196 | return true; | ||
| 1197 | } | ||
| 1198 | |||
| 1199 | void CheckForShutdown(int n) | ||
| 1200 | { | ||
| 1201 | if (fShutdown) | ||
| 1202 | { | ||
| 1203 | if (n != -1) | ||
| 1204 | vfThreadRunning[n] = false; | ||
| 1205 | _endthread(); | ||
| 1206 | } | ||
| 1207 | } | ||
diff --git a/src/net.h b/src/net.h new file mode 100644 index 0000000..6e62126 --- /dev/null +++ b/src/net.h | |||
| @@ -0,0 +1,863 @@ | |||
| 1 | // Copyright (c) 2009 Satoshi Nakamoto | ||
| 2 | // Distributed under the MIT/X11 software license, see the accompanying | ||
| 3 | // file license.txt or http://www.opensource.org/licenses/mit-license.php. | ||
| 4 | |||
| 5 | class CMessageHeader; | ||
| 6 | class CAddress; | ||
| 7 | class CInv; | ||
| 8 | class CRequestTracker; | ||
| 9 | class CNode; | ||
| 10 | |||
| 11 | |||
| 12 | |||
| 13 | static const unsigned short DEFAULT_PORT = htons(8433); | ||
| 14 | static const unsigned int PUBLISH_HOPS = 5; | ||
| 15 | enum | ||
| 16 | { | ||
| 17 | NODE_NETWORK = (1 << 0), | ||
| 18 | }; | ||
| 19 | |||
| 20 | |||
| 21 | |||
| 22 | |||
| 23 | |||
| 24 | |||
| 25 | bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet); | ||
| 26 | bool GetMyExternalIP(unsigned int& ipRet); | ||
| 27 | bool AddAddress(CAddrDB& addrdb, const CAddress& addr); | ||
| 28 | CNode* FindNode(unsigned int ip); | ||
| 29 | CNode* ConnectNode(CAddress addrConnect, int64 nTimeout=0); | ||
| 30 | CNode* ConnectNodeBtf(const string& strBtfAddr); | ||
| 31 | void ThreadBtfAccept(void* parg); | ||
| 32 | void ThreadBtfConnect(void* parg); | ||
| 33 | extern string strBtfConnect; | ||
| 34 | void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1); | ||
| 35 | bool AnySubscribed(unsigned int nChannel); | ||
| 36 | void ThreadBitcoinMiner(void* parg); | ||
| 37 | bool StartNode(string& strError=REF(string())); | ||
| 38 | bool StopNode(); | ||
| 39 | void CheckForShutdown(int n); | ||
| 40 | |||
| 41 | |||
| 42 | |||
| 43 | |||
| 44 | |||
| 45 | |||
| 46 | |||
| 47 | |||
| 48 | |||
| 49 | // | ||
| 50 | // Message header | ||
| 51 | // (4) message start | ||
| 52 | // (12) command | ||
| 53 | // (4) size | ||
| 54 | |||
| 55 | // The message start string is designed to be unlikely to occur in normal data. | ||
| 56 | // The characters are rarely used upper ascii, not valid as UTF-8, and produce | ||
| 57 | // a large 4-byte int at any alignment. | ||
| 58 | // Magic bytes unique to the Bitflash network (0xbf = "BF"). Second byte bumped | ||
| 59 | // to 0x20 for the 2026 stable relaunch so the old test chain can't interfere. | ||
| 60 | static const char pchMessageStart[4] = { 0xbf, 0x20, 0x5c, 0xfd }; | ||
| 61 | |||
| 62 | class CMessageHeader | ||
| 63 | { | ||
| 64 | public: | ||
| 65 | enum { COMMAND_SIZE=12 }; | ||
| 66 | char pchMessageStart[sizeof(::pchMessageStart)]; | ||
| 67 | char pchCommand[COMMAND_SIZE]; | ||
| 68 | unsigned int nMessageSize; | ||
| 69 | |||
| 70 | CMessageHeader() | ||
| 71 | { | ||
| 72 | memcpy(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart)); | ||
| 73 | memset(pchCommand, 0, sizeof(pchCommand)); | ||
| 74 | pchCommand[1] = 1; | ||
| 75 | nMessageSize = -1; | ||
| 76 | } | ||
| 77 | |||
| 78 | CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn) | ||
| 79 | { | ||
| 80 | memcpy(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart)); | ||
| 81 | strncpy(pchCommand, pszCommand, COMMAND_SIZE); | ||
| 82 | nMessageSize = nMessageSizeIn; | ||
| 83 | } | ||
| 84 | |||
| 85 | IMPLEMENT_SERIALIZE | ||
| 86 | ( | ||
| 87 | READWRITE(FLATDATA(pchMessageStart)); | ||
| 88 | READWRITE(FLATDATA(pchCommand)); | ||
| 89 | READWRITE(nMessageSize); | ||
| 90 | ) | ||
| 91 | |||
| 92 | string GetCommand() | ||
| 93 | { | ||
| 94 | if (pchCommand[COMMAND_SIZE-1] == 0) | ||
| 95 | return string(pchCommand, pchCommand + strlen(pchCommand)); | ||
| 96 | else | ||
| 97 | return string(pchCommand, pchCommand + COMMAND_SIZE); | ||
| 98 | } | ||
| 99 | |||
| 100 | bool IsValid() | ||
| 101 | { | ||
| 102 | // Check start string | ||
| 103 | if (memcmp(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart)) != 0) | ||
| 104 | return false; | ||
| 105 | |||
| 106 | // Check the command string for errors | ||
| 107 | for (char* p1 = pchCommand; p1 < pchCommand + COMMAND_SIZE; p1++) | ||
| 108 | { | ||
| 109 | if (*p1 == 0) | ||
| 110 | { | ||
| 111 | // Must be all zeros after the first zero | ||
| 112 | for (; p1 < pchCommand + COMMAND_SIZE; p1++) | ||
| 113 | if (*p1 != 0) | ||
| 114 | return false; | ||
| 115 | } | ||
| 116 | else if (*p1 < ' ' || *p1 > 0x7E) | ||
| 117 | return false; | ||
| 118 | } | ||
| 119 | |||
| 120 | // Message size | ||
| 121 | if (nMessageSize > 0x10000000) | ||
| 122 | { | ||
| 123 | printf("CMessageHeader::IsValid() : nMessageSize too large %u\n", nMessageSize); | ||
| 124 | return false; | ||
| 125 | } | ||
| 126 | |||
| 127 | return true; | ||
| 128 | } | ||
| 129 | }; | ||
| 130 | |||
| 131 | |||
| 132 | |||
| 133 | |||
| 134 | |||
| 135 | |||
| 136 | static const unsigned char pchIPv4[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff }; | ||
| 137 | |||
| 138 | class CAddress | ||
| 139 | { | ||
| 140 | public: | ||
| 141 | uint64 nServices; | ||
| 142 | unsigned char pchReserved[12]; | ||
| 143 | unsigned int ip; | ||
| 144 | unsigned short port; | ||
| 145 | |||
| 146 | // disk only | ||
| 147 | unsigned int nTime; | ||
| 148 | |||
| 149 | // memory only | ||
| 150 | unsigned int nLastFailed; | ||
| 151 | |||
| 152 | CAddress() | ||
| 153 | { | ||
| 154 | nServices = 0; | ||
| 155 | memcpy(pchReserved, pchIPv4, sizeof(pchReserved)); | ||
| 156 | ip = 0; | ||
| 157 | port = DEFAULT_PORT; | ||
| 158 | nTime = GetAdjustedTime(); | ||
| 159 | nLastFailed = 0; | ||
| 160 | } | ||
| 161 | |||
| 162 | CAddress(unsigned int ipIn, unsigned short portIn, uint64 nServicesIn=0) | ||
| 163 | { | ||
| 164 | nServices = nServicesIn; | ||
| 165 | memcpy(pchReserved, pchIPv4, sizeof(pchReserved)); | ||
| 166 | ip = ipIn; | ||
| 167 | port = portIn; | ||
| 168 | nTime = GetAdjustedTime(); | ||
| 169 | nLastFailed = 0; | ||
| 170 | } | ||
| 171 | |||
| 172 | explicit CAddress(const struct sockaddr_in& sockaddr, uint64 nServicesIn=0) | ||
| 173 | { | ||
| 174 | nServices = nServicesIn; | ||
| 175 | memcpy(pchReserved, pchIPv4, sizeof(pchReserved)); | ||
| 176 | ip = sockaddr.sin_addr.s_addr; | ||
| 177 | port = sockaddr.sin_port; | ||
| 178 | nTime = GetAdjustedTime(); | ||
| 179 | nLastFailed = 0; | ||
| 180 | } | ||
| 181 | |||
| 182 | explicit CAddress(const char* pszIn, uint64 nServicesIn=0) | ||
| 183 | { | ||
| 184 | nServices = nServicesIn; | ||
| 185 | memcpy(pchReserved, pchIPv4, sizeof(pchReserved)); | ||
| 186 | ip = 0; | ||
| 187 | port = DEFAULT_PORT; | ||
| 188 | nTime = GetAdjustedTime(); | ||
| 189 | nLastFailed = 0; | ||
| 190 | |||
| 191 | char psz[100]; | ||
| 192 | if (strlen(pszIn) > ARRAYLEN(psz)-1) | ||
| 193 | return; | ||
| 194 | strcpy(psz, pszIn); | ||
| 195 | unsigned int a, b, c, d, e; | ||
| 196 | if (sscanf(psz, "%u.%u.%u.%u:%u", &a, &b, &c, &d, &e) < 4) | ||
| 197 | return; | ||
| 198 | char* pszPort = strchr(psz, ':'); | ||
| 199 | if (pszPort) | ||
| 200 | { | ||
| 201 | *pszPort++ = '\0'; | ||
| 202 | port = htons(atoi(pszPort)); | ||
| 203 | } | ||
| 204 | ip = inet_addr(psz); | ||
| 205 | } | ||
| 206 | |||
| 207 | IMPLEMENT_SERIALIZE | ||
| 208 | ( | ||
| 209 | if (nType & SER_DISK) | ||
| 210 | { | ||
| 211 | READWRITE(nVersion); | ||
| 212 | READWRITE(nTime); | ||
| 213 | } | ||
| 214 | READWRITE(nServices); | ||
| 215 | READWRITE(FLATDATA(pchReserved)); | ||
| 216 | READWRITE(ip); | ||
| 217 | READWRITE(port); | ||
| 218 | ) | ||
| 219 | |||
| 220 | friend inline bool operator==(const CAddress& a, const CAddress& b) | ||
| 221 | { | ||
| 222 | return (memcmp(a.pchReserved, b.pchReserved, sizeof(a.pchReserved)) == 0 && | ||
| 223 | a.ip == b.ip && | ||
| 224 | a.port == b.port); | ||
| 225 | } | ||
| 226 | |||
| 227 | friend inline bool operator<(const CAddress& a, const CAddress& b) | ||
| 228 | { | ||
| 229 | int ret = memcmp(a.pchReserved, b.pchReserved, sizeof(a.pchReserved)); | ||
| 230 | if (ret < 0) | ||
| 231 | return true; | ||
| 232 | else if (ret == 0) | ||
| 233 | { | ||
| 234 | if (ntohl(a.ip) < ntohl(b.ip)) | ||
| 235 | return true; | ||
| 236 | else if (a.ip == b.ip) | ||
| 237 | return ntohs(a.port) < ntohs(b.port); | ||
| 238 | } | ||
| 239 | return false; | ||
| 240 | } | ||
| 241 | |||
| 242 | vector<unsigned char> GetKey() const | ||
| 243 | { | ||
| 244 | CDataStream ss; | ||
| 245 | ss.reserve(18); | ||
| 246 | ss << FLATDATA(pchReserved) << ip << port; | ||
| 247 | |||
| 248 | #if defined(_MSC_VER) && _MSC_VER < 1300 | ||
| 249 | return vector<unsigned char>((unsigned char*)&ss.begin()[0], (unsigned char*)&ss.end()[0]); | ||
| 250 | #else | ||
| 251 | return vector<unsigned char>(ss.begin(), ss.end()); | ||
| 252 | #endif | ||
| 253 | } | ||
| 254 | |||
| 255 | struct sockaddr_in GetSockAddr() const | ||
| 256 | { | ||
| 257 | struct sockaddr_in sockaddr; | ||
| 258 | sockaddr.sin_family = AF_INET; | ||
| 259 | sockaddr.sin_addr.s_addr = ip; | ||
| 260 | sockaddr.sin_port = port; | ||
| 261 | return sockaddr; | ||
| 262 | } | ||
| 263 | |||
| 264 | bool IsIPv4() const | ||
| 265 | { | ||
| 266 | return (memcmp(pchReserved, pchIPv4, sizeof(pchIPv4)) == 0); | ||
| 267 | } | ||
| 268 | |||
| 269 | bool IsRoutable() const | ||
| 270 | { | ||
| 271 | return !(GetByte(3) == 10 || (GetByte(3) == 192 && GetByte(2) == 168)); | ||
| 272 | } | ||
| 273 | |||
| 274 | unsigned char GetByte(int n) const | ||
| 275 | { | ||
| 276 | return ((unsigned char*)&ip)[3-n]; | ||
| 277 | } | ||
| 278 | |||
| 279 | string ToStringIPPort() const | ||
| 280 | { | ||
| 281 | return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port)); | ||
| 282 | } | ||
| 283 | |||
| 284 | string ToStringIP() const | ||
| 285 | { | ||
| 286 | return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0)); | ||
| 287 | } | ||
| 288 | |||
| 289 | string ToString() const | ||
| 290 | { | ||
| 291 | return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port)); | ||
| 292 | //return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0)); | ||
| 293 | } | ||
| 294 | |||
| 295 | void print() const | ||
| 296 | { | ||
| 297 | printf("CAddress(%s)\n", ToString().c_str()); | ||
| 298 | } | ||
| 299 | }; | ||
| 300 | |||
| 301 | |||
| 302 | |||
| 303 | |||
| 304 | |||
| 305 | |||
| 306 | |||
| 307 | enum | ||
| 308 | { | ||
| 309 | MSG_TX = 1, | ||
| 310 | MSG_BLOCK, | ||
| 311 | MSG_REVIEW, | ||
| 312 | MSG_PRODUCT, | ||
| 313 | MSG_TABLE, | ||
| 314 | }; | ||
| 315 | |||
| 316 | static const char* ppszTypeName[] = | ||
| 317 | { | ||
| 318 | "ERROR", | ||
| 319 | "tx", | ||
| 320 | "block", | ||
| 321 | "review", | ||
| 322 | "product", | ||
| 323 | "table", | ||
| 324 | }; | ||
| 325 | |||
| 326 | class CInv | ||
| 327 | { | ||
| 328 | public: | ||
| 329 | int type; | ||
| 330 | uint256 hash; | ||
| 331 | |||
| 332 | CInv() | ||
| 333 | { | ||
| 334 | type = 0; | ||
| 335 | hash = 0; | ||
| 336 | } | ||
| 337 | |||
| 338 | CInv(int typeIn, const uint256& hashIn) | ||
| 339 | { | ||
| 340 | type = typeIn; | ||
| 341 | hash = hashIn; | ||
| 342 | } | ||
| 343 | |||
| 344 | CInv(const string& strType, const uint256& hashIn) | ||
| 345 | { | ||
| 346 | int i; | ||
| 347 | for (i = 1; i < ARRAYLEN(ppszTypeName); i++) | ||
| 348 | { | ||
| 349 | if (strType == ppszTypeName[i]) | ||
| 350 | { | ||
| 351 | type = i; | ||
| 352 | break; | ||
| 353 | } | ||
| 354 | } | ||
| 355 | if (i == ARRAYLEN(ppszTypeName)) | ||
| 356 | throw std::out_of_range(strprintf("CInv::CInv(string, uint256) : unknown type '%s'", strType.c_str())); | ||
| 357 | hash = hashIn; | ||
| 358 | } | ||
| 359 | |||
| 360 | IMPLEMENT_SERIALIZE | ||
| 361 | ( | ||
| 362 | READWRITE(type); | ||
| 363 | READWRITE(hash); | ||
| 364 | ) | ||
| 365 | |||
| 366 | friend inline bool operator<(const CInv& a, const CInv& b) | ||
| 367 | { | ||
| 368 | return (a.type < b.type || (a.type == b.type && a.hash < b.hash)); | ||
| 369 | } | ||
| 370 | |||
| 371 | bool IsKnownType() const | ||
| 372 | { | ||
| 373 | return (type >= 1 && type < ARRAYLEN(ppszTypeName)); | ||
| 374 | } | ||
| 375 | |||
| 376 | const char* GetCommand() const | ||
| 377 | { | ||
| 378 | if (!IsKnownType()) | ||
| 379 | throw std::out_of_range(strprintf("CInv::GetCommand() : type=% unknown type", type)); | ||
| 380 | return ppszTypeName[type]; | ||
| 381 | } | ||
| 382 | |||
| 383 | string ToString() const | ||
| 384 | { | ||
| 385 | return strprintf("%s %s", GetCommand(), hash.ToString().substr(0,14).c_str()); | ||
| 386 | } | ||
| 387 | |||
| 388 | void print() const | ||
| 389 | { | ||
| 390 | printf("CInv(%s)\n", ToString().c_str()); | ||
| 391 | } | ||
| 392 | }; | ||
| 393 | |||
| 394 | |||
| 395 | |||
| 396 | |||
| 397 | |||
| 398 | class CRequestTracker | ||
| 399 | { | ||
| 400 | public: | ||
| 401 | void (*fn)(void*, CDataStream&); | ||
| 402 | void* param1; | ||
| 403 | |||
| 404 | explicit CRequestTracker(void (*fnIn)(void*, CDataStream&)=NULL, void* param1In=NULL) | ||
| 405 | { | ||
| 406 | fn = fnIn; | ||
| 407 | param1 = param1In; | ||
| 408 | } | ||
| 409 | |||
| 410 | bool IsNull() | ||
| 411 | { | ||
| 412 | return fn == NULL; | ||
| 413 | } | ||
| 414 | }; | ||
| 415 | |||
| 416 | |||
| 417 | |||
| 418 | |||
| 419 | |||
| 420 | extern bool fClient; | ||
| 421 | extern uint64 nLocalServices; | ||
| 422 | extern CAddress addrLocalHost; | ||
| 423 | extern unsigned short nListenPort; | ||
| 424 | extern CNode* pnodeLocalHost; | ||
| 425 | extern bool fShutdown; | ||
| 426 | extern array<bool, 10> vfThreadRunning; | ||
| 427 | extern vector<CNode*> vNodes; | ||
| 428 | extern CCriticalSection cs_vNodes; | ||
| 429 | extern map<vector<unsigned char>, CAddress> mapAddresses; | ||
| 430 | extern CCriticalSection cs_mapAddresses; | ||
| 431 | extern map<CInv, CDataStream> mapRelay; | ||
| 432 | extern deque<pair<int64, CInv> > vRelayExpiration; | ||
| 433 | extern CCriticalSection cs_mapRelay; | ||
| 434 | extern map<CInv, int64> mapAlreadyAskedFor; | ||
| 435 | extern CAddress addrProxy; | ||
| 436 | |||
| 437 | |||
| 438 | |||
| 439 | |||
| 440 | |||
| 441 | class CNode | ||
| 442 | { | ||
| 443 | public: | ||
| 444 | // socket | ||
| 445 | uint64 nServices; | ||
| 446 | SOCKET hSocket; | ||
| 447 | CDataStream vSend; | ||
| 448 | CDataStream vRecv; | ||
| 449 | CCriticalSection cs_vSend; | ||
| 450 | CCriticalSection cs_vRecv; | ||
| 451 | unsigned int nPushPos; | ||
| 452 | CAddress addr; | ||
| 453 | int nVersion; | ||
| 454 | bool fClient; | ||
| 455 | bool fInbound; | ||
| 456 | bool fNetworkNode; | ||
| 457 | bool fDisconnect; | ||
| 458 | protected: | ||
| 459 | int nRefCount; | ||
| 460 | public: | ||
| 461 | int64 nReleaseTime; | ||
| 462 | map<uint256, CRequestTracker> mapRequests; | ||
| 463 | CCriticalSection cs_mapRequests; | ||
| 464 | |||
| 465 | // flood | ||
| 466 | vector<CAddress> vAddrToSend; | ||
| 467 | set<CAddress> setAddrKnown; | ||
| 468 | |||
| 469 | // inventory based relay | ||
| 470 | set<CInv> setInventoryKnown; | ||
| 471 | set<CInv> setInventoryKnown2; | ||
| 472 | vector<CInv> vInventoryToSend; | ||
| 473 | CCriticalSection cs_inventory; | ||
| 474 | multimap<int64, CInv> mapAskFor; | ||
| 475 | |||
| 476 | // publish and subscription | ||
| 477 | vector<char> vfSubscribe; | ||
| 478 | |||
| 479 | |||
| 480 | CNode(SOCKET hSocketIn, CAddress addrIn, bool fInboundIn=false) | ||
| 481 | { | ||
| 482 | nServices = 0; | ||
| 483 | hSocket = hSocketIn; | ||
| 484 | vSend.SetType(SER_NETWORK); | ||
| 485 | vRecv.SetType(SER_NETWORK); | ||
| 486 | nPushPos = -1; | ||
| 487 | addr = addrIn; | ||
| 488 | nVersion = 0; | ||
| 489 | fClient = false; // set by version message | ||
| 490 | fInbound = fInboundIn; | ||
| 491 | fNetworkNode = false; | ||
| 492 | fDisconnect = false; | ||
| 493 | nRefCount = 0; | ||
| 494 | nReleaseTime = 0; | ||
| 495 | vfSubscribe.assign(256, false); | ||
| 496 | |||
| 497 | // Push a version message | ||
| 498 | /// when NTP implemented, change to just nTime = GetAdjustedTime() | ||
| 499 | int64 nTime = (fInbound ? GetAdjustedTime() : GetTime()); | ||
| 500 | PushMessage("version", VERSION, nLocalServices, nTime, addr); | ||
| 501 | } | ||
| 502 | |||
| 503 | ~CNode() | ||
| 504 | { | ||
| 505 | if (hSocket != INVALID_SOCKET) | ||
| 506 | closesocket(hSocket); | ||
| 507 | } | ||
| 508 | |||
| 509 | private: | ||
| 510 | CNode(const CNode&); | ||
| 511 | void operator=(const CNode&); | ||
| 512 | public: | ||
| 513 | |||
| 514 | |||
| 515 | bool ReadyToDisconnect() | ||
| 516 | { | ||
| 517 | return fDisconnect || GetRefCount() <= 0; | ||
| 518 | } | ||
| 519 | |||
| 520 | int GetRefCount() | ||
| 521 | { | ||
| 522 | return max(nRefCount, 0) + (GetTime() < nReleaseTime ? 1 : 0); | ||
| 523 | } | ||
| 524 | |||
| 525 | void AddRef(int64 nTimeout=0) | ||
| 526 | { | ||
| 527 | if (nTimeout != 0) | ||
| 528 | nReleaseTime = max(nReleaseTime, GetTime() + nTimeout); | ||
| 529 | else | ||
| 530 | nRefCount++; | ||
| 531 | } | ||
| 532 | |||
| 533 | void Release() | ||
| 534 | { | ||
| 535 | nRefCount--; | ||
| 536 | } | ||
| 537 | |||
| 538 | |||
| 539 | |||
| 540 | void AddInventoryKnown(const CInv& inv) | ||
| 541 | { | ||
| 542 | CRITICAL_BLOCK(cs_inventory) | ||
| 543 | setInventoryKnown.insert(inv); | ||
| 544 | } | ||
| 545 | |||
| 546 | void PushInventory(const CInv& inv) | ||
| 547 | { | ||
| 548 | CRITICAL_BLOCK(cs_inventory) | ||
| 549 | if (!setInventoryKnown.count(inv)) | ||
| 550 | vInventoryToSend.push_back(inv); | ||
| 551 | } | ||
| 552 | |||
| 553 | void AskFor(const CInv& inv) | ||
| 554 | { | ||
| 555 | // We're using mapAskFor as a priority queue, | ||
| 556 | // the key is the earliest time the request can be sent | ||
| 557 | int64& nRequestTime = mapAlreadyAskedFor[inv]; | ||
| 558 | printf("askfor %s %I64d\n", inv.ToString().c_str(), nRequestTime); | ||
| 559 | |||
| 560 | // Make sure not to reuse time indexes to keep things in the same order | ||
| 561 | int64 nNow = (GetTime() - 1) * 1000000; | ||
| 562 | static int64 nLastTime; | ||
| 563 | nLastTime = nNow = max(nNow, ++nLastTime); | ||
| 564 | |||
| 565 | // Each retry is 2 minutes after the last | ||
| 566 | nRequestTime = max(nRequestTime + 2 * 60 * 1000000, nNow); | ||
| 567 | mapAskFor.insert(make_pair(nRequestTime, inv)); | ||
| 568 | } | ||
| 569 | |||
| 570 | |||
| 571 | |||
| 572 | void BeginMessage(const char* pszCommand) | ||
| 573 | { | ||
| 574 | EnterCriticalSection(&cs_vSend); | ||
| 575 | if (nPushPos != -1) | ||
| 576 | AbortMessage(); | ||
| 577 | nPushPos = vSend.size(); | ||
| 578 | vSend << CMessageHeader(pszCommand, 0); | ||
| 579 | printf("sending: %-12s ", pszCommand); | ||
| 580 | } | ||
| 581 | |||
| 582 | void AbortMessage() | ||
| 583 | { | ||
| 584 | if (nPushPos == -1) | ||
| 585 | return; | ||
| 586 | vSend.resize(nPushPos); | ||
| 587 | nPushPos = -1; | ||
| 588 | LeaveCriticalSection(&cs_vSend); | ||
| 589 | printf("(aborted)\n"); | ||
| 590 | } | ||
| 591 | |||
| 592 | void EndMessage() | ||
| 593 | { | ||
| 594 | extern int nDropMessagesTest; | ||
| 595 | if (nDropMessagesTest > 0 && GetRand(nDropMessagesTest) == 0) | ||
| 596 | { | ||
| 597 | printf("dropmessages DROPPING SEND MESSAGE\n"); | ||
| 598 | AbortMessage(); | ||
| 599 | return; | ||
| 600 | } | ||
| 601 | |||
| 602 | if (nPushPos == -1) | ||
| 603 | return; | ||
| 604 | |||
| 605 | // Patch in the size | ||
| 606 | unsigned int nSize = vSend.size() - nPushPos - sizeof(CMessageHeader); | ||
| 607 | memcpy((char*)&vSend[nPushPos] + offsetof(CMessageHeader, nMessageSize), &nSize, sizeof(nSize)); | ||
| 608 | |||
| 609 | printf("(%d bytes) ", nSize); | ||
| 610 | //for (int i = nPushPos+sizeof(CMessageHeader); i < min(vSend.size(), nPushPos+sizeof(CMessageHeader)+20U); i++) | ||
| 611 | // printf("%02x ", vSend[i] & 0xff); | ||
| 612 | printf("\n"); | ||
| 613 | |||
| 614 | nPushPos = -1; | ||
| 615 | LeaveCriticalSection(&cs_vSend); | ||
| 616 | } | ||
| 617 | |||
| 618 | void EndMessageAbortIfEmpty() | ||
| 619 | { | ||
| 620 | if (nPushPos == -1) | ||
| 621 | return; | ||
| 622 | int nSize = vSend.size() - nPushPos - sizeof(CMessageHeader); | ||
| 623 | if (nSize > 0) | ||
| 624 | EndMessage(); | ||
| 625 | else | ||
| 626 | AbortMessage(); | ||
| 627 | } | ||
| 628 | |||
| 629 | const char* GetMessageCommand() const | ||
| 630 | { | ||
| 631 | if (nPushPos == -1) | ||
| 632 | return ""; | ||
| 633 | return &vSend[nPushPos] + offsetof(CMessageHeader, pchCommand); | ||
| 634 | } | ||
| 635 | |||
| 636 | |||
| 637 | |||
| 638 | |||
| 639 | void PushMessage(const char* pszCommand) | ||
| 640 | { | ||
| 641 | try | ||
| 642 | { | ||
| 643 | BeginMessage(pszCommand); | ||
| 644 | EndMessage(); | ||
| 645 | } | ||
| 646 | catch (...) | ||
| 647 | { | ||
| 648 | AbortMessage(); | ||
| 649 | throw; | ||
| 650 | } | ||
| 651 | } | ||
| 652 | |||
| 653 | template<typename T1> | ||
| 654 | void PushMessage(const char* pszCommand, const T1& a1) | ||
| 655 | { | ||
| 656 | try | ||
| 657 | { | ||
| 658 | BeginMessage(pszCommand); | ||
| 659 | vSend << a1; | ||
| 660 | EndMessage(); | ||
| 661 | } | ||
| 662 | catch (...) | ||
| 663 | { | ||
| 664 | AbortMessage(); | ||
| 665 | throw; | ||
| 666 | } | ||
| 667 | } | ||
| 668 | |||
| 669 | template<typename T1, typename T2> | ||
| 670 | void PushMessage(const char* pszCommand, const T1& a1, const T2& a2) | ||
| 671 | { | ||
| 672 | try | ||
| 673 | { | ||
| 674 | BeginMessage(pszCommand); | ||
| 675 | vSend << a1 << a2; | ||
| 676 | EndMessage(); | ||
| 677 | } | ||
| 678 | catch (...) | ||
| 679 | { | ||
| 680 | AbortMessage(); | ||
| 681 | throw; | ||
| 682 | } | ||
| 683 | } | ||
| 684 | |||
| 685 | template<typename T1, typename T2, typename T3> | ||
| 686 | void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3) | ||
| 687 | { | ||
| 688 | try | ||
| 689 | { | ||
| 690 | BeginMessage(pszCommand); | ||
| 691 | vSend << a1 << a2 << a3; | ||
| 692 | EndMessage(); | ||
| 693 | } | ||
| 694 | catch (...) | ||
| 695 | { | ||
| 696 | AbortMessage(); | ||
| 697 | throw; | ||
| 698 | } | ||
| 699 | } | ||
| 700 | |||
| 701 | template<typename T1, typename T2, typename T3, typename T4> | ||
| 702 | void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4) | ||
| 703 | { | ||
| 704 | try | ||
| 705 | { | ||
| 706 | BeginMessage(pszCommand); | ||
| 707 | vSend << a1 << a2 << a3 << a4; | ||
| 708 | EndMessage(); | ||
| 709 | } | ||
| 710 | catch (...) | ||
| 711 | { | ||
| 712 | AbortMessage(); | ||
| 713 | throw; | ||
| 714 | } | ||
| 715 | } | ||
| 716 | |||
| 717 | |||
| 718 | void PushRequest(const char* pszCommand, | ||
| 719 | void (*fn)(void*, CDataStream&), void* param1) | ||
| 720 | { | ||
| 721 | uint256 hashReply; | ||
| 722 | RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply)); | ||
| 723 | |||
| 724 | CRITICAL_BLOCK(cs_mapRequests) | ||
| 725 | mapRequests[hashReply] = CRequestTracker(fn, param1); | ||
| 726 | |||
| 727 | PushMessage(pszCommand, hashReply); | ||
| 728 | } | ||
| 729 | |||
| 730 | template<typename T1> | ||
| 731 | void PushRequest(const char* pszCommand, const T1& a1, | ||
| 732 | void (*fn)(void*, CDataStream&), void* param1) | ||
| 733 | { | ||
| 734 | uint256 hashReply; | ||
| 735 | RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply)); | ||
| 736 | |||
| 737 | CRITICAL_BLOCK(cs_mapRequests) | ||
| 738 | mapRequests[hashReply] = CRequestTracker(fn, param1); | ||
| 739 | |||
| 740 | PushMessage(pszCommand, hashReply, a1); | ||
| 741 | } | ||
| 742 | |||
| 743 | template<typename T1, typename T2> | ||
| 744 | void PushRequest(const char* pszCommand, const T1& a1, const T2& a2, | ||
| 745 | void (*fn)(void*, CDataStream&), void* param1) | ||
| 746 | { | ||
| 747 | uint256 hashReply; | ||
| 748 | RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply)); | ||
| 749 | |||
| 750 | CRITICAL_BLOCK(cs_mapRequests) | ||
| 751 | mapRequests[hashReply] = CRequestTracker(fn, param1); | ||
| 752 | |||
| 753 | PushMessage(pszCommand, hashReply, a1, a2); | ||
| 754 | } | ||
| 755 | |||
| 756 | |||
| 757 | |||
| 758 | bool IsSubscribed(unsigned int nChannel); | ||
| 759 | void Subscribe(unsigned int nChannel, unsigned int nHops=0); | ||
| 760 | void CancelSubscribe(unsigned int nChannel); | ||
| 761 | void Disconnect(); | ||
| 762 | }; | ||
| 763 | |||
| 764 | |||
| 765 | |||
| 766 | |||
| 767 | |||
| 768 | |||
| 769 | |||
| 770 | |||
| 771 | |||
| 772 | |||
| 773 | inline void RelayInventory(const CInv& inv) | ||
| 774 | { | ||
| 775 | // Put on lists to offer to the other nodes | ||
| 776 | CRITICAL_BLOCK(cs_vNodes) | ||
| 777 | foreach(CNode* pnode, vNodes) | ||
| 778 | pnode->PushInventory(inv); | ||
| 779 | } | ||
| 780 | |||
| 781 | template<typename T> | ||
| 782 | void RelayMessage(const CInv& inv, const T& a) | ||
| 783 | { | ||
| 784 | CDataStream ss(SER_NETWORK); | ||
| 785 | ss.reserve(10000); | ||
| 786 | ss << a; | ||
| 787 | RelayMessage(inv, ss); | ||
| 788 | } | ||
| 789 | |||
| 790 | template<> | ||
| 791 | inline void RelayMessage<>(const CInv& inv, const CDataStream& ss) | ||
| 792 | { | ||
| 793 | CRITICAL_BLOCK(cs_mapRelay) | ||
| 794 | { | ||
| 795 | // Expire old relay messages | ||
| 796 | while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime()) | ||
| 797 | { | ||
| 798 | mapRelay.erase(vRelayExpiration.front().second); | ||
| 799 | vRelayExpiration.pop_front(); | ||
| 800 | } | ||
| 801 | |||
| 802 | // Save original serialized message so newer versions are preserved | ||
| 803 | mapRelay[inv] = ss; | ||
| 804 | vRelayExpiration.push_back(make_pair(GetTime() + 15 * 60, inv)); | ||
| 805 | } | ||
| 806 | |||
| 807 | RelayInventory(inv); | ||
| 808 | } | ||
| 809 | |||
| 810 | |||
| 811 | |||
| 812 | |||
| 813 | |||
| 814 | |||
| 815 | |||
| 816 | |||
| 817 | // | ||
| 818 | // Templates for the publish and subscription system. | ||
| 819 | // The object being published as T& obj needs to have: | ||
| 820 | // a set<unsigned int> setSources member | ||
| 821 | // specializations of AdvertInsert and AdvertErase | ||
| 822 | // Currently implemented for CTable and CProduct. | ||
| 823 | // | ||
| 824 | |||
| 825 | template<typename T> | ||
| 826 | void AdvertStartPublish(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj) | ||
| 827 | { | ||
| 828 | // Add to sources | ||
| 829 | obj.setSources.insert(pfrom->addr.ip); | ||
| 830 | |||
| 831 | if (!AdvertInsert(obj)) | ||
| 832 | return; | ||
| 833 | |||
| 834 | // Relay | ||
| 835 | CRITICAL_BLOCK(cs_vNodes) | ||
| 836 | foreach(CNode* pnode, vNodes) | ||
| 837 | if (pnode != pfrom && (nHops < PUBLISH_HOPS || pnode->IsSubscribed(nChannel))) | ||
| 838 | pnode->PushMessage("publish", nChannel, nHops, obj); | ||
| 839 | } | ||
| 840 | |||
| 841 | template<typename T> | ||
| 842 | void AdvertStopPublish(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj) | ||
| 843 | { | ||
| 844 | uint256 hash = obj.GetHash(); | ||
| 845 | |||
| 846 | CRITICAL_BLOCK(cs_vNodes) | ||
| 847 | foreach(CNode* pnode, vNodes) | ||
| 848 | if (pnode != pfrom && (nHops < PUBLISH_HOPS || pnode->IsSubscribed(nChannel))) | ||
| 849 | pnode->PushMessage("pub-cancel", nChannel, nHops, hash); | ||
| 850 | |||
| 851 | AdvertErase(obj); | ||
| 852 | } | ||
| 853 | |||
| 854 | template<typename T> | ||
| 855 | void AdvertRemoveSource(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj) | ||
| 856 | { | ||
| 857 | // Remove a source | ||
| 858 | obj.setSources.erase(pfrom->addr.ip); | ||
| 859 | |||
| 860 | // If no longer supported by any sources, cancel it | ||
| 861 | if (obj.setSources.empty()) | ||
| 862 | AdvertStopPublish(pfrom, nChannel, nHops, obj); | ||
| 863 | } | ||
diff --git a/src/nostr.cpp b/src/nostr.cpp new file mode 100644 index 0000000..8e2a07d --- /dev/null +++ b/src/nostr.cpp | |||
| @@ -0,0 +1,838 @@ | |||
| 1 | // Copyright (c) 2026 Bitflash developers | ||
| 2 | // Distributed under the MIT/X11 software license. | ||
| 3 | // | ||
| 4 | // Peer discovery over Nostr relays. See nostr.h. | ||
| 5 | |||
| 6 | #include "headers.h" | ||
| 7 | #include <openssl/ssl.h> | ||
| 8 | #include <openssl/err.h> | ||
| 9 | // We link libsecp256k1 statically (without this the header assumes DLL import) | ||
| 10 | #define SECP256K1_STATIC | ||
| 11 | #include <secp256k1.h> | ||
| 12 | #include <secp256k1_schnorrsig.h> | ||
| 13 | #include <secp256k1_extrakeys.h> | ||
| 14 | |||
| 15 | // util.h redefines snprintf as a macro (2009 MSVC compat); this breaks | ||
| 16 | // nlohmann/json, which calls std::snprintf. Undo the macro just here. | ||
| 17 | #ifdef snprintf | ||
| 18 | #undef snprintf | ||
| 19 | #endif | ||
| 20 | #include <nlohmann/json.hpp> | ||
| 21 | |||
| 22 | #include "btfaddr.h" | ||
| 23 | #include "btfchan.h" | ||
| 24 | |||
| 25 | using json = nlohmann::json; | ||
| 26 | |||
| 27 | // Bitflash rendezvous descriptor: parameterized-replaceable Nostr event so each | ||
| 28 | // node keeps exactly one current descriptor (keyed by author pubkey). | ||
| 29 | static const int BTF_DESC_KIND = 38501; | ||
| 30 | // "-2" scopes the 2026 stable relaunch: new nodes discover only each other, and | ||
| 31 | // the abandoned test .btf descriptors lingering on the relays become invisible. | ||
| 32 | static const char* BTF_DESC_DTAG = "btf-descriptor-2"; | ||
| 33 | |||
| 34 | // Nostr network/scope for Bitflash. Events are replaceable (NIP-78). | ||
| 35 | static const int NOSTR_KIND = 30078; | ||
| 36 | static const char* NOSTR_DTAG = "bitflash-mainnet-2"; | ||
| 37 | |||
| 38 | // Anonymous auto-discovery: how many peers to keep connected via .btf rendezvous | ||
| 39 | // before we stop dialing more, and how many new dials to attempt per cycle. | ||
| 40 | static const unsigned int BTF_TARGET_CONN = 8; | ||
| 41 | static const int BTF_DIALS_PER_PASS = 4; | ||
| 42 | |||
| 43 | // Other nodes' .btf addresses learned from their descriptors on the relays. | ||
| 44 | static set<string> g_btfPeers; | ||
| 45 | static CCriticalSection cs_btfPeers; | ||
| 46 | |||
| 47 | // Public discovery relays. Tunable. | ||
| 48 | const char* pszNostrRelays[] = { | ||
| 49 | "wss://relay.damus.io", | ||
| 50 | "wss://nos.lol", | ||
| 51 | "wss://relay.nostr.band", | ||
| 52 | "wss://relay.snort.social", | ||
| 53 | }; | ||
| 54 | const int nNostrRelays = ARRAYLEN(pszNostrRelays); | ||
| 55 | |||
| 56 | // Rendezvous meeting relay this node registers at (ThreadBtfAccept in net.cpp) | ||
| 57 | // and advertises in its .btf descriptor. Seed default; /rvrelay overrides. | ||
| 58 | string strBtfMeetingRelay = "90.156.222.107:8434"; | ||
| 59 | |||
| 60 | |||
| 61 | // | ||
| 62 | // Utilities | ||
| 63 | // | ||
| 64 | static string HexEncode(const unsigned char* p, size_t n) | ||
| 65 | { | ||
| 66 | static const char* h = "0123456789abcdef"; | ||
| 67 | string s; | ||
| 68 | s.reserve(n * 2); | ||
| 69 | for (size_t i = 0; i < n; i++) | ||
| 70 | { | ||
| 71 | s += h[p[i] >> 4]; | ||
| 72 | s += h[p[i] & 0xf]; | ||
| 73 | } | ||
| 74 | return s; | ||
| 75 | } | ||
| 76 | |||
| 77 | static bool HexDecode(const string& s, unsigned char* out, size_t n) | ||
| 78 | { | ||
| 79 | if (s.size() != n * 2) | ||
| 80 | return false; | ||
| 81 | for (size_t i = 0; i < n; i++) | ||
| 82 | { | ||
| 83 | unsigned int b; | ||
| 84 | if (sscanf(s.c_str() + i * 2, "%2x", &b) != 1) | ||
| 85 | return false; | ||
| 86 | out[i] = (unsigned char)b; | ||
| 87 | } | ||
| 88 | return true; | ||
| 89 | } | ||
| 90 | |||
| 91 | static string Base64Encode(const unsigned char* p, size_t n) | ||
| 92 | { | ||
| 93 | static const char* tbl = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | ||
| 94 | string s; | ||
| 95 | for (size_t i = 0; i < n; i += 3) | ||
| 96 | { | ||
| 97 | unsigned int b = p[i] << 16; | ||
| 98 | if (i + 1 < n) b |= p[i + 1] << 8; | ||
| 99 | if (i + 2 < n) b |= p[i + 2]; | ||
| 100 | s += tbl[(b >> 18) & 0x3f]; | ||
| 101 | s += tbl[(b >> 12) & 0x3f]; | ||
| 102 | s += (i + 1 < n) ? tbl[(b >> 6) & 0x3f] : '='; | ||
| 103 | s += (i + 2 < n) ? tbl[b & 0x3f] : '='; | ||
| 104 | } | ||
| 105 | return s; | ||
| 106 | } | ||
| 107 | |||
| 108 | |||
| 109 | // | ||
| 110 | // Node Nostr key -- secp256k1 x-only (BIP340), persisted in <appdir>/nostr.key | ||
| 111 | // | ||
| 112 | class CNostrKey | ||
| 113 | { | ||
| 114 | public: | ||
| 115 | secp256k1_context* ctx; | ||
| 116 | secp256k1_keypair keypair; | ||
| 117 | unsigned char seckey[32]; // node's secp256k1 secret (for descriptor signing) | ||
| 118 | unsigned char xonly[32]; // node's x-only pubkey (also its .btf identity) | ||
| 119 | unsigned char enc_pk[32]; // node's x25519 public key (echan `enc` field) | ||
| 120 | unsigned char enc_sk[32]; // node's x25519 secret key | ||
| 121 | bool fValid; | ||
| 122 | |||
| 123 | CNostrKey() : ctx(NULL), fValid(false) {} | ||
| 124 | |||
| 125 | ~CNostrKey() | ||
| 126 | { | ||
| 127 | if (ctx) secp256k1_context_destroy(ctx); | ||
| 128 | } | ||
| 129 | |||
| 130 | // Load or generate a 32-byte key persisted as hex in <appdir>/<name>. | ||
| 131 | static void LoadOrGenSecp(secp256k1_context* ctx, const string& file, unsigned char sk[32]) | ||
| 132 | { | ||
| 133 | FILE* f = fopen(file.c_str(), "rb"); | ||
| 134 | string strHex; | ||
| 135 | if (f) { char buf[65] = {0}; fread(buf, 1, 64, f); fclose(f); strHex = buf; } | ||
| 136 | if (!HexDecode(strHex, sk, 32) || !secp256k1_ec_seckey_verify(ctx, sk)) | ||
| 137 | { | ||
| 138 | do { RAND_bytes(sk, sizeof(unsigned char) * 32); } while (!secp256k1_ec_seckey_verify(ctx, sk)); | ||
| 139 | FILE* fw = fopen(file.c_str(), "wb"); | ||
| 140 | if (fw) { string h = HexEncode(sk, 32); fwrite(h.c_str(), 1, h.size(), fw); fclose(fw); } | ||
| 141 | } | ||
| 142 | } | ||
| 143 | |||
| 144 | bool Init() | ||
| 145 | { | ||
| 146 | ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); | ||
| 147 | if (!ctx) | ||
| 148 | return false; | ||
| 149 | unsigned char seed[32]; | ||
| 150 | RAND_bytes(seed, sizeof(seed)); | ||
| 151 | secp256k1_context_randomize(ctx, seed); | ||
| 152 | |||
| 153 | LoadOrGenSecp(ctx, GetAppDir() + "/nostr.key", seckey); | ||
| 154 | |||
| 155 | if (!secp256k1_keypair_create(ctx, &keypair, seckey)) | ||
| 156 | return false; | ||
| 157 | secp256k1_xonly_pubkey xpub; | ||
| 158 | if (!secp256k1_keypair_xonly_pub(ctx, &xpub, NULL, &keypair)) | ||
| 159 | return false; | ||
| 160 | secp256k1_xonly_pubkey_serialize(ctx, xonly, &xpub); | ||
| 161 | |||
| 162 | // x25519 encryption keypair for the end-to-end channel, persisted separately. | ||
| 163 | btf::ChanInit(); | ||
| 164 | string strEncFile = GetAppDir() + "/btf_enc.key"; | ||
| 165 | FILE* fe = fopen(strEncFile.c_str(), "rb"); | ||
| 166 | bool fLoaded = false; | ||
| 167 | if (fe) | ||
| 168 | { | ||
| 169 | char buf[65] = {0}; | ||
| 170 | if (fread(buf, 1, 64, fe) == 64 && HexDecode(string(buf), enc_sk, 32)) | ||
| 171 | fLoaded = true; | ||
| 172 | fclose(fe); | ||
| 173 | } | ||
| 174 | if (fLoaded) | ||
| 175 | { | ||
| 176 | // Derive the public key from the stored secret (stable identity). | ||
| 177 | btf::ChanPublicFromSecret(enc_pk, enc_sk); | ||
| 178 | } | ||
| 179 | else | ||
| 180 | { | ||
| 181 | btf::ChanKeypair(enc_pk, enc_sk); | ||
| 182 | FILE* few = fopen(strEncFile.c_str(), "wb"); | ||
| 183 | if (few) { string h = HexEncode(enc_sk, 32); fwrite(h.c_str(), 1, h.size(), few); fclose(few); } | ||
| 184 | } | ||
| 185 | |||
| 186 | fValid = true; | ||
| 187 | return true; | ||
| 188 | } | ||
| 189 | |||
| 190 | string PubKeyHex() const { return HexEncode(xonly, 32); } | ||
| 191 | string EncPubHex() const { return HexEncode(enc_pk, 32); } | ||
| 192 | string BtfAddress() const { return btf::Address(xonly); } | ||
| 193 | |||
| 194 | bool SignId(const unsigned char id[32], string& sigHexOut) | ||
| 195 | { | ||
| 196 | unsigned char sig[64]; | ||
| 197 | unsigned char aux[32]; | ||
| 198 | RAND_bytes(aux, sizeof(aux)); | ||
| 199 | if (!secp256k1_schnorrsig_sign32(ctx, sig, id, &keypair, aux)) | ||
| 200 | return false; | ||
| 201 | sigHexOut = HexEncode(sig, 64); | ||
| 202 | return true; | ||
| 203 | } | ||
| 204 | }; | ||
| 205 | |||
| 206 | // The node's single Nostr/.btf identity, shared by the seeding thread here and | ||
| 207 | // the rendezvous transport in net.cpp. Lazily initialized under a lock; the | ||
| 208 | // secp256k1 context is immutable after Init, so concurrent use is safe. | ||
| 209 | static CNostrKey g_nostrKey; | ||
| 210 | static CCriticalSection cs_nostrKey; | ||
| 211 | |||
| 212 | static bool EnsureNostrKey() | ||
| 213 | { | ||
| 214 | CRITICAL_BLOCK(cs_nostrKey) | ||
| 215 | if (!g_nostrKey.fValid) | ||
| 216 | g_nostrKey.Init(); | ||
| 217 | return g_nostrKey.fValid; | ||
| 218 | } | ||
| 219 | |||
| 220 | bool BtfGetIdentity(unsigned char pubkey[32], unsigned char enc_sk[32]) | ||
| 221 | { | ||
| 222 | if (!EnsureNostrKey()) | ||
| 223 | return false; | ||
| 224 | memcpy(pubkey, g_nostrKey.xonly, 32); | ||
| 225 | memcpy(enc_sk, g_nostrKey.enc_sk, 32); | ||
| 226 | return true; | ||
| 227 | } | ||
| 228 | |||
| 229 | std::string BtfLocalAddress() | ||
| 230 | { | ||
| 231 | if (!EnsureNostrKey()) | ||
| 232 | return ""; | ||
| 233 | return g_nostrKey.BtfAddress(); | ||
| 234 | } | ||
| 235 | |||
| 236 | |||
| 237 | // Build and sign a Nostr event (NIP-01). Returns the event JSON. | ||
| 238 | static bool BuildSignedEvent(CNostrKey& key, int kind, const json& tags, | ||
| 239 | const string& content, json& eventOut) | ||
| 240 | { | ||
| 241 | int64 created = GetTime(); | ||
| 242 | // Canonical serialization for the id: [0,pubkey,created_at,kind,tags,content] | ||
| 243 | json ser = json::array({ 0, key.PubKeyHex(), created, kind, tags, content }); | ||
| 244 | string s = ser.dump(); | ||
| 245 | |||
| 246 | unsigned char id[32]; | ||
| 247 | SHA256((const unsigned char*)s.data(), s.size(), id); | ||
| 248 | |||
| 249 | string sigHex; | ||
| 250 | if (!key.SignId(id, sigHex)) | ||
| 251 | return false; | ||
| 252 | |||
| 253 | eventOut = json::object(); | ||
| 254 | eventOut["id"] = HexEncode(id, 32); | ||
| 255 | eventOut["pubkey"] = key.PubKeyHex(); | ||
| 256 | eventOut["created_at"] = created; | ||
| 257 | eventOut["kind"] = kind; | ||
| 258 | eventOut["tags"] = tags; | ||
| 259 | eventOut["content"] = content; | ||
| 260 | eventOut["sig"] = sigHex; | ||
| 261 | return true; | ||
| 262 | } | ||
| 263 | |||
| 264 | |||
| 265 | // | ||
| 266 | // Minimal WebSocket client over TLS (wss) or TCP (ws), blocking with timeout. | ||
| 267 | // | ||
| 268 | class CWebSocket | ||
| 269 | { | ||
| 270 | public: | ||
| 271 | SOCKET hSocket; | ||
| 272 | SSL_CTX* sslctx; | ||
| 273 | SSL* ssl; | ||
| 274 | bool fTls; | ||
| 275 | string recvbuf; | ||
| 276 | |||
| 277 | CWebSocket() : hSocket(INVALID_SOCKET), sslctx(NULL), ssl(NULL), fTls(false) {} | ||
| 278 | ~CWebSocket() { Close(); } | ||
| 279 | |||
| 280 | void Close() | ||
| 281 | { | ||
| 282 | if (ssl) { SSL_shutdown(ssl); SSL_free(ssl); ssl = NULL; } | ||
| 283 | if (sslctx) { SSL_CTX_free(sslctx); sslctx = NULL; } | ||
| 284 | if (hSocket != INVALID_SOCKET) { closesocket(hSocket); hSocket = INVALID_SOCKET; } | ||
| 285 | } | ||
| 286 | |||
| 287 | int RawRead(char* buf, int len) | ||
| 288 | { | ||
| 289 | if (fTls) return SSL_read(ssl, buf, len); | ||
| 290 | return recv(hSocket, buf, len, 0); | ||
| 291 | } | ||
| 292 | |||
| 293 | bool RawWrite(const char* buf, int len) | ||
| 294 | { | ||
| 295 | int off = 0; | ||
| 296 | while (off < len) | ||
| 297 | { | ||
| 298 | int n = fTls ? SSL_write(ssl, buf + off, len - off) | ||
| 299 | : send(hSocket, buf + off, len - off, 0); | ||
| 300 | if (n <= 0) return false; | ||
| 301 | off += n; | ||
| 302 | } | ||
| 303 | return true; | ||
| 304 | } | ||
| 305 | |||
| 306 | // Connect and perform the WebSocket handshake. url = wss://host[:port]/path | ||
| 307 | bool Connect(const string& url, int timeoutSec) | ||
| 308 | { | ||
| 309 | string u = url; | ||
| 310 | int port = 443; | ||
| 311 | fTls = true; | ||
| 312 | if (u.compare(0, 6, "wss://") == 0) { u = u.substr(6); fTls = true; port = 443; } | ||
| 313 | else if (u.compare(0, 5, "ws://") == 0) { u = u.substr(5); fTls = false; port = 80; } | ||
| 314 | else return false; | ||
| 315 | |||
| 316 | string host, path = "/"; | ||
| 317 | size_t slash = u.find('/'); | ||
| 318 | if (slash != string::npos) { host = u.substr(0, slash); path = u.substr(slash); } | ||
| 319 | else host = u; | ||
| 320 | size_t colon = host.find(':'); | ||
| 321 | if (colon != string::npos) { port = atoi(host.substr(colon + 1).c_str()); host = host.substr(0, colon); } | ||
| 322 | |||
| 323 | // Resolve and connect (TCP) | ||
| 324 | struct addrinfo hints, *res = NULL; | ||
| 325 | memset(&hints, 0, sizeof(hints)); | ||
| 326 | hints.ai_family = AF_INET; | ||
| 327 | hints.ai_socktype = SOCK_STREAM; | ||
| 328 | char portstr[16]; sprintf(portstr, "%d", port); | ||
| 329 | if (getaddrinfo(host.c_str(), portstr, &hints, &res) != 0 || !res) | ||
| 330 | return error("Nostr: getaddrinfo %s failed", host.c_str()); | ||
| 331 | hSocket = socket(res->ai_family, res->ai_socktype, res->ai_protocol); | ||
| 332 | if (hSocket == INVALID_SOCKET) { freeaddrinfo(res); return false; } | ||
| 333 | |||
| 334 | // Socket receive/send timeout: Windows takes a DWORD of milliseconds; | ||
| 335 | // POSIX takes a struct timeval. | ||
| 336 | #ifdef _WIN32 | ||
| 337 | DWORD tv = timeoutSec * 1000; | ||
| 338 | setsockopt(hSocket, SOL_SOCKET, SO_RCVTIMEO, (char*)&tv, sizeof(tv)); | ||
| 339 | setsockopt(hSocket, SOL_SOCKET, SO_SNDTIMEO, (char*)&tv, sizeof(tv)); | ||
| 340 | #else | ||
| 341 | struct timeval tv; | ||
| 342 | tv.tv_sec = timeoutSec; | ||
| 343 | tv.tv_usec = 0; | ||
| 344 | setsockopt(hSocket, SOL_SOCKET, SO_RCVTIMEO, (char*)&tv, sizeof(tv)); | ||
| 345 | setsockopt(hSocket, SOL_SOCKET, SO_SNDTIMEO, (char*)&tv, sizeof(tv)); | ||
| 346 | #endif | ||
| 347 | |||
| 348 | if (connect(hSocket, res->ai_addr, (int)res->ai_addrlen) != 0) | ||
| 349 | { | ||
| 350 | freeaddrinfo(res); | ||
| 351 | return error("Nostr: connect %s:%d failed", host.c_str(), port); | ||
| 352 | } | ||
| 353 | freeaddrinfo(res); | ||
| 354 | |||
| 355 | // TLS | ||
| 356 | if (fTls) | ||
| 357 | { | ||
| 358 | sslctx = SSL_CTX_new(TLS_client_method()); | ||
| 359 | if (!sslctx) return false; | ||
| 360 | ssl = SSL_new(sslctx); | ||
| 361 | SSL_set_fd(ssl, (int)hSocket); | ||
| 362 | SSL_set_tlsext_host_name(ssl, host.c_str()); // SNI | ||
| 363 | if (SSL_connect(ssl) != 1) | ||
| 364 | return error("Nostr: TLS handshake with %s failed", host.c_str()); | ||
| 365 | } | ||
| 366 | |||
| 367 | // WebSocket handshake (HTTP Upgrade) | ||
| 368 | unsigned char keybytes[16]; | ||
| 369 | RAND_bytes(keybytes, sizeof(keybytes)); | ||
| 370 | string wskey = Base64Encode(keybytes, sizeof(keybytes)); | ||
| 371 | string req = | ||
| 372 | "GET " + path + " HTTP/1.1\r\n" | ||
| 373 | "Host: " + host + "\r\n" | ||
| 374 | "Upgrade: websocket\r\n" | ||
| 375 | "Connection: Upgrade\r\n" | ||
| 376 | "Sec-WebSocket-Key: " + wskey + "\r\n" | ||
| 377 | "Sec-WebSocket-Version: 13\r\n\r\n"; | ||
| 378 | if (!RawWrite(req.data(), (int)req.size())) | ||
| 379 | return false; | ||
| 380 | |||
| 381 | // Read the handshake response until \r\n\r\n | ||
| 382 | string resp; | ||
| 383 | char c; | ||
| 384 | while (resp.find("\r\n\r\n") == string::npos) | ||
| 385 | { | ||
| 386 | int n = RawRead(&c, 1); | ||
| 387 | if (n <= 0) return error("Nostr: no handshake response from %s", host.c_str()); | ||
| 388 | resp += c; | ||
| 389 | if (resp.size() > 4096) break; | ||
| 390 | } | ||
| 391 | if (resp.find(" 101 ") == string::npos) | ||
| 392 | return error("Nostr: handshake refused by %s", host.c_str()); | ||
| 393 | return true; | ||
| 394 | } | ||
| 395 | |||
| 396 | // Send a text message (masked frame, as required by the protocol) | ||
| 397 | bool SendText(const string& msg) | ||
| 398 | { | ||
| 399 | string frame; | ||
| 400 | frame += (char)0x81; // FIN + opcode texto | ||
| 401 | size_t len = msg.size(); | ||
| 402 | if (len < 126) | ||
| 403 | frame += (char)(0x80 | len); | ||
| 404 | else if (len <= 0xffff) | ||
| 405 | { | ||
| 406 | frame += (char)(0x80 | 126); | ||
| 407 | frame += (char)((len >> 8) & 0xff); | ||
| 408 | frame += (char)(len & 0xff); | ||
| 409 | } | ||
| 410 | else | ||
| 411 | { | ||
| 412 | frame += (char)(0x80 | 127); | ||
| 413 | for (int i = 7; i >= 0; i--) frame += (char)((len >> (8 * i)) & 0xff); | ||
| 414 | } | ||
| 415 | unsigned char mask[4]; | ||
| 416 | RAND_bytes(mask, 4); | ||
| 417 | frame.append((char*)mask, 4); | ||
| 418 | string masked = msg; | ||
| 419 | for (size_t i = 0; i < masked.size(); i++) | ||
| 420 | masked[i] ^= mask[i & 3]; | ||
| 421 | frame += masked; | ||
| 422 | return RawWrite(frame.data(), (int)frame.size()); | ||
| 423 | } | ||
| 424 | |||
| 425 | // Receive the next complete text message. Returns false on error/timeout. | ||
| 426 | bool RecvText(string& out) | ||
| 427 | { | ||
| 428 | out.clear(); | ||
| 429 | for (;;) | ||
| 430 | { | ||
| 431 | unsigned char hdr[2]; | ||
| 432 | if (!ReadN((char*)hdr, 2)) return false; | ||
| 433 | bool fin = hdr[0] & 0x80; | ||
| 434 | int opcode = hdr[0] & 0x0f; | ||
| 435 | bool masked = hdr[1] & 0x80; | ||
| 436 | uint64 len = hdr[1] & 0x7f; | ||
| 437 | if (len == 126) | ||
| 438 | { | ||
| 439 | unsigned char e[2]; | ||
| 440 | if (!ReadN((char*)e, 2)) return false; | ||
| 441 | len = (e[0] << 8) | e[1]; | ||
| 442 | } | ||
| 443 | else if (len == 127) | ||
| 444 | { | ||
| 445 | unsigned char e[8]; | ||
| 446 | if (!ReadN((char*)e, 8)) return false; | ||
| 447 | len = 0; | ||
| 448 | for (int i = 0; i < 8; i++) len = (len << 8) | e[i]; | ||
| 449 | } | ||
| 450 | unsigned char mask[4] = {0,0,0,0}; | ||
| 451 | if (masked && !ReadN((char*)mask, 4)) return false; | ||
| 452 | |||
| 453 | string payload; | ||
| 454 | payload.resize((size_t)len); | ||
| 455 | if (len && !ReadN(&payload[0], (int)len)) return false; | ||
| 456 | if (masked) | ||
| 457 | for (size_t i = 0; i < payload.size(); i++) | ||
| 458 | payload[i] ^= mask[i & 3]; | ||
| 459 | |||
| 460 | if (opcode == 0x8) return false; // close | ||
| 461 | if (opcode == 0x9) { SendPong(payload); continue; } // ping | ||
| 462 | if (opcode == 0xA) continue; // pong | ||
| 463 | out += payload; // text/continuation | ||
| 464 | if (fin) return true; | ||
| 465 | } | ||
| 466 | } | ||
| 467 | |||
| 468 | private: | ||
| 469 | bool ReadN(char* buf, int n) | ||
| 470 | { | ||
| 471 | int off = 0; | ||
| 472 | while (off < n) | ||
| 473 | { | ||
| 474 | int r = RawRead(buf + off, n - off); | ||
| 475 | if (r <= 0) return false; | ||
| 476 | off += r; | ||
| 477 | } | ||
| 478 | return true; | ||
| 479 | } | ||
| 480 | |||
| 481 | void SendPong(const string& payload) | ||
| 482 | { | ||
| 483 | string frame; | ||
| 484 | frame += (char)0x8A; | ||
| 485 | frame += (char)(0x80 | (payload.size() & 0x7f)); | ||
| 486 | unsigned char mask[4]; RAND_bytes(mask, 4); | ||
| 487 | frame.append((char*)mask, 4); | ||
| 488 | string m = payload; | ||
| 489 | for (size_t i = 0; i < m.size(); i++) m[i] ^= mask[i & 3]; | ||
| 490 | frame += m; | ||
| 491 | RawWrite(frame.data(), (int)frame.size()); | ||
| 492 | } | ||
| 493 | }; | ||
| 494 | |||
| 495 | |||
| 496 | // Handle a received event: extract "ip:port" and register the address. | ||
| 497 | static void HandlePeerEvent(const json& ev) | ||
| 498 | { | ||
| 499 | if (!ev.contains("content")) return; | ||
| 500 | string content = ev["content"].get<string>(); | ||
| 501 | // expected content: "ip:port" | ||
| 502 | CAddress addr(content.c_str()); | ||
| 503 | if (addr.ip == 0 || addr.ip == INADDR_NONE) | ||
| 504 | return; | ||
| 505 | if (addr.ip == addrLocalHost.ip && addr.port == addrLocalHost.port) | ||
| 506 | return; // not ourselves (same ip:port) | ||
| 507 | // Peer received from the relay (before AddAddress's routability filter). | ||
| 508 | printf("Nostr: peer received from relay: %s\n", addr.ToStringIPPort().c_str()); | ||
| 509 | CAddrDB addrdb; | ||
| 510 | if (AddAddress(addrdb, addr)) | ||
| 511 | printf("Nostr: new peer added %s\n", addr.ToStringIPPort().c_str()); | ||
| 512 | } | ||
| 513 | |||
| 514 | |||
| 515 | // Publish this node's self-certifying `.btf` descriptor: "reach me (this key) | ||
| 516 | // via <meeting_node>, encrypting to my x25519 key <enc>". Signed by the node | ||
| 517 | // key so only the address's owner can publish it (no hijacking). | ||
| 518 | static void PublishDescriptor(CWebSocket& ws, CNostrKey& key) | ||
| 519 | { | ||
| 520 | // meeting_node is the rendezvous relay this node's hidden service | ||
| 521 | // (ThreadBtfAccept in net.cpp) is registered at -- where clients dial us. | ||
| 522 | string meeting_node = strBtfMeetingRelay.empty() ? "rendezvous-pending" | ||
| 523 | : strBtfMeetingRelay; | ||
| 524 | string desc = btf::SignDescriptor(key.ctx, key.seckey, key.EncPubHex(), | ||
| 525 | meeting_node, (uint64_t)GetTime()); | ||
| 526 | if (desc.empty()) | ||
| 527 | return; | ||
| 528 | json tags = json::array({ json::array({ "d", BTF_DESC_DTAG }) }); | ||
| 529 | json ev; | ||
| 530 | if (BuildSignedEvent(key, BTF_DESC_KIND, tags, desc, ev)) | ||
| 531 | { | ||
| 532 | json pub = json::array({ "EVENT", ev }); | ||
| 533 | ws.SendText(pub.dump()); | ||
| 534 | } | ||
| 535 | } | ||
| 536 | |||
| 537 | // Resolve a `.btf` address via a relay: fetch the descriptor published by that | ||
| 538 | // address's key and verify it self-certifies under the decoded pubkey. | ||
| 539 | static bool ResolveDescriptor(CWebSocket& ws, void* ctx, const string& btfAddr, | ||
| 540 | btf::Descriptor& out) | ||
| 541 | { | ||
| 542 | unsigned char pk[32]; | ||
| 543 | if (!btf::ParseAddress(btfAddr, pk)) | ||
| 544 | return false; | ||
| 545 | json filter = json::object(); | ||
| 546 | filter["authors"] = json::array({ HexEncode(pk, 32) }); | ||
| 547 | filter["kinds"] = json::array({ BTF_DESC_KIND }); | ||
| 548 | filter["limit"] = 1; | ||
| 549 | json req = json::array({ "REQ", "btf-resolve", filter }); | ||
| 550 | if (!ws.SendText(req.dump())) | ||
| 551 | return false; | ||
| 552 | for (;;) | ||
| 553 | { | ||
| 554 | string msg; | ||
| 555 | if (!ws.RecvText(msg)) | ||
| 556 | break; | ||
| 557 | json j; | ||
| 558 | try { j = json::parse(msg); } catch (...) { continue; } | ||
| 559 | if (!j.is_array() || j.empty()) continue; | ||
| 560 | string t = j[0].get<string>(); | ||
| 561 | if (t == "EVENT" && j.size() >= 3) | ||
| 562 | { | ||
| 563 | const json& ev = j[2]; | ||
| 564 | if (ev.contains("content") && | ||
| 565 | btf::VerifyDescriptor(ctx, ev["content"].get<string>(), pk, out)) | ||
| 566 | return true; | ||
| 567 | } | ||
| 568 | else if (t == "EOSE") | ||
| 569 | break; | ||
| 570 | } | ||
| 571 | return false; | ||
| 572 | } | ||
| 573 | |||
| 574 | // Resolve a `.btf` address into its rendezvous coordinates by querying the | ||
| 575 | // public discovery relays for the owner's self-certified descriptor. Used by | ||
| 576 | // ConnectNodeBtf in net.cpp. | ||
| 577 | bool BtfResolve(const std::string& btfAddr, std::string& meetingHostPort, | ||
| 578 | unsigned char enc_pub[32]) | ||
| 579 | { | ||
| 580 | if (!EnsureNostrKey()) | ||
| 581 | return false; | ||
| 582 | for (int i = 0; i < nNostrRelays && !fShutdown; i++) | ||
| 583 | { | ||
| 584 | try | ||
| 585 | { | ||
| 586 | CWebSocket ws; | ||
| 587 | if (!ws.Connect(pszNostrRelays[i], 10)) | ||
| 588 | continue; | ||
| 589 | btf::Descriptor d; | ||
| 590 | if (!ResolveDescriptor(ws, g_nostrKey.ctx, btfAddr, d)) | ||
| 591 | continue; | ||
| 592 | if (d.meeting_node.empty() || d.meeting_node == "rendezvous-pending") | ||
| 593 | continue; // descriptor predates the owner's relay config | ||
| 594 | if (!HexDecode(d.enc, enc_pub, 32)) | ||
| 595 | continue; | ||
| 596 | meetingHostPort = d.meeting_node; | ||
| 597 | return true; | ||
| 598 | } | ||
| 599 | CATCH_PRINT_EXCEPTION("BtfResolve") | ||
| 600 | } | ||
| 601 | return false; | ||
| 602 | } | ||
| 603 | |||
| 604 | |||
| 605 | // Connect to a relay: publish our address and collect the others'. | ||
| 606 | static bool SeedFromRelay(CNostrKey& key, const string& relay) | ||
| 607 | { | ||
| 608 | CWebSocket ws; | ||
| 609 | if (!ws.Connect(relay, 10)) | ||
| 610 | return false; | ||
| 611 | printf("Nostr: connected to %s\n", relay.c_str()); | ||
| 612 | |||
| 613 | // Publish our announcement (replaceable event with our ip:port) | ||
| 614 | if (addrLocalHost.ip != 0) | ||
| 615 | { | ||
| 616 | json tags = json::array({ | ||
| 617 | json::array({ "d", NOSTR_DTAG }), | ||
| 618 | json::array({ "t", NOSTR_DTAG }) | ||
| 619 | }); | ||
| 620 | json ev; | ||
| 621 | if (BuildSignedEvent(key, NOSTR_KIND, tags, addrLocalHost.ToStringIPPort(), ev)) | ||
| 622 | { | ||
| 623 | json pub = json::array({ "EVENT", ev }); | ||
| 624 | ws.SendText(pub.dump()); | ||
| 625 | } | ||
| 626 | } | ||
| 627 | |||
| 628 | // Publish our self-certifying .btf descriptor (rendezvous discovery) | ||
| 629 | PublishDescriptor(ws, key); | ||
| 630 | |||
| 631 | // Subscribe to receive the announcements of other nodes | ||
| 632 | json filter = json::object(); | ||
| 633 | filter["kinds"] = json::array({ NOSTR_KIND }); | ||
| 634 | filter["#d"] = json::array({ NOSTR_DTAG }); | ||
| 635 | filter["limit"] = 500; | ||
| 636 | json req = json::array({ "REQ", "bf-sub", filter }); | ||
| 637 | if (!ws.SendText(req.dump())) | ||
| 638 | return false; | ||
| 639 | |||
| 640 | // Read responses until EOSE (end of stored events) or timeout | ||
| 641 | int nEvents = 0; | ||
| 642 | for (;;) | ||
| 643 | { | ||
| 644 | string msg; | ||
| 645 | if (!ws.RecvText(msg)) | ||
| 646 | break; // timeout or closed connection | ||
| 647 | json j; | ||
| 648 | try { j = json::parse(msg); } catch (...) { continue; } | ||
| 649 | if (!j.is_array() || j.empty()) continue; | ||
| 650 | string type = j[0].get<string>(); | ||
| 651 | if (type == "EVENT" && j.size() >= 3) | ||
| 652 | { | ||
| 653 | HandlePeerEvent(j[2]); | ||
| 654 | if (++nEvents > 1000) break; | ||
| 655 | } | ||
| 656 | else if (type == "EOSE") | ||
| 657 | { | ||
| 658 | // We received all stored events; close this relay. | ||
| 659 | break; | ||
| 660 | } | ||
| 661 | else if (type == "NOTICE" || type == "OK" || type == "CLOSED") | ||
| 662 | { | ||
| 663 | // informational | ||
| 664 | } | ||
| 665 | } | ||
| 666 | printf("Nostr: %s returned %d events\n", relay.c_str(), nEvents); | ||
| 667 | |||
| 668 | // Discover other nodes' .btf descriptors so we can auto-connect anonymously | ||
| 669 | // (no manual /connectbtf). Each node publishes one addressable descriptor | ||
| 670 | // (kind 38501, d-tag btf-descriptor); we learn every peer's .btf address by | ||
| 671 | // deriving it from the event author. Reachability is verified later, when | ||
| 672 | // the rendezvous tunnel boxes to that key's static x25519 key. | ||
| 673 | ws.SendText(json::array({ "CLOSE", "bf-sub" }).dump()); | ||
| 674 | { | ||
| 675 | json dfilter = json::object(); | ||
| 676 | dfilter["kinds"] = json::array({ BTF_DESC_KIND }); | ||
| 677 | dfilter["#d"] = json::array({ BTF_DESC_DTAG }); | ||
| 678 | dfilter["limit"] = 200; | ||
| 679 | json dreq = json::array({ "REQ", "btf-disc", dfilter }); | ||
| 680 | int nPeers = 0; | ||
| 681 | if (ws.SendText(dreq.dump())) | ||
| 682 | { | ||
| 683 | for (;;) | ||
| 684 | { | ||
| 685 | string msg; | ||
| 686 | if (!ws.RecvText(msg)) | ||
| 687 | break; | ||
| 688 | json j; | ||
| 689 | try { j = json::parse(msg); } catch (...) { continue; } | ||
| 690 | if (!j.is_array() || j.empty()) continue; | ||
| 691 | string type = j[0].get<string>(); | ||
| 692 | if (type == "EVENT" && j.size() >= 3) | ||
| 693 | { | ||
| 694 | const json& ev = j[2]; | ||
| 695 | if (!ev.contains("pubkey") || !ev.contains("kind")) continue; | ||
| 696 | if (ev["kind"].get<int>() != BTF_DESC_KIND) continue; | ||
| 697 | unsigned char pkb[32]; | ||
| 698 | if (!HexDecode(ev["pubkey"].get<string>(), pkb, 32)) continue; | ||
| 699 | if (memcmp(pkb, key.xonly, 32) == 0) continue; // not ourselves | ||
| 700 | string peerAddr = btf::Address(pkb); | ||
| 701 | bool fNew = false; | ||
| 702 | CRITICAL_BLOCK(cs_btfPeers) | ||
| 703 | fNew = g_btfPeers.insert(peerAddr).second; | ||
| 704 | if (fNew) | ||
| 705 | printf("Nostr: discovered .btf peer %s\n", peerAddr.c_str()); | ||
| 706 | if (++nPeers > 500) break; | ||
| 707 | } | ||
| 708 | else if (type == "EOSE") | ||
| 709 | break; | ||
| 710 | } | ||
| 711 | } | ||
| 712 | } | ||
| 713 | return true; | ||
| 714 | } | ||
| 715 | |||
| 716 | |||
| 717 | // Per-peer backoff: don't redial a .btf that just failed until this time. Keeps | ||
| 718 | // dead/stale descriptors (e.g. abandoned test identities that linger on the | ||
| 719 | // relays) from consuming the whole per-pass dial budget and starving the live | ||
| 720 | // peers. Backoff grows on repeated failures, capped. | ||
| 721 | static map<string, int64> g_btfPeerBackoff; // addr -> next-try time | ||
| 722 | static map<string, int> g_btfPeerFails; // addr -> consecutive failures | ||
| 723 | |||
| 724 | // Dial the .btf peers discovered on the relays, up to a target connection count. | ||
| 725 | // Mirrors ThreadOpenConnections' ref handling: a kept connection holds one ref | ||
| 726 | // (owned by fNetworkNode, released on disconnect); a redundant one is released. | ||
| 727 | static void ConnectDiscoveredBtfPeers() | ||
| 728 | { | ||
| 729 | vector<string> peers; | ||
| 730 | CRITICAL_BLOCK(cs_btfPeers) | ||
| 731 | peers.assign(g_btfPeers.begin(), g_btfPeers.end()); | ||
| 732 | |||
| 733 | // Shuffle: the candidate set is sorted, so without this a handful of dead | ||
| 734 | // peers at the front would be retried every pass and the live peers further | ||
| 735 | // down the list would never be reached within the per-pass dial budget. | ||
| 736 | for (size_t i = peers.size(); i > 1; i--) | ||
| 737 | swap(peers[i - 1], peers[(size_t)GetRand(i)]); | ||
| 738 | |||
| 739 | int64 now = GetTime(); | ||
| 740 | int nDials = 0; | ||
| 741 | foreach(const string& addr, peers) | ||
| 742 | { | ||
| 743 | if (fShutdown) break; | ||
| 744 | if (vNodes.size() >= BTF_TARGET_CONN) break; | ||
| 745 | if (nDials >= BTF_DIALS_PER_PASS) break; | ||
| 746 | |||
| 747 | // Skip peers still in backoff from a recent failure. | ||
| 748 | map<string, int64>::iterator bi = g_btfPeerBackoff.find(addr); | ||
| 749 | if (bi != g_btfPeerBackoff.end() && now < bi->second) | ||
| 750 | continue; | ||
| 751 | |||
| 752 | CNode* pnode = ConnectNodeBtf(addr); | ||
| 753 | if (pnode) | ||
| 754 | { | ||
| 755 | if (!pnode->fNetworkNode) | ||
| 756 | pnode->fNetworkNode = true; // keep the ref from ConnectNodeBtf | ||
| 757 | else | ||
| 758 | pnode->Release(); // already connected; drop the extra ref | ||
| 759 | g_btfPeerBackoff.erase(addr); // reachable again | ||
| 760 | g_btfPeerFails.erase(addr); | ||
| 761 | } | ||
| 762 | else | ||
| 763 | { | ||
| 764 | // Exponential-ish backoff: 1,2,4,... minutes, capped at 30. | ||
| 765 | int n = ++g_btfPeerFails[addr]; | ||
| 766 | int64 mins = 1; | ||
| 767 | for (int k = 1; k < n && mins < 30; k++) mins *= 2; | ||
| 768 | if (mins > 30) mins = 30; | ||
| 769 | g_btfPeerBackoff[addr] = now + mins * 60; | ||
| 770 | nDials++; // only count real (failed) dial attempts against the budget | ||
| 771 | } | ||
| 772 | } | ||
| 773 | } | ||
| 774 | |||
| 775 | |||
| 776 | void ThreadNostrSeed(void* parg) | ||
| 777 | { | ||
| 778 | printf("ThreadNostrSeed started\n"); | ||
| 779 | |||
| 780 | if (!EnsureNostrKey()) | ||
| 781 | { | ||
| 782 | printf("Nostr: failed to initialize secp256k1 key\n"); | ||
| 783 | return; | ||
| 784 | } | ||
| 785 | CNostrKey& key = g_nostrKey; | ||
| 786 | printf("Nostr: node pubkey = %s\n", key.PubKeyHex().c_str()); | ||
| 787 | printf("Nostr: node .btf address = %s\n", key.BtfAddress().c_str()); | ||
| 788 | |||
| 789 | // One-time self-test of the rendezvous: publish our descriptor to a relay, | ||
| 790 | // then resolve our OWN .btf address back and verify it self-certifies. Proves | ||
| 791 | // the .btf publish/resolve/verify chain works against real public relays. | ||
| 792 | for (int i = 0; i < nNostrRelays && !fShutdown; i++) | ||
| 793 | { | ||
| 794 | try | ||
| 795 | { | ||
| 796 | CWebSocket ws; | ||
| 797 | if (!ws.Connect(pszNostrRelays[i], 10)) continue; | ||
| 798 | PublishDescriptor(ws, key); | ||
| 799 | Sleep(700); // let the relay store the replaceable event | ||
| 800 | btf::Descriptor d; | ||
| 801 | if (ResolveDescriptor(ws, key.ctx, key.BtfAddress(), d)) | ||
| 802 | { | ||
| 803 | printf("Nostr: .btf self-resolve OK via %s (meeting_node=%s, enc=%s...)\n", | ||
| 804 | pszNostrRelays[i], d.meeting_node.c_str(), d.enc.substr(0, 16).c_str()); | ||
| 805 | break; | ||
| 806 | } | ||
| 807 | } | ||
| 808 | CATCH_PRINT_EXCEPTION("btf self-test") | ||
| 809 | } | ||
| 810 | |||
| 811 | // OpenSSL is already initialized by the rest of the app; TLS_client_method is enough. | ||
| 812 | loop | ||
| 813 | { | ||
| 814 | for (int i = 0; i < nNostrRelays; i++) | ||
| 815 | { | ||
| 816 | if (fShutdown) return; | ||
| 817 | try | ||
| 818 | { | ||
| 819 | SeedFromRelay(key, pszNostrRelays[i]); | ||
| 820 | } | ||
| 821 | CATCH_PRINT_EXCEPTION("SeedFromRelay") | ||
| 822 | } | ||
| 823 | |||
| 824 | // Auto-connect to discovered .btf peers over the rendezvous relay -- the | ||
| 825 | // anonymous, CGNAT-friendly replacement for the old IP-based connect. No | ||
| 826 | // manual /connectbtf needed: nodes find each other purely via Nostr. | ||
| 827 | try | ||
| 828 | { | ||
| 829 | ConnectDiscoveredBtfPeers(); | ||
| 830 | } | ||
| 831 | CATCH_PRINT_EXCEPTION("ConnectDiscoveredBtfPeers") | ||
| 832 | |||
| 833 | // Re-announce/re-discover periodically (the replaceable event keeps the | ||
| 834 | // relay up to date and picks up nodes that joined after us) | ||
| 835 | for (int i = 0; i < 60 && !fShutdown; i++) | ||
| 836 | Sleep(1000); | ||
| 837 | } | ||
| 838 | } | ||
diff --git a/src/nostr.h b/src/nostr.h new file mode 100644 index 0000000..5ec9f65 --- /dev/null +++ b/src/nostr.h | |||
| @@ -0,0 +1,39 @@ | |||
| 1 | // Copyright (c) 2026 Bitflash developers | ||
| 2 | // Distributed under the MIT/X11 software license. | ||
| 3 | // | ||
| 4 | // Peer discovery over Nostr relays -- replaces the old ThreadIRCSeed. Each | ||
| 5 | // node publishes a replaceable event (NIP-78, kind 30078) containing its | ||
| 6 | // "ip:port", signed with Schnorr/secp256k1 (BIP340, the same scheme used by | ||
| 7 | // Nostr), and subscribes to receive the announcements of other nodes, feeding | ||
| 8 | // them into the Bitflash address manager. | ||
| 9 | |||
| 10 | #ifndef BITFLASH_NOSTR_H | ||
| 11 | #define BITFLASH_NOSTR_H | ||
| 12 | |||
| 13 | #include <string> | ||
| 14 | |||
| 15 | // Thread entry point (signature compatible with _beginthread) | ||
| 16 | void ThreadNostrSeed(void* parg); | ||
| 17 | |||
| 18 | // Public relays used for discovery. Tunable. | ||
| 19 | extern const char* pszNostrRelays[]; | ||
| 20 | extern const int nNostrRelays; | ||
| 21 | |||
| 22 | // Rendezvous meeting relay ("host:port") this node registers at and advertises | ||
| 23 | // in its .btf descriptor. Overridable with /rvrelay=host:port. | ||
| 24 | extern std::string strBtfMeetingRelay; | ||
| 25 | |||
| 26 | // Copy this node's .btf identity (lazily loading or generating it): the x-only | ||
| 27 | // pubkey (= the .btf address) and the x25519 secret for the end-to-end channel. | ||
| 28 | bool BtfGetIdentity(unsigned char pubkey[32], unsigned char enc_sk[32]); | ||
| 29 | |||
| 30 | // This node's printable .btf address, or "" if the identity failed to load. | ||
| 31 | std::string BtfLocalAddress(); | ||
| 32 | |||
| 33 | // Resolve a .btf address via the public discovery relays: fetch the owner's | ||
| 34 | // self-certified descriptor and return its meeting node ("host:port") and | ||
| 35 | // x25519 public key for the end-to-end channel. | ||
| 36 | bool BtfResolve(const std::string& btfAddr, std::string& meetingHostPort, | ||
| 37 | unsigned char enc_pub[32]); | ||
| 38 | |||
| 39 | #endif | ||
diff --git a/src/randomx_pow.cpp b/src/randomx_pow.cpp new file mode 100644 index 0000000..17bf455 --- /dev/null +++ b/src/randomx_pow.cpp | |||
| @@ -0,0 +1,143 @@ | |||
| 1 | // Copyright (c) 2026 Bitflash developers | ||
| 2 | // Distributed under the MIT/X11 software license. | ||
| 3 | // | ||
| 4 | // RandomX PoW implementation. See randomx_pow.h. | ||
| 5 | |||
| 6 | #include "headers.h" | ||
| 7 | #include <randomx.h> | ||
| 8 | #include <thread> | ||
| 9 | #include <vector> | ||
| 10 | |||
| 11 | // Fixed key (seed) that determines the RandomX cache/dataset. Keeping it | ||
| 12 | // constant avoids per-epoch "reseed" logic; for the CPU+RAM fairness goal | ||
| 13 | // this is sufficient (RandomX already neutralizes GPU/ASIC by design). | ||
| 14 | static const char* RANDOMX_KEY = "Bitflash/RandomX/v1/one-cpu-one-vote"; | ||
| 15 | |||
| 16 | static randomx_flags g_flags = RANDOMX_FLAG_DEFAULT; | ||
| 17 | static randomx_cache* g_cache = NULL; | ||
| 18 | static randomx_dataset* g_dataset = NULL; | ||
| 19 | static randomx_vm* g_vmVerify = NULL; | ||
| 20 | static CCriticalSection g_csVerify; | ||
| 21 | static bool g_fInit = false; | ||
| 22 | static bool g_fFast = false; | ||
| 23 | |||
| 24 | |||
| 25 | bool RandomXInit() | ||
| 26 | { | ||
| 27 | if (g_fInit) | ||
| 28 | return true; | ||
| 29 | |||
| 30 | // Detect the best flags for this CPU (JIT, hardware AES, Argon2). | ||
| 31 | g_flags = randomx_get_flags(); | ||
| 32 | |||
| 33 | g_cache = randomx_alloc_cache(g_flags); | ||
| 34 | if (!g_cache) | ||
| 35 | { | ||
| 36 | // Try without JIT as a fallback | ||
| 37 | g_flags = RANDOMX_FLAG_DEFAULT; | ||
| 38 | g_cache = randomx_alloc_cache(g_flags); | ||
| 39 | if (!g_cache) | ||
| 40 | return error("RandomX: failed to allocate cache (256 MB)"); | ||
| 41 | } | ||
| 42 | randomx_init_cache(g_cache, RANDOMX_KEY, strlen(RANDOMX_KEY)); | ||
| 43 | |||
| 44 | // Verification VM in light mode (cache only) | ||
| 45 | g_vmVerify = randomx_create_vm(g_flags, g_cache, NULL); | ||
| 46 | if (!g_vmVerify) | ||
| 47 | return error("RandomX: failed to create verification VM"); | ||
| 48 | |||
| 49 | g_fInit = true; | ||
| 50 | printf("RandomX: initialized (cache 256 MB, flags=%d)\n", (int)g_flags); | ||
| 51 | return true; | ||
| 52 | } | ||
| 53 | |||
| 54 | |||
| 55 | bool RandomXInitDataset(int nThreads) | ||
| 56 | { | ||
| 57 | if (!g_fInit && !RandomXInit()) | ||
| 58 | return false; | ||
| 59 | if (g_fFast) | ||
| 60 | return true; | ||
| 61 | |||
| 62 | randomx_flags fastFlags = (randomx_flags)(g_flags | RANDOMX_FLAG_FULL_MEM); | ||
| 63 | g_dataset = randomx_alloc_dataset(fastFlags); | ||
| 64 | if (!g_dataset) | ||
| 65 | { | ||
| 66 | printf("RandomX: not enough memory for the 2 GB dataset, staying in light mode\n"); | ||
| 67 | return false; | ||
| 68 | } | ||
| 69 | |||
| 70 | unsigned long total = randomx_dataset_item_count(); | ||
| 71 | if (nThreads < 1) nThreads = 1; | ||
| 72 | printf("RandomX: initializing ~2 GB dataset with %d threads...\n", nThreads); | ||
| 73 | |||
| 74 | std::vector<std::thread> workers; | ||
| 75 | unsigned long per = total / nThreads; | ||
| 76 | for (int i = 0; i < nThreads; i++) | ||
| 77 | { | ||
| 78 | unsigned long start = i * per; | ||
| 79 | unsigned long count = (i == nThreads - 1) ? (total - start) : per; | ||
| 80 | workers.emplace_back([start, count]() { | ||
| 81 | randomx_init_dataset(g_dataset, g_cache, start, count); | ||
| 82 | }); | ||
| 83 | } | ||
| 84 | for (auto& w : workers) w.join(); | ||
| 85 | |||
| 86 | g_fFast = true; | ||
| 87 | printf("RandomX: dataset ready (fast mode active)\n"); | ||
| 88 | return true; | ||
| 89 | } | ||
| 90 | |||
| 91 | |||
| 92 | bool RandomXFastReady() | ||
| 93 | { | ||
| 94 | return g_fFast; | ||
| 95 | } | ||
| 96 | |||
| 97 | |||
| 98 | uint256 RandomXPoWHash(const void* pHeader, size_t nSize) | ||
| 99 | { | ||
| 100 | uint256 result = 0; | ||
| 101 | if (!g_fInit && !RandomXInit()) | ||
| 102 | return result; | ||
| 103 | CRITICAL_BLOCK(g_csVerify) | ||
| 104 | { | ||
| 105 | unsigned char hash[RANDOMX_HASH_SIZE]; | ||
| 106 | randomx_calculate_hash(g_vmVerify, pHeader, nSize, hash); | ||
| 107 | memcpy(&result, hash, RANDOMX_HASH_SIZE); | ||
| 108 | } | ||
| 109 | return result; | ||
| 110 | } | ||
| 111 | |||
| 112 | |||
| 113 | void* RandomXCreateMinerVM() | ||
| 114 | { | ||
| 115 | if (!g_fInit && !RandomXInit()) | ||
| 116 | return NULL; | ||
| 117 | if (g_fFast && g_dataset) | ||
| 118 | { | ||
| 119 | randomx_flags fastFlags = (randomx_flags)(g_flags | RANDOMX_FLAG_FULL_MEM); | ||
| 120 | return randomx_create_vm(fastFlags, NULL, g_dataset); | ||
| 121 | } | ||
| 122 | // Light mode: own VM sharing the cache | ||
| 123 | return randomx_create_vm(g_flags, g_cache, NULL); | ||
| 124 | } | ||
| 125 | |||
| 126 | |||
| 127 | void RandomXDestroyMinerVM(void* vm) | ||
| 128 | { | ||
| 129 | if (vm) | ||
| 130 | randomx_destroy_vm((randomx_vm*)vm); | ||
| 131 | } | ||
| 132 | |||
| 133 | |||
| 134 | uint256 RandomXHashWithVM(void* vm, const void* pHeader, size_t nSize) | ||
| 135 | { | ||
| 136 | uint256 result = 0; | ||
| 137 | if (!vm) | ||
| 138 | return result; | ||
| 139 | unsigned char hash[RANDOMX_HASH_SIZE]; | ||
| 140 | randomx_calculate_hash((randomx_vm*)vm, pHeader, nSize, hash); | ||
| 141 | memcpy(&result, hash, RANDOMX_HASH_SIZE); | ||
| 142 | return result; | ||
| 143 | } | ||
diff --git a/src/randomx_pow.h b/src/randomx_pow.h new file mode 100644 index 0000000..0027571 --- /dev/null +++ b/src/randomx_pow.h | |||
| @@ -0,0 +1,44 @@ | |||
| 1 | // Copyright (c) 2026 Bitflash developers | ||
| 2 | // Distributed under the MIT/X11 software license. | ||
| 3 | // | ||
| 4 | // Memory-hard Proof of Work (CPU + RAM) via RandomX -- replaces SHA-256d as | ||
| 5 | // the PoW algorithm. The block IDENTITY hash stays SHA-256d (GetHash), | ||
| 6 | // preserving all indexing; what changes is the PROOF-OF-WORK hash | ||
| 7 | // (GetPoWHash), computed with RandomX. | ||
| 8 | // | ||
| 9 | // Modes: | ||
| 10 | // - Verification (all nodes): 256 MB cache, "light" VM. Cheap. | ||
| 11 | // - Mining (optional, fast): ~2 GB dataset, "full" VMs. Fast. | ||
| 12 | // GPUs and ASICs are neutralized by RandomX's memory cost/latency. | ||
| 13 | |||
| 14 | #ifndef BITFLASH_RANDOMX_POW_H | ||
| 15 | #define BITFLASH_RANDOMX_POW_H | ||
| 16 | |||
| 17 | // uint256 comes from uint256.h, already included by headers.h before this file. | ||
| 18 | |||
| 19 | // Initialize the cache (256 MB) and the verification VM. Call once at startup. | ||
| 20 | // Returns false if allocation fails. | ||
| 21 | bool RandomXInit(); | ||
| 22 | |||
| 23 | // Allocate and initialize the ~2 GB dataset for fast mining (fast mode), | ||
| 24 | // using nThreads to speed it up. Idempotent. Returns false on failure (the | ||
| 25 | // miner then falls back to light mode automatically). | ||
| 26 | bool RandomXInitDataset(int nThreads); | ||
| 27 | |||
| 28 | // PoW hash of an 80-byte header, using the verification VM (thread-safe, | ||
| 29 | // guarded by a critical section). | ||
| 30 | uint256 RandomXPoWHash(const void* pHeader, size_t nSize); | ||
| 31 | |||
| 32 | // Create a VM for a mining thread (own VM, not shared). Uses the dataset | ||
| 33 | // (fast) if available, otherwise the cache (light). Release with | ||
| 34 | // RandomXDestroyMinerVM. Returns NULL on failure. | ||
| 35 | void* RandomXCreateMinerVM(); | ||
| 36 | void RandomXDestroyMinerVM(void* vm); | ||
| 37 | |||
| 38 | // Compute a PoW hash on an owned mining VM (not guarded). | ||
| 39 | uint256 RandomXHashWithVM(void* vm, const void* pHeader, size_t nSize); | ||
| 40 | |||
| 41 | // True when the 2 GB dataset is ready (fast mode active). | ||
| 42 | bool RandomXFastReady(); | ||
| 43 | |||
| 44 | #endif | ||
diff --git a/src/rc/addressbook16.bmp b/src/rc/addressbook16.bmp new file mode 100644 index 0000000..c557691 --- /dev/null +++ b/src/rc/addressbook16.bmp | |||
| Binary files differ | |||
diff --git a/src/rc/addressbook16mask.bmp b/src/rc/addressbook16mask.bmp new file mode 100644 index 0000000..d3a478d --- /dev/null +++ b/src/rc/addressbook16mask.bmp | |||
| Binary files differ | |||
diff --git a/src/rc/addressbook20.bmp b/src/rc/addressbook20.bmp new file mode 100644 index 0000000..2b33b22 --- /dev/null +++ b/src/rc/addressbook20.bmp | |||
| Binary files differ | |||
diff --git a/src/rc/addressbook20mask.bmp b/src/rc/addressbook20mask.bmp new file mode 100644 index 0000000..56ce612 --- /dev/null +++ b/src/rc/addressbook20mask.bmp | |||
| Binary files differ | |||
diff --git a/src/rc/bitcoin.ico b/src/rc/bitcoin.ico new file mode 100644 index 0000000..b768077 --- /dev/null +++ b/src/rc/bitcoin.ico | |||
| Binary files differ | |||
diff --git a/src/rc/bitcoin_bc_original.ico b/src/rc/bitcoin_bc_original.ico new file mode 100644 index 0000000..88cc240 --- /dev/null +++ b/src/rc/bitcoin_bc_original.ico | |||
| Binary files differ | |||
diff --git a/src/rc/check.ico b/src/rc/check.ico new file mode 100644 index 0000000..0c4e6e8 --- /dev/null +++ b/src/rc/check.ico | |||
| Binary files differ | |||
diff --git a/src/rc/send16.bmp b/src/rc/send16.bmp new file mode 100644 index 0000000..676b5c4 --- /dev/null +++ b/src/rc/send16.bmp | |||
| Binary files differ | |||
diff --git a/src/rc/send16mask.bmp b/src/rc/send16mask.bmp new file mode 100644 index 0000000..06c747f --- /dev/null +++ b/src/rc/send16mask.bmp | |||
| Binary files differ | |||
diff --git a/src/rc/send16masknoshadow.bmp b/src/rc/send16masknoshadow.bmp new file mode 100644 index 0000000..faf24e0 --- /dev/null +++ b/src/rc/send16masknoshadow.bmp | |||
| Binary files differ | |||
diff --git a/src/rc/send20.bmp b/src/rc/send20.bmp new file mode 100644 index 0000000..2b90422 --- /dev/null +++ b/src/rc/send20.bmp | |||
| Binary files differ | |||
diff --git a/src/rc/send20mask.bmp b/src/rc/send20mask.bmp new file mode 100644 index 0000000..f124d0d --- /dev/null +++ b/src/rc/send20mask.bmp | |||
| Binary files differ | |||
diff --git a/src/readme.txt b/src/readme.txt new file mode 100644 index 0000000..c72fcec --- /dev/null +++ b/src/readme.txt | |||
| @@ -0,0 +1,54 @@ | |||
| 1 | Bitflash (BTF) v0.1 ALPHA | ||
| 2 | ========================= | ||
| 3 | |||
| 4 | A revival of Satoshi Nakamoto's original Bitcoin v0.1 client (2009), ported to | ||
| 5 | a modern toolchain and turned into its own Layer 1 network. | ||
| 6 | |||
| 7 | Philosophy: fair launch, no pre-mine, no ICO. One CPU, one vote. | ||
| 8 | |||
| 9 | Based on code Copyright (c) 2009 Satoshi Nakamoto. | ||
| 10 | Copyright (c) 2026 The Bitflash developers. | ||
| 11 | Distributed under the MIT/X11 software license, see the accompanying | ||
| 12 | file license.txt or http://www.opensource.org/licenses/mit-license.php. | ||
| 13 | This product includes software developed by the OpenSSL Project. | ||
| 14 | |||
| 15 | |||
| 16 | Differences from the original Bitcoin | ||
| 17 | ------------------------------------- | ||
| 18 | - Own genesis block (22/Jul/2026 headline, independent chain) | ||
| 19 | - Own magic bytes (0xbf 0x1a 0x5c 0xfd) and P2P port 8433 | ||
| 20 | - Addresses start with "B" (ADDRESSVERSION = 25) | ||
| 21 | - Consensus fixes applied: value overflow (CVE-2010-5139), duplicate inputs, | ||
| 22 | money range checks (MoneyRange) | ||
| 23 | - IRC peer discovery replaced by Nostr relay discovery | ||
| 24 | - Memory-hard Proof of Work (RandomX, CPU + RAM) instead of SHA-256d | ||
| 25 | - Economics identical to Bitcoin: 50 BTF/block, halving every 210,000 blocks, | ||
| 26 | 21 million total | ||
| 27 | |||
| 28 | |||
| 29 | Build (Windows, MSYS2 UCRT64) | ||
| 30 | ----------------------------- | ||
| 31 | Modern toolchain: | ||
| 32 | g++ 16 (MinGW-w64 UCRT), wxWidgets 3.2, OpenSSL 3, Berkeley DB 6, Boost, | ||
| 33 | libsecp256k1 (Schnorr), nlohmann/json, RandomX | ||
| 34 | |||
| 35 | Bundled dependencies are built from source into ../deps and ../RandomX. | ||
| 36 | In the MSYS2 UCRT64 shell: | ||
| 37 | bash build.sh (uses src/makefile.mingw) | ||
| 38 | |||
| 39 | The resulting executable is src/bitflash.exe. | ||
| 40 | |||
| 41 | |||
| 42 | Command-line options (in addition to the original ones) | ||
| 43 | ------------------------------------------------------- | ||
| 44 | /port=N listen on P2P port N (default 8433) | ||
| 45 | /solomine mine without requiring a connected peer (local testing) | ||
| 46 | |||
| 47 | |||
| 48 | Roadmap | ||
| 49 | ------- | ||
| 50 | Milestone 0 Compile the original client on a modern toolchain [done] | ||
| 51 | Milestone 1 Bitflash identity + genesis + consensus fixes [done] | ||
| 52 | Milestone 2 Peer discovery over Nostr relays [done] | ||
| 53 | Milestone 3 Memory-hard PoW (RandomX) instead of SHA-256d [done] | ||
| 54 | Milestone 4 Public testnet | ||
diff --git a/src/script.cpp b/src/script.cpp new file mode 100644 index 0000000..d2111ed --- /dev/null +++ b/src/script.cpp | |||
| @@ -0,0 +1,1127 @@ | |||
| 1 | // Copyright (c) 2009 Satoshi Nakamoto | ||
| 2 | // Distributed under the MIT/X11 software license, see the accompanying | ||
| 3 | // file license.txt or http://www.opensource.org/licenses/mit-license.php. | ||
| 4 | |||
| 5 | #include "headers.h" | ||
| 6 | |||
| 7 | bool CheckSig(vector<unsigned char> vchSig, vector<unsigned char> vchPubKey, CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType); | ||
| 8 | |||
| 9 | |||
| 10 | |||
| 11 | typedef vector<unsigned char> valtype; | ||
| 12 | static const valtype vchFalse(0); | ||
| 13 | static const valtype vchZero(0); | ||
| 14 | static const valtype vchTrue(1, 1); | ||
| 15 | static const CBigNum bnZero(0); | ||
| 16 | static const CBigNum bnOne(1); | ||
| 17 | static const CBigNum bnFalse(0); | ||
| 18 | static const CBigNum bnTrue(1); | ||
| 19 | |||
| 20 | |||
| 21 | bool CastToBool(const valtype& vch) | ||
| 22 | { | ||
| 23 | return (CBigNum(vch) != bnZero); | ||
| 24 | } | ||
| 25 | |||
| 26 | void MakeSameSize(valtype& vch1, valtype& vch2) | ||
| 27 | { | ||
| 28 | // Lengthen the shorter one | ||
| 29 | if (vch1.size() < vch2.size()) | ||
| 30 | vch1.resize(vch2.size(), 0); | ||
| 31 | if (vch2.size() < vch1.size()) | ||
| 32 | vch2.resize(vch1.size(), 0); | ||
| 33 | } | ||
| 34 | |||
| 35 | |||
| 36 | |||
| 37 | // | ||
| 38 | // Script is a stack machine (like Forth) that evaluates a predicate | ||
| 39 | // returning a bool indicating valid or not. There are no loops. | ||
| 40 | // | ||
| 41 | #define stacktop(i) (stack.at(stack.size()+(i))) | ||
| 42 | #define altstacktop(i) (altstack.at(altstack.size()+(i))) | ||
| 43 | |||
| 44 | bool EvalScript(const CScript& script, const CTransaction& txTo, unsigned int nIn, int nHashType, | ||
| 45 | vector<vector<unsigned char> >* pvStackRet) | ||
| 46 | { | ||
| 47 | CAutoBN_CTX pctx; | ||
| 48 | CScript::const_iterator pc = script.begin(); | ||
| 49 | CScript::const_iterator pend = script.end(); | ||
| 50 | CScript::const_iterator pbegincodehash = script.begin(); | ||
| 51 | vector<bool> vfExec; | ||
| 52 | vector<valtype> stack; | ||
| 53 | vector<valtype> altstack; | ||
| 54 | if (pvStackRet) | ||
| 55 | pvStackRet->clear(); | ||
| 56 | |||
| 57 | |||
| 58 | while (pc < pend) | ||
| 59 | { | ||
| 60 | bool fExec = !count(vfExec.begin(), vfExec.end(), false); | ||
| 61 | |||
| 62 | // | ||
| 63 | // Read instruction | ||
| 64 | // | ||
| 65 | opcodetype opcode; | ||
| 66 | valtype vchPushValue; | ||
| 67 | if (!script.GetOp(pc, opcode, vchPushValue)) | ||
| 68 | return false; | ||
| 69 | |||
| 70 | if (fExec && opcode <= OP_PUSHDATA4) | ||
| 71 | stack.push_back(vchPushValue); | ||
| 72 | else if (fExec || (OP_IF <= opcode && opcode <= OP_ENDIF)) | ||
| 73 | switch (opcode) | ||
| 74 | { | ||
| 75 | // | ||
| 76 | // Push value | ||
| 77 | // | ||
| 78 | case OP_1NEGATE: | ||
| 79 | case OP_1: | ||
| 80 | case OP_2: | ||
| 81 | case OP_3: | ||
| 82 | case OP_4: | ||
| 83 | case OP_5: | ||
| 84 | case OP_6: | ||
| 85 | case OP_7: | ||
| 86 | case OP_8: | ||
| 87 | case OP_9: | ||
| 88 | case OP_10: | ||
| 89 | case OP_11: | ||
| 90 | case OP_12: | ||
| 91 | case OP_13: | ||
| 92 | case OP_14: | ||
| 93 | case OP_15: | ||
| 94 | case OP_16: | ||
| 95 | { | ||
| 96 | // ( -- value) | ||
| 97 | CBigNum bn((int)opcode - (int)(OP_1 - 1)); | ||
| 98 | stack.push_back(bn.getvch()); | ||
| 99 | } | ||
| 100 | break; | ||
| 101 | |||
| 102 | |||
| 103 | // | ||
| 104 | // Control | ||
| 105 | // | ||
| 106 | case OP_NOP: | ||
| 107 | break; | ||
| 108 | |||
| 109 | case OP_VER: | ||
| 110 | { | ||
| 111 | CBigNum bn(VERSION); | ||
| 112 | stack.push_back(bn.getvch()); | ||
| 113 | } | ||
| 114 | break; | ||
| 115 | |||
| 116 | case OP_IF: | ||
| 117 | case OP_NOTIF: | ||
| 118 | case OP_VERIF: | ||
| 119 | case OP_VERNOTIF: | ||
| 120 | { | ||
| 121 | // <expression> if [statements] [else [statements]] endif | ||
| 122 | bool fValue = false; | ||
| 123 | if (fExec) | ||
| 124 | { | ||
| 125 | if (stack.size() < 1) | ||
| 126 | return false; | ||
| 127 | valtype& vch = stacktop(-1); | ||
| 128 | if (opcode == OP_VERIF || opcode == OP_VERNOTIF) | ||
| 129 | fValue = (CBigNum(VERSION) >= CBigNum(vch)); | ||
| 130 | else | ||
| 131 | fValue = CastToBool(vch); | ||
| 132 | if (opcode == OP_NOTIF || opcode == OP_VERNOTIF) | ||
| 133 | fValue = !fValue; | ||
| 134 | stack.pop_back(); | ||
| 135 | } | ||
| 136 | vfExec.push_back(fValue); | ||
| 137 | } | ||
| 138 | break; | ||
| 139 | |||
| 140 | case OP_ELSE: | ||
| 141 | { | ||
| 142 | if (vfExec.empty()) | ||
| 143 | return false; | ||
| 144 | vfExec.back() = !vfExec.back(); | ||
| 145 | } | ||
| 146 | break; | ||
| 147 | |||
| 148 | case OP_ENDIF: | ||
| 149 | { | ||
| 150 | if (vfExec.empty()) | ||
| 151 | return false; | ||
| 152 | vfExec.pop_back(); | ||
| 153 | } | ||
| 154 | break; | ||
| 155 | |||
| 156 | case OP_VERIFY: | ||
| 157 | { | ||
| 158 | // (true -- ) or | ||
| 159 | // (false -- false) and return | ||
| 160 | if (stack.size() < 1) | ||
| 161 | return false; | ||
| 162 | bool fValue = CastToBool(stacktop(-1)); | ||
| 163 | if (fValue) | ||
| 164 | stack.pop_back(); | ||
| 165 | else | ||
| 166 | pc = pend; | ||
| 167 | } | ||
| 168 | break; | ||
| 169 | |||
| 170 | case OP_RETURN: | ||
| 171 | { | ||
| 172 | pc = pend; | ||
| 173 | } | ||
| 174 | break; | ||
| 175 | |||
| 176 | |||
| 177 | // | ||
| 178 | // Stack ops | ||
| 179 | // | ||
| 180 | case OP_TOALTSTACK: | ||
| 181 | { | ||
| 182 | if (stack.size() < 1) | ||
| 183 | return false; | ||
| 184 | altstack.push_back(stacktop(-1)); | ||
| 185 | stack.pop_back(); | ||
| 186 | } | ||
| 187 | break; | ||
| 188 | |||
| 189 | case OP_FROMALTSTACK: | ||
| 190 | { | ||
| 191 | if (altstack.size() < 1) | ||
| 192 | return false; | ||
| 193 | stack.push_back(altstacktop(-1)); | ||
| 194 | altstack.pop_back(); | ||
| 195 | } | ||
| 196 | break; | ||
| 197 | |||
| 198 | case OP_2DROP: | ||
| 199 | { | ||
| 200 | // (x1 x2 -- ) | ||
| 201 | stack.pop_back(); | ||
| 202 | stack.pop_back(); | ||
| 203 | } | ||
| 204 | break; | ||
| 205 | |||
| 206 | case OP_2DUP: | ||
| 207 | { | ||
| 208 | // (x1 x2 -- x1 x2 x1 x2) | ||
| 209 | if (stack.size() < 2) | ||
| 210 | return false; | ||
| 211 | valtype vch1 = stacktop(-2); | ||
| 212 | valtype vch2 = stacktop(-1); | ||
| 213 | stack.push_back(vch1); | ||
| 214 | stack.push_back(vch2); | ||
| 215 | } | ||
| 216 | break; | ||
| 217 | |||
| 218 | case OP_3DUP: | ||
| 219 | { | ||
| 220 | // (x1 x2 x3 -- x1 x2 x3 x1 x2 x3) | ||
| 221 | if (stack.size() < 3) | ||
| 222 | return false; | ||
| 223 | valtype vch1 = stacktop(-3); | ||
| 224 | valtype vch2 = stacktop(-2); | ||
| 225 | valtype vch3 = stacktop(-1); | ||
| 226 | stack.push_back(vch1); | ||
| 227 | stack.push_back(vch2); | ||
| 228 | stack.push_back(vch3); | ||
| 229 | } | ||
| 230 | break; | ||
| 231 | |||
| 232 | case OP_2OVER: | ||
| 233 | { | ||
| 234 | // (x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2) | ||
| 235 | if (stack.size() < 4) | ||
| 236 | return false; | ||
| 237 | valtype vch1 = stacktop(-4); | ||
| 238 | valtype vch2 = stacktop(-3); | ||
| 239 | stack.push_back(vch1); | ||
| 240 | stack.push_back(vch2); | ||
| 241 | } | ||
| 242 | break; | ||
| 243 | |||
| 244 | case OP_2ROT: | ||
| 245 | { | ||
| 246 | // (x1 x2 x3 x4 x5 x6 -- x3 x4 x5 x6 x1 x2) | ||
| 247 | if (stack.size() < 6) | ||
| 248 | return false; | ||
| 249 | valtype vch1 = stacktop(-6); | ||
| 250 | valtype vch2 = stacktop(-5); | ||
| 251 | stack.erase(stack.end()-6, stack.end()-4); | ||
| 252 | stack.push_back(vch1); | ||
| 253 | stack.push_back(vch2); | ||
| 254 | } | ||
| 255 | break; | ||
| 256 | |||
| 257 | case OP_2SWAP: | ||
| 258 | { | ||
| 259 | // (x1 x2 x3 x4 -- x3 x4 x1 x2) | ||
| 260 | if (stack.size() < 4) | ||
| 261 | return false; | ||
| 262 | swap(stacktop(-4), stacktop(-2)); | ||
| 263 | swap(stacktop(-3), stacktop(-1)); | ||
| 264 | } | ||
| 265 | break; | ||
| 266 | |||
| 267 | case OP_IFDUP: | ||
| 268 | { | ||
| 269 | // (x - 0 | x x) | ||
| 270 | if (stack.size() < 1) | ||
| 271 | return false; | ||
| 272 | valtype vch = stacktop(-1); | ||
| 273 | if (CastToBool(vch)) | ||
| 274 | stack.push_back(vch); | ||
| 275 | } | ||
| 276 | break; | ||
| 277 | |||
| 278 | case OP_DEPTH: | ||
| 279 | { | ||
| 280 | // -- stacksize | ||
| 281 | CBigNum bn(stack.size()); | ||
| 282 | stack.push_back(bn.getvch()); | ||
| 283 | } | ||
| 284 | break; | ||
| 285 | |||
| 286 | case OP_DROP: | ||
| 287 | { | ||
| 288 | // (x -- ) | ||
| 289 | if (stack.size() < 1) | ||
| 290 | return false; | ||
| 291 | stack.pop_back(); | ||
| 292 | } | ||
| 293 | break; | ||
| 294 | |||
| 295 | case OP_DUP: | ||
| 296 | { | ||
| 297 | // (x -- x x) | ||
| 298 | if (stack.size() < 1) | ||
| 299 | return false; | ||
| 300 | valtype vch = stacktop(-1); | ||
| 301 | stack.push_back(vch); | ||
| 302 | } | ||
| 303 | break; | ||
| 304 | |||
| 305 | case OP_NIP: | ||
| 306 | { | ||
| 307 | // (x1 x2 -- x2) | ||
| 308 | if (stack.size() < 2) | ||
| 309 | return false; | ||
| 310 | stack.erase(stack.end() - 2); | ||
| 311 | } | ||
| 312 | break; | ||
| 313 | |||
| 314 | case OP_OVER: | ||
| 315 | { | ||
| 316 | // (x1 x2 -- x1 x2 x1) | ||
| 317 | if (stack.size() < 2) | ||
| 318 | return false; | ||
| 319 | valtype vch = stacktop(-2); | ||
| 320 | stack.push_back(vch); | ||
| 321 | } | ||
| 322 | break; | ||
| 323 | |||
| 324 | case OP_PICK: | ||
| 325 | case OP_ROLL: | ||
| 326 | { | ||
| 327 | // (xn ... x2 x1 x0 n - xn ... x2 x1 x0 xn) | ||
| 328 | // (xn ... x2 x1 x0 n - ... x2 x1 x0 xn) | ||
| 329 | if (stack.size() < 2) | ||
| 330 | return false; | ||
| 331 | int n = CBigNum(stacktop(-1)).getint(); | ||
| 332 | stack.pop_back(); | ||
| 333 | if (n < 0 || n >= stack.size()) | ||
| 334 | return false; | ||
| 335 | valtype vch = stacktop(-n-1); | ||
| 336 | if (opcode == OP_ROLL) | ||
| 337 | stack.erase(stack.end()-n-1); | ||
| 338 | stack.push_back(vch); | ||
| 339 | } | ||
| 340 | break; | ||
| 341 | |||
| 342 | case OP_ROT: | ||
| 343 | { | ||
| 344 | // (x1 x2 x3 -- x2 x3 x1) | ||
| 345 | // x2 x1 x3 after first swap | ||
| 346 | // x2 x3 x1 after second swap | ||
| 347 | if (stack.size() < 3) | ||
| 348 | return false; | ||
| 349 | swap(stacktop(-3), stacktop(-2)); | ||
| 350 | swap(stacktop(-2), stacktop(-1)); | ||
| 351 | } | ||
| 352 | break; | ||
| 353 | |||
| 354 | case OP_SWAP: | ||
| 355 | { | ||
| 356 | // (x1 x2 -- x2 x1) | ||
| 357 | if (stack.size() < 2) | ||
| 358 | return false; | ||
| 359 | swap(stacktop(-2), stacktop(-1)); | ||
| 360 | } | ||
| 361 | break; | ||
| 362 | |||
| 363 | case OP_TUCK: | ||
| 364 | { | ||
| 365 | // (x1 x2 -- x2 x1 x2) | ||
| 366 | if (stack.size() < 2) | ||
| 367 | return false; | ||
| 368 | valtype vch = stacktop(-1); | ||
| 369 | stack.insert(stack.end()-2, vch); | ||
| 370 | } | ||
| 371 | break; | ||
| 372 | |||
| 373 | |||
| 374 | // | ||
| 375 | // Splice ops | ||
| 376 | // | ||
| 377 | case OP_CAT: | ||
| 378 | { | ||
| 379 | // (x1 x2 -- out) | ||
| 380 | if (stack.size() < 2) | ||
| 381 | return false; | ||
| 382 | valtype& vch1 = stacktop(-2); | ||
| 383 | valtype& vch2 = stacktop(-1); | ||
| 384 | vch1.insert(vch1.end(), vch2.begin(), vch2.end()); | ||
| 385 | stack.pop_back(); | ||
| 386 | } | ||
| 387 | break; | ||
| 388 | |||
| 389 | case OP_SUBSTR: | ||
| 390 | { | ||
| 391 | // (in begin size -- out) | ||
| 392 | if (stack.size() < 3) | ||
| 393 | return false; | ||
| 394 | valtype& vch = stacktop(-3); | ||
| 395 | int nBegin = CBigNum(stacktop(-2)).getint(); | ||
| 396 | int nEnd = nBegin + CBigNum(stacktop(-1)).getint(); | ||
| 397 | if (nBegin < 0 || nEnd < nBegin) | ||
| 398 | return false; | ||
| 399 | if (nBegin > vch.size()) | ||
| 400 | nBegin = vch.size(); | ||
| 401 | if (nEnd > vch.size()) | ||
| 402 | nEnd = vch.size(); | ||
| 403 | vch.erase(vch.begin() + nEnd, vch.end()); | ||
| 404 | vch.erase(vch.begin(), vch.begin() + nBegin); | ||
| 405 | stack.pop_back(); | ||
| 406 | stack.pop_back(); | ||
| 407 | } | ||
| 408 | break; | ||
| 409 | |||
| 410 | case OP_LEFT: | ||
| 411 | case OP_RIGHT: | ||
| 412 | { | ||
| 413 | // (in size -- out) | ||
| 414 | if (stack.size() < 2) | ||
| 415 | return false; | ||
| 416 | valtype& vch = stacktop(-2); | ||
| 417 | int nSize = CBigNum(stacktop(-1)).getint(); | ||
| 418 | if (nSize < 0) | ||
| 419 | return false; | ||
| 420 | if (nSize > vch.size()) | ||
| 421 | nSize = vch.size(); | ||
| 422 | if (opcode == OP_LEFT) | ||
| 423 | vch.erase(vch.begin() + nSize, vch.end()); | ||
| 424 | else | ||
| 425 | vch.erase(vch.begin(), vch.end() - nSize); | ||
| 426 | stack.pop_back(); | ||
| 427 | } | ||
| 428 | break; | ||
| 429 | |||
| 430 | case OP_SIZE: | ||
| 431 | { | ||
| 432 | // (in -- in size) | ||
| 433 | if (stack.size() < 1) | ||
| 434 | return false; | ||
| 435 | CBigNum bn(stacktop(-1).size()); | ||
| 436 | stack.push_back(bn.getvch()); | ||
| 437 | } | ||
| 438 | break; | ||
| 439 | |||
| 440 | |||
| 441 | // | ||
| 442 | // Bitwise logic | ||
| 443 | // | ||
| 444 | case OP_INVERT: | ||
| 445 | { | ||
| 446 | // (in - out) | ||
| 447 | if (stack.size() < 1) | ||
| 448 | return false; | ||
| 449 | valtype& vch = stacktop(-1); | ||
| 450 | for (int i = 0; i < vch.size(); i++) | ||
| 451 | vch[i] = ~vch[i]; | ||
| 452 | } | ||
| 453 | break; | ||
| 454 | |||
| 455 | case OP_AND: | ||
| 456 | case OP_OR: | ||
| 457 | case OP_XOR: | ||
| 458 | { | ||
| 459 | // (x1 x2 - out) | ||
| 460 | if (stack.size() < 2) | ||
| 461 | return false; | ||
| 462 | valtype& vch1 = stacktop(-2); | ||
| 463 | valtype& vch2 = stacktop(-1); | ||
| 464 | MakeSameSize(vch1, vch2); | ||
| 465 | if (opcode == OP_AND) | ||
| 466 | { | ||
| 467 | for (int i = 0; i < vch1.size(); i++) | ||
| 468 | vch1[i] &= vch2[i]; | ||
| 469 | } | ||
| 470 | else if (opcode == OP_OR) | ||
| 471 | { | ||
| 472 | for (int i = 0; i < vch1.size(); i++) | ||
| 473 | vch1[i] |= vch2[i]; | ||
| 474 | } | ||
| 475 | else if (opcode == OP_XOR) | ||
| 476 | { | ||
| 477 | for (int i = 0; i < vch1.size(); i++) | ||
| 478 | vch1[i] ^= vch2[i]; | ||
| 479 | } | ||
| 480 | stack.pop_back(); | ||
| 481 | } | ||
| 482 | break; | ||
| 483 | |||
| 484 | case OP_EQUAL: | ||
| 485 | case OP_EQUALVERIFY: | ||
| 486 | //case OP_NOTEQUAL: // use OP_NUMNOTEQUAL | ||
| 487 | { | ||
| 488 | // (x1 x2 - bool) | ||
| 489 | if (stack.size() < 2) | ||
| 490 | return false; | ||
| 491 | valtype& vch1 = stacktop(-2); | ||
| 492 | valtype& vch2 = stacktop(-1); | ||
| 493 | bool fEqual = (vch1 == vch2); | ||
| 494 | // OP_NOTEQUAL is disabled because it would be too easy to say | ||
| 495 | // something like n != 1 and have some wiseguy pass in 1 with extra | ||
| 496 | // zero bytes after it (numerically, 0x01 == 0x0001 == 0x000001) | ||
| 497 | //if (opcode == OP_NOTEQUAL) | ||
| 498 | // fEqual = !fEqual; | ||
| 499 | stack.pop_back(); | ||
| 500 | stack.pop_back(); | ||
| 501 | stack.push_back(fEqual ? vchTrue : vchFalse); | ||
| 502 | if (opcode == OP_EQUALVERIFY) | ||
| 503 | { | ||
| 504 | if (fEqual) | ||
| 505 | stack.pop_back(); | ||
| 506 | else | ||
| 507 | pc = pend; | ||
| 508 | } | ||
| 509 | } | ||
| 510 | break; | ||
| 511 | |||
| 512 | |||
| 513 | // | ||
| 514 | // Numeric | ||
| 515 | // | ||
| 516 | case OP_1ADD: | ||
| 517 | case OP_1SUB: | ||
| 518 | case OP_2MUL: | ||
| 519 | case OP_2DIV: | ||
| 520 | case OP_NEGATE: | ||
| 521 | case OP_ABS: | ||
| 522 | case OP_NOT: | ||
| 523 | case OP_0NOTEQUAL: | ||
| 524 | { | ||
| 525 | // (in -- out) | ||
| 526 | if (stack.size() < 1) | ||
| 527 | return false; | ||
| 528 | CBigNum bn(stacktop(-1)); | ||
| 529 | switch (opcode) | ||
| 530 | { | ||
| 531 | case OP_1ADD: bn += bnOne; break; | ||
| 532 | case OP_1SUB: bn -= bnOne; break; | ||
| 533 | case OP_2MUL: bn <<= 1; break; | ||
| 534 | case OP_2DIV: bn >>= 1; break; | ||
| 535 | case OP_NEGATE: bn = -bn; break; | ||
| 536 | case OP_ABS: if (bn < bnZero) bn = -bn; break; | ||
| 537 | case OP_NOT: bn = (bn == bnZero); break; | ||
| 538 | case OP_0NOTEQUAL: bn = (bn != bnZero); break; | ||
| 539 | } | ||
| 540 | stack.pop_back(); | ||
| 541 | stack.push_back(bn.getvch()); | ||
| 542 | } | ||
| 543 | break; | ||
| 544 | |||
| 545 | case OP_ADD: | ||
| 546 | case OP_SUB: | ||
| 547 | case OP_MUL: | ||
| 548 | case OP_DIV: | ||
| 549 | case OP_MOD: | ||
| 550 | case OP_LSHIFT: | ||
| 551 | case OP_RSHIFT: | ||
| 552 | case OP_BOOLAND: | ||
| 553 | case OP_BOOLOR: | ||
| 554 | case OP_NUMEQUAL: | ||
| 555 | case OP_NUMEQUALVERIFY: | ||
| 556 | case OP_NUMNOTEQUAL: | ||
| 557 | case OP_LESSTHAN: | ||
| 558 | case OP_GREATERTHAN: | ||
| 559 | case OP_LESSTHANOREQUAL: | ||
| 560 | case OP_GREATERTHANOREQUAL: | ||
| 561 | case OP_MIN: | ||
| 562 | case OP_MAX: | ||
| 563 | { | ||
| 564 | // (x1 x2 -- out) | ||
| 565 | if (stack.size() < 2) | ||
| 566 | return false; | ||
| 567 | CBigNum bn1(stacktop(-2)); | ||
| 568 | CBigNum bn2(stacktop(-1)); | ||
| 569 | CBigNum bn; | ||
| 570 | switch (opcode) | ||
| 571 | { | ||
| 572 | case OP_ADD: | ||
| 573 | bn = bn1 + bn2; | ||
| 574 | break; | ||
| 575 | |||
| 576 | case OP_SUB: | ||
| 577 | bn = bn1 - bn2; | ||
| 578 | break; | ||
| 579 | |||
| 580 | case OP_MUL: | ||
| 581 | if (!BN_mul(bn.get(), bn1.get(), bn2.get(), pctx)) | ||
| 582 | return false; | ||
| 583 | break; | ||
| 584 | |||
| 585 | case OP_DIV: | ||
| 586 | if (!BN_div(bn.get(), NULL, bn1.get(), bn2.get(), pctx)) | ||
| 587 | return false; | ||
| 588 | break; | ||
| 589 | |||
| 590 | case OP_MOD: | ||
| 591 | if (!BN_mod(bn.get(), bn1.get(), bn2.get(), pctx)) | ||
| 592 | return false; | ||
| 593 | break; | ||
| 594 | |||
| 595 | case OP_LSHIFT: | ||
| 596 | if (bn2 < bnZero) | ||
| 597 | return false; | ||
| 598 | bn = bn1 << bn2.getulong(); | ||
| 599 | break; | ||
| 600 | |||
| 601 | case OP_RSHIFT: | ||
| 602 | if (bn2 < bnZero) | ||
| 603 | return false; | ||
| 604 | bn = bn1 >> bn2.getulong(); | ||
| 605 | break; | ||
| 606 | |||
| 607 | case OP_BOOLAND: bn = (bn1 != bnZero && bn2 != bnZero); break; | ||
| 608 | case OP_BOOLOR: bn = (bn1 != bnZero || bn2 != bnZero); break; | ||
| 609 | case OP_NUMEQUAL: bn = (bn1 == bn2); break; | ||
| 610 | case OP_NUMEQUALVERIFY: bn = (bn1 == bn2); break; | ||
| 611 | case OP_NUMNOTEQUAL: bn = (bn1 != bn2); break; | ||
| 612 | case OP_LESSTHAN: bn = (bn1 < bn2); break; | ||
| 613 | case OP_GREATERTHAN: bn = (bn1 > bn2); break; | ||
| 614 | case OP_LESSTHANOREQUAL: bn = (bn1 <= bn2); break; | ||
| 615 | case OP_GREATERTHANOREQUAL: bn = (bn1 >= bn2); break; | ||
| 616 | case OP_MIN: bn = (bn1 < bn2 ? bn1 : bn2); break; | ||
| 617 | case OP_MAX: bn = (bn1 > bn2 ? bn1 : bn2); break; | ||
| 618 | } | ||
| 619 | stack.pop_back(); | ||
| 620 | stack.pop_back(); | ||
| 621 | stack.push_back(bn.getvch()); | ||
| 622 | |||
| 623 | if (opcode == OP_NUMEQUALVERIFY) | ||
| 624 | { | ||
| 625 | if (CastToBool(stacktop(-1))) | ||
| 626 | stack.pop_back(); | ||
| 627 | else | ||
| 628 | pc = pend; | ||
| 629 | } | ||
| 630 | } | ||
| 631 | break; | ||
| 632 | |||
| 633 | case OP_WITHIN: | ||
| 634 | { | ||
| 635 | // (x min max -- out) | ||
| 636 | if (stack.size() < 3) | ||
| 637 | return false; | ||
| 638 | CBigNum bn1(stacktop(-3)); | ||
| 639 | CBigNum bn2(stacktop(-2)); | ||
| 640 | CBigNum bn3(stacktop(-1)); | ||
| 641 | bool fValue = (bn2 <= bn1 && bn1 < bn3); | ||
| 642 | stack.pop_back(); | ||
| 643 | stack.pop_back(); | ||
| 644 | stack.pop_back(); | ||
| 645 | stack.push_back(fValue ? vchTrue : vchFalse); | ||
| 646 | } | ||
| 647 | break; | ||
| 648 | |||
| 649 | |||
| 650 | // | ||
| 651 | // Crypto | ||
| 652 | // | ||
| 653 | case OP_RIPEMD160: | ||
| 654 | case OP_SHA1: | ||
| 655 | case OP_SHA256: | ||
| 656 | case OP_HASH160: | ||
| 657 | case OP_HASH256: | ||
| 658 | { | ||
| 659 | // (in -- hash) | ||
| 660 | if (stack.size() < 1) | ||
| 661 | return false; | ||
| 662 | valtype& vch = stacktop(-1); | ||
| 663 | valtype vchHash(opcode == OP_RIPEMD160 || opcode == OP_SHA1 || opcode == OP_HASH160 ? 20 : 32); | ||
| 664 | if (opcode == OP_RIPEMD160) | ||
| 665 | RIPEMD160(&vch[0], vch.size(), &vchHash[0]); | ||
| 666 | else if (opcode == OP_SHA1) | ||
| 667 | SHA1(&vch[0], vch.size(), &vchHash[0]); | ||
| 668 | else if (opcode == OP_SHA256) | ||
| 669 | SHA256(&vch[0], vch.size(), &vchHash[0]); | ||
| 670 | else if (opcode == OP_HASH160) | ||
| 671 | { | ||
| 672 | uint160 hash160 = Hash160(vch); | ||
| 673 | memcpy(&vchHash[0], &hash160, sizeof(hash160)); | ||
| 674 | } | ||
| 675 | else if (opcode == OP_HASH256) | ||
| 676 | { | ||
| 677 | uint256 hash = Hash(vch.begin(), vch.end()); | ||
| 678 | memcpy(&vchHash[0], &hash, sizeof(hash)); | ||
| 679 | } | ||
| 680 | stack.pop_back(); | ||
| 681 | stack.push_back(vchHash); | ||
| 682 | } | ||
| 683 | break; | ||
| 684 | |||
| 685 | case OP_CODESEPARATOR: | ||
| 686 | { | ||
| 687 | // Hash starts after the code separator | ||
| 688 | pbegincodehash = pc; | ||
| 689 | } | ||
| 690 | break; | ||
| 691 | |||
| 692 | case OP_CHECKSIG: | ||
| 693 | case OP_CHECKSIGVERIFY: | ||
| 694 | { | ||
| 695 | // (sig pubkey -- bool) | ||
| 696 | if (stack.size() < 2) | ||
| 697 | return false; | ||
| 698 | |||
| 699 | valtype& vchSig = stacktop(-2); | ||
| 700 | valtype& vchPubKey = stacktop(-1); | ||
| 701 | |||
| 702 | ////// debug print | ||
| 703 | //PrintHex(vchSig.begin(), vchSig.end(), "sig: %s\n"); | ||
| 704 | //PrintHex(vchPubKey.begin(), vchPubKey.end(), "pubkey: %s\n"); | ||
| 705 | |||
| 706 | // Subset of script starting at the most recent codeseparator | ||
| 707 | CScript scriptCode(pbegincodehash, pend); | ||
| 708 | |||
| 709 | // Drop the signature, since there's no way for a signature to sign itself | ||
| 710 | scriptCode.FindAndDelete(CScript(vchSig)); | ||
| 711 | |||
| 712 | bool fSuccess = CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType); | ||
| 713 | |||
| 714 | stack.pop_back(); | ||
| 715 | stack.pop_back(); | ||
| 716 | stack.push_back(fSuccess ? vchTrue : vchFalse); | ||
| 717 | if (opcode == OP_CHECKSIGVERIFY) | ||
| 718 | { | ||
| 719 | if (fSuccess) | ||
| 720 | stack.pop_back(); | ||
| 721 | else | ||
| 722 | pc = pend; | ||
| 723 | } | ||
| 724 | } | ||
| 725 | break; | ||
| 726 | |||
| 727 | case OP_CHECKMULTISIG: | ||
| 728 | case OP_CHECKMULTISIGVERIFY: | ||
| 729 | { | ||
| 730 | // ([sig ...] num_of_signatures [pubkey ...] num_of_pubkeys -- bool) | ||
| 731 | |||
| 732 | int i = 1; | ||
| 733 | if (stack.size() < i) | ||
| 734 | return false; | ||
| 735 | |||
| 736 | int nKeysCount = CBigNum(stacktop(-i)).getint(); | ||
| 737 | if (nKeysCount < 0) | ||
| 738 | return false; | ||
| 739 | int ikey = ++i; | ||
| 740 | i += nKeysCount; | ||
| 741 | if (stack.size() < i) | ||
| 742 | return false; | ||
| 743 | |||
| 744 | int nSigsCount = CBigNum(stacktop(-i)).getint(); | ||
| 745 | if (nSigsCount < 0 || nSigsCount > nKeysCount) | ||
| 746 | return false; | ||
| 747 | int isig = ++i; | ||
| 748 | i += nSigsCount; | ||
| 749 | if (stack.size() < i) | ||
| 750 | return false; | ||
| 751 | |||
| 752 | // Subset of script starting at the most recent codeseparator | ||
| 753 | CScript scriptCode(pbegincodehash, pend); | ||
| 754 | |||
| 755 | // Drop the signatures, since there's no way for a signature to sign itself | ||
| 756 | for (int i = 0; i < nSigsCount; i++) | ||
| 757 | { | ||
| 758 | valtype& vchSig = stacktop(-isig-i); | ||
| 759 | scriptCode.FindAndDelete(CScript(vchSig)); | ||
| 760 | } | ||
| 761 | |||
| 762 | bool fSuccess = true; | ||
| 763 | while (fSuccess && nSigsCount > 0) | ||
| 764 | { | ||
| 765 | valtype& vchSig = stacktop(-isig); | ||
| 766 | valtype& vchPubKey = stacktop(-ikey); | ||
| 767 | |||
| 768 | // Check signature | ||
| 769 | if (CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType)) | ||
| 770 | { | ||
| 771 | isig++; | ||
| 772 | nSigsCount--; | ||
| 773 | } | ||
| 774 | ikey++; | ||
| 775 | nKeysCount--; | ||
| 776 | |||
| 777 | // If there are more signatures left than keys left, | ||
| 778 | // then too many signatures have failed | ||
| 779 | if (nSigsCount > nKeysCount) | ||
| 780 | fSuccess = false; | ||
| 781 | } | ||
| 782 | |||
| 783 | while (i-- > 0) | ||
| 784 | stack.pop_back(); | ||
| 785 | stack.push_back(fSuccess ? vchTrue : vchFalse); | ||
| 786 | |||
| 787 | if (opcode == OP_CHECKMULTISIGVERIFY) | ||
| 788 | { | ||
| 789 | if (fSuccess) | ||
| 790 | stack.pop_back(); | ||
| 791 | else | ||
| 792 | pc = pend; | ||
| 793 | } | ||
| 794 | } | ||
| 795 | break; | ||
| 796 | |||
| 797 | default: | ||
| 798 | return false; | ||
| 799 | } | ||
| 800 | } | ||
| 801 | |||
| 802 | |||
| 803 | if (pvStackRet) | ||
| 804 | *pvStackRet = stack; | ||
| 805 | return (stack.empty() ? false : CastToBool(stack.back())); | ||
| 806 | } | ||
| 807 | |||
| 808 | #undef top | ||
| 809 | |||
| 810 | |||
| 811 | |||
| 812 | |||
| 813 | |||
| 814 | |||
| 815 | |||
| 816 | |||
| 817 | |||
| 818 | uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType) | ||
| 819 | { | ||
| 820 | if (nIn >= txTo.vin.size()) | ||
| 821 | { | ||
| 822 | printf("ERROR: SignatureHash() : nIn=%d out of range\n", nIn); | ||
| 823 | return 1; | ||
| 824 | } | ||
| 825 | CTransaction txTmp(txTo); | ||
| 826 | |||
| 827 | // In case concatenating two scripts ends up with two codeseparators, | ||
| 828 | // or an extra one at the end, this prevents all those possible incompatibilities. | ||
| 829 | scriptCode.FindAndDelete(CScript(OP_CODESEPARATOR)); | ||
| 830 | |||
| 831 | // Blank out other inputs' signatures | ||
| 832 | for (int i = 0; i < txTmp.vin.size(); i++) | ||
| 833 | txTmp.vin[i].scriptSig = CScript(); | ||
| 834 | txTmp.vin[nIn].scriptSig = scriptCode; | ||
| 835 | |||
| 836 | // Blank out some of the outputs | ||
| 837 | if ((nHashType & 0x1f) == SIGHASH_NONE) | ||
| 838 | { | ||
| 839 | // Wildcard payee | ||
| 840 | txTmp.vout.clear(); | ||
| 841 | |||
| 842 | // Let the others update at will | ||
| 843 | for (int i = 0; i < txTmp.vin.size(); i++) | ||
| 844 | if (i != nIn) | ||
| 845 | txTmp.vin[i].nSequence = 0; | ||
| 846 | } | ||
| 847 | else if ((nHashType & 0x1f) == SIGHASH_SINGLE) | ||
| 848 | { | ||
| 849 | // Only lockin the txout payee at same index as txin | ||
| 850 | unsigned int nOut = nIn; | ||
| 851 | if (nOut >= txTmp.vout.size()) | ||
| 852 | { | ||
| 853 | printf("ERROR: SignatureHash() : nOut=%d out of range\n", nOut); | ||
| 854 | return 1; | ||
| 855 | } | ||
| 856 | txTmp.vout.resize(nOut+1); | ||
| 857 | for (int i = 0; i < nOut; i++) | ||
| 858 | txTmp.vout[i].SetNull(); | ||
| 859 | |||
| 860 | // Let the others update at will | ||
| 861 | for (int i = 0; i < txTmp.vin.size(); i++) | ||
| 862 | if (i != nIn) | ||
| 863 | txTmp.vin[i].nSequence = 0; | ||
| 864 | } | ||
| 865 | |||
| 866 | // Blank out other inputs completely, not recommended for open transactions | ||
| 867 | if (nHashType & SIGHASH_ANYONECANPAY) | ||
| 868 | { | ||
| 869 | txTmp.vin[0] = txTmp.vin[nIn]; | ||
| 870 | txTmp.vin.resize(1); | ||
| 871 | } | ||
| 872 | |||
| 873 | // Serialize and hash | ||
| 874 | CDataStream ss(SER_GETHASH); | ||
| 875 | ss.reserve(10000); | ||
| 876 | ss << txTmp << nHashType; | ||
| 877 | return Hash(ss.begin(), ss.end()); | ||
| 878 | } | ||
| 879 | |||
| 880 | |||
| 881 | bool CheckSig(vector<unsigned char> vchSig, vector<unsigned char> vchPubKey, CScript scriptCode, | ||
| 882 | const CTransaction& txTo, unsigned int nIn, int nHashType) | ||
| 883 | { | ||
| 884 | CKey key; | ||
| 885 | if (!key.SetPubKey(vchPubKey)) | ||
| 886 | return false; | ||
| 887 | |||
| 888 | // Hash type is one byte tacked on to the end of the signature | ||
| 889 | if (vchSig.empty()) | ||
| 890 | return false; | ||
| 891 | if (nHashType == 0) | ||
| 892 | nHashType = vchSig.back(); | ||
| 893 | else if (nHashType != vchSig.back()) | ||
| 894 | return false; | ||
| 895 | vchSig.pop_back(); | ||
| 896 | |||
| 897 | if (key.Verify(SignatureHash(scriptCode, txTo, nIn, nHashType), vchSig)) | ||
| 898 | return true; | ||
| 899 | |||
| 900 | return false; | ||
| 901 | } | ||
| 902 | |||
| 903 | |||
| 904 | |||
| 905 | |||
| 906 | |||
| 907 | |||
| 908 | |||
| 909 | |||
| 910 | |||
| 911 | |||
| 912 | |||
| 913 | bool Solver(const CScript& scriptPubKey, vector<pair<opcodetype, valtype> >& vSolutionRet) | ||
| 914 | { | ||
| 915 | // Templates | ||
| 916 | static vector<CScript> vTemplates; | ||
| 917 | if (vTemplates.empty()) | ||
| 918 | { | ||
| 919 | // Standard tx, sender provides pubkey, receiver adds signature | ||
| 920 | vTemplates.push_back(CScript() << OP_PUBKEY << OP_CHECKSIG); | ||
| 921 | |||
| 922 | // Short account number tx, sender provides hash of pubkey, receiver provides signature and pubkey | ||
| 923 | vTemplates.push_back(CScript() << OP_DUP << OP_HASH160 << OP_PUBKEYHASH << OP_EQUALVERIFY << OP_CHECKSIG); | ||
| 924 | } | ||
| 925 | |||
| 926 | // Scan templates | ||
| 927 | const CScript& script1 = scriptPubKey; | ||
| 928 | foreach(const CScript& script2, vTemplates) | ||
| 929 | { | ||
| 930 | vSolutionRet.clear(); | ||
| 931 | opcodetype opcode1, opcode2; | ||
| 932 | vector<unsigned char> vch1, vch2; | ||
| 933 | |||
| 934 | // Compare | ||
| 935 | CScript::const_iterator pc1 = script1.begin(); | ||
| 936 | CScript::const_iterator pc2 = script2.begin(); | ||
| 937 | loop | ||
| 938 | { | ||
| 939 | bool f1 = script1.GetOp(pc1, opcode1, vch1); | ||
| 940 | bool f2 = script2.GetOp(pc2, opcode2, vch2); | ||
| 941 | if (!f1 && !f2) | ||
| 942 | { | ||
| 943 | // Success | ||
| 944 | reverse(vSolutionRet.begin(), vSolutionRet.end()); | ||
| 945 | return true; | ||
| 946 | } | ||
| 947 | else if (f1 != f2) | ||
| 948 | { | ||
| 949 | break; | ||
| 950 | } | ||
| 951 | else if (opcode2 == OP_PUBKEY) | ||
| 952 | { | ||
| 953 | if (vch1.size() <= sizeof(uint256)) | ||
| 954 | break; | ||
| 955 | vSolutionRet.push_back(make_pair(opcode2, vch1)); | ||
| 956 | } | ||
| 957 | else if (opcode2 == OP_PUBKEYHASH) | ||
| 958 | { | ||
| 959 | if (vch1.size() != sizeof(uint160)) | ||
| 960 | break; | ||
| 961 | vSolutionRet.push_back(make_pair(opcode2, vch1)); | ||
| 962 | } | ||
| 963 | else if (opcode1 != opcode2) | ||
| 964 | { | ||
| 965 | break; | ||
| 966 | } | ||
| 967 | } | ||
| 968 | } | ||
| 969 | |||
| 970 | vSolutionRet.clear(); | ||
| 971 | return false; | ||
| 972 | } | ||
| 973 | |||
| 974 | |||
| 975 | bool Solver(const CScript& scriptPubKey, uint256 hash, int nHashType, CScript& scriptSigRet) | ||
| 976 | { | ||
| 977 | scriptSigRet.clear(); | ||
| 978 | |||
| 979 | vector<pair<opcodetype, valtype> > vSolution; | ||
| 980 | if (!Solver(scriptPubKey, vSolution)) | ||
| 981 | return false; | ||
| 982 | |||
| 983 | // Compile solution | ||
| 984 | CRITICAL_BLOCK(cs_mapKeys) | ||
| 985 | { | ||
| 986 | foreach(PAIRTYPE(opcodetype, valtype)& item, vSolution) | ||
| 987 | { | ||
| 988 | if (item.first == OP_PUBKEY) | ||
| 989 | { | ||
| 990 | // Sign | ||
| 991 | const valtype& vchPubKey = item.second; | ||
| 992 | if (!mapKeys.count(vchPubKey)) | ||
| 993 | return false; | ||
| 994 | if (hash != 0) | ||
| 995 | { | ||
| 996 | vector<unsigned char> vchSig; | ||
| 997 | if (!CKey::Sign(mapKeys[vchPubKey], hash, vchSig)) | ||
| 998 | return false; | ||
| 999 | vchSig.push_back((unsigned char)nHashType); | ||
| 1000 | scriptSigRet << vchSig; | ||
| 1001 | } | ||
| 1002 | } | ||
| 1003 | else if (item.first == OP_PUBKEYHASH) | ||
| 1004 | { | ||
| 1005 | // Sign and give pubkey | ||
| 1006 | map<uint160, valtype>::iterator mi = mapPubKeys.find(uint160(item.second)); | ||
| 1007 | if (mi == mapPubKeys.end()) | ||
| 1008 | return false; | ||
| 1009 | const vector<unsigned char>& vchPubKey = (*mi).second; | ||
| 1010 | if (!mapKeys.count(vchPubKey)) | ||
| 1011 | return false; | ||
| 1012 | if (hash != 0) | ||
| 1013 | { | ||
| 1014 | vector<unsigned char> vchSig; | ||
| 1015 | if (!CKey::Sign(mapKeys[vchPubKey], hash, vchSig)) | ||
| 1016 | return false; | ||
| 1017 | vchSig.push_back((unsigned char)nHashType); | ||
| 1018 | scriptSigRet << vchSig << vchPubKey; | ||
| 1019 | } | ||
| 1020 | } | ||
| 1021 | } | ||
| 1022 | } | ||
| 1023 | |||
| 1024 | return true; | ||
| 1025 | } | ||
| 1026 | |||
| 1027 | |||
| 1028 | bool IsMine(const CScript& scriptPubKey) | ||
| 1029 | { | ||
| 1030 | CScript scriptSig; | ||
| 1031 | return Solver(scriptPubKey, 0, 0, scriptSig); | ||
| 1032 | } | ||
| 1033 | |||
| 1034 | |||
| 1035 | bool ExtractPubKey(const CScript& scriptPubKey, bool fMineOnly, vector<unsigned char>& vchPubKeyRet) | ||
| 1036 | { | ||
| 1037 | vchPubKeyRet.clear(); | ||
| 1038 | |||
| 1039 | vector<pair<opcodetype, valtype> > vSolution; | ||
| 1040 | if (!Solver(scriptPubKey, vSolution)) | ||
| 1041 | return false; | ||
| 1042 | |||
| 1043 | CRITICAL_BLOCK(cs_mapKeys) | ||
| 1044 | { | ||
| 1045 | foreach(PAIRTYPE(opcodetype, valtype)& item, vSolution) | ||
| 1046 | { | ||
| 1047 | valtype vchPubKey; | ||
| 1048 | if (item.first == OP_PUBKEY) | ||
| 1049 | { | ||
| 1050 | vchPubKey = item.second; | ||
| 1051 | } | ||
| 1052 | else if (item.first == OP_PUBKEYHASH) | ||
| 1053 | { | ||
| 1054 | map<uint160, valtype>::iterator mi = mapPubKeys.find(uint160(item.second)); | ||
| 1055 | if (mi == mapPubKeys.end()) | ||
| 1056 | continue; | ||
| 1057 | vchPubKey = (*mi).second; | ||
| 1058 | } | ||
| 1059 | if (!fMineOnly || mapKeys.count(vchPubKey)) | ||
| 1060 | { | ||
| 1061 | vchPubKeyRet = vchPubKey; | ||
| 1062 | return true; | ||
| 1063 | } | ||
| 1064 | } | ||
| 1065 | } | ||
| 1066 | return false; | ||
| 1067 | } | ||
| 1068 | |||
| 1069 | |||
| 1070 | bool ExtractHash160(const CScript& scriptPubKey, uint160& hash160Ret) | ||
| 1071 | { | ||
| 1072 | hash160Ret = 0; | ||
| 1073 | |||
| 1074 | vector<pair<opcodetype, valtype> > vSolution; | ||
| 1075 | if (!Solver(scriptPubKey, vSolution)) | ||
| 1076 | return false; | ||
| 1077 | |||
| 1078 | foreach(PAIRTYPE(opcodetype, valtype)& item, vSolution) | ||
| 1079 | { | ||
| 1080 | if (item.first == OP_PUBKEYHASH) | ||
| 1081 | { | ||
| 1082 | hash160Ret = uint160(item.second); | ||
| 1083 | return true; | ||
| 1084 | } | ||
| 1085 | } | ||
| 1086 | return false; | ||
| 1087 | } | ||
| 1088 | |||
| 1089 | |||
| 1090 | bool SignSignature(const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType, CScript scriptPrereq) | ||
| 1091 | { | ||
| 1092 | assert(nIn < txTo.vin.size()); | ||
| 1093 | CTxIn& txin = txTo.vin[nIn]; | ||
| 1094 | assert(txin.prevout.n < txFrom.vout.size()); | ||
| 1095 | const CTxOut& txout = txFrom.vout[txin.prevout.n]; | ||
| 1096 | |||
| 1097 | // Leave out the signature from the hash, since a signature can't sign itself. | ||
| 1098 | // The checksig op will also drop the signatures from its hash. | ||
| 1099 | uint256 hash = SignatureHash(scriptPrereq + txout.scriptPubKey, txTo, nIn, nHashType); | ||
| 1100 | |||
| 1101 | if (!Solver(txout.scriptPubKey, hash, nHashType, txin.scriptSig)) | ||
| 1102 | return false; | ||
| 1103 | |||
| 1104 | txin.scriptSig = scriptPrereq + txin.scriptSig; | ||
| 1105 | |||
| 1106 | // Test solution | ||
| 1107 | if (scriptPrereq.empty()) | ||
| 1108 | if (!EvalScript(txin.scriptSig + CScript(OP_CODESEPARATOR) + txout.scriptPubKey, txTo, nIn)) | ||
| 1109 | return false; | ||
| 1110 | |||
| 1111 | return true; | ||
| 1112 | } | ||
| 1113 | |||
| 1114 | |||
| 1115 | bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsigned int nIn, int nHashType) | ||
| 1116 | { | ||
| 1117 | assert(nIn < txTo.vin.size()); | ||
| 1118 | const CTxIn& txin = txTo.vin[nIn]; | ||
| 1119 | if (txin.prevout.n >= txFrom.vout.size()) | ||
| 1120 | return false; | ||
| 1121 | const CTxOut& txout = txFrom.vout[txin.prevout.n]; | ||
| 1122 | |||
| 1123 | if (txin.prevout.hash != txFrom.GetHash()) | ||
| 1124 | return false; | ||
| 1125 | |||
| 1126 | return EvalScript(txin.scriptSig + CScript(OP_CODESEPARATOR) + txout.scriptPubKey, txTo, nIn, nHashType); | ||
| 1127 | } | ||
diff --git a/src/script.h b/src/script.h new file mode 100644 index 0000000..d52d06b --- /dev/null +++ b/src/script.h | |||
| @@ -0,0 +1,597 @@ | |||
| 1 | // Copyright (c) 2009 Satoshi Nakamoto | ||
| 2 | // Distributed under the MIT/X11 software license, see the accompanying | ||
| 3 | // file license.txt or http://www.opensource.org/licenses/mit-license.php. | ||
| 4 | |||
| 5 | class CTransaction; | ||
| 6 | |||
| 7 | enum | ||
| 8 | { | ||
| 9 | SIGHASH_ALL = 1, | ||
| 10 | SIGHASH_NONE = 2, | ||
| 11 | SIGHASH_SINGLE = 3, | ||
| 12 | SIGHASH_ANYONECANPAY = 0x80, | ||
| 13 | }; | ||
| 14 | |||
| 15 | |||
| 16 | |||
| 17 | enum opcodetype | ||
| 18 | { | ||
| 19 | // push value | ||
| 20 | OP_0=0, | ||
| 21 | OP_FALSE=OP_0, | ||
| 22 | OP_PUSHDATA1=76, | ||
| 23 | OP_PUSHDATA2, | ||
| 24 | OP_PUSHDATA4, | ||
| 25 | OP_1NEGATE, | ||
| 26 | OP_RESERVED, | ||
| 27 | OP_1, | ||
| 28 | OP_TRUE=OP_1, | ||
| 29 | OP_2, | ||
| 30 | OP_3, | ||
| 31 | OP_4, | ||
| 32 | OP_5, | ||
| 33 | OP_6, | ||
| 34 | OP_7, | ||
| 35 | OP_8, | ||
| 36 | OP_9, | ||
| 37 | OP_10, | ||
| 38 | OP_11, | ||
| 39 | OP_12, | ||
| 40 | OP_13, | ||
| 41 | OP_14, | ||
| 42 | OP_15, | ||
| 43 | OP_16, | ||
| 44 | |||
| 45 | // control | ||
| 46 | OP_NOP, | ||
| 47 | OP_VER, | ||
| 48 | OP_IF, | ||
| 49 | OP_NOTIF, | ||
| 50 | OP_VERIF, | ||
| 51 | OP_VERNOTIF, | ||
| 52 | OP_ELSE, | ||
| 53 | OP_ENDIF, | ||
| 54 | OP_VERIFY, | ||
| 55 | OP_RETURN, | ||
| 56 | |||
| 57 | // stack ops | ||
| 58 | OP_TOALTSTACK, | ||
| 59 | OP_FROMALTSTACK, | ||
| 60 | OP_2DROP, | ||
| 61 | OP_2DUP, | ||
| 62 | OP_3DUP, | ||
| 63 | OP_2OVER, | ||
| 64 | OP_2ROT, | ||
| 65 | OP_2SWAP, | ||
| 66 | OP_IFDUP, | ||
| 67 | OP_DEPTH, | ||
| 68 | OP_DROP, | ||
| 69 | OP_DUP, | ||
| 70 | OP_NIP, | ||
| 71 | OP_OVER, | ||
| 72 | OP_PICK, | ||
| 73 | OP_ROLL, | ||
| 74 | OP_ROT, | ||
| 75 | OP_SWAP, | ||
| 76 | OP_TUCK, | ||
| 77 | |||
| 78 | // splice ops | ||
| 79 | OP_CAT, | ||
| 80 | OP_SUBSTR, | ||
| 81 | OP_LEFT, | ||
| 82 | OP_RIGHT, | ||
| 83 | OP_SIZE, | ||
| 84 | |||
| 85 | // bit logic | ||
| 86 | OP_INVERT, | ||
| 87 | OP_AND, | ||
| 88 | OP_OR, | ||
| 89 | OP_XOR, | ||
| 90 | OP_EQUAL, | ||
| 91 | OP_EQUALVERIFY, | ||
| 92 | OP_RESERVED1, | ||
| 93 | OP_RESERVED2, | ||
| 94 | |||
| 95 | // numeric | ||
| 96 | OP_1ADD, | ||
| 97 | OP_1SUB, | ||
| 98 | OP_2MUL, | ||
| 99 | OP_2DIV, | ||
| 100 | OP_NEGATE, | ||
| 101 | OP_ABS, | ||
| 102 | OP_NOT, | ||
| 103 | OP_0NOTEQUAL, | ||
| 104 | |||
| 105 | OP_ADD, | ||
| 106 | OP_SUB, | ||
| 107 | OP_MUL, | ||
| 108 | OP_DIV, | ||
| 109 | OP_MOD, | ||
| 110 | OP_LSHIFT, | ||
| 111 | OP_RSHIFT, | ||
| 112 | |||
| 113 | OP_BOOLAND, | ||
| 114 | OP_BOOLOR, | ||
| 115 | OP_NUMEQUAL, | ||
| 116 | OP_NUMEQUALVERIFY, | ||
| 117 | OP_NUMNOTEQUAL, | ||
| 118 | OP_LESSTHAN, | ||
| 119 | OP_GREATERTHAN, | ||
| 120 | OP_LESSTHANOREQUAL, | ||
| 121 | OP_GREATERTHANOREQUAL, | ||
| 122 | OP_MIN, | ||
| 123 | OP_MAX, | ||
| 124 | |||
| 125 | OP_WITHIN, | ||
| 126 | |||
| 127 | // crypto | ||
| 128 | OP_RIPEMD160, | ||
| 129 | OP_SHA1, | ||
| 130 | OP_SHA256, | ||
| 131 | OP_HASH160, | ||
| 132 | OP_HASH256, | ||
| 133 | OP_CODESEPARATOR, | ||
| 134 | OP_CHECKSIG, | ||
| 135 | OP_CHECKSIGVERIFY, | ||
| 136 | OP_CHECKMULTISIG, | ||
| 137 | OP_CHECKMULTISIGVERIFY, | ||
| 138 | |||
| 139 | |||
| 140 | // multi-byte opcodes | ||
| 141 | OP_SINGLEBYTE_END = 0xF0, | ||
| 142 | OP_DOUBLEBYTE_BEGIN = 0xF000, | ||
| 143 | |||
| 144 | // template matching params | ||
| 145 | OP_PUBKEY, | ||
| 146 | OP_PUBKEYHASH, | ||
| 147 | |||
| 148 | |||
| 149 | |||
| 150 | OP_INVALIDOPCODE = 0xFFFF, | ||
| 151 | }; | ||
| 152 | |||
| 153 | |||
| 154 | |||
| 155 | |||
| 156 | |||
| 157 | |||
| 158 | |||
| 159 | |||
| 160 | inline const char* GetOpName(opcodetype opcode) | ||
| 161 | { | ||
| 162 | switch (opcode) | ||
| 163 | { | ||
| 164 | // push value | ||
| 165 | case OP_0 : return "0"; | ||
| 166 | case OP_PUSHDATA1 : return "OP_PUSHDATA1"; | ||
| 167 | case OP_PUSHDATA2 : return "OP_PUSHDATA2"; | ||
| 168 | case OP_PUSHDATA4 : return "OP_PUSHDATA4"; | ||
| 169 | case OP_1NEGATE : return "-1"; | ||
| 170 | case OP_RESERVED : return "OP_RESERVED"; | ||
| 171 | case OP_1 : return "1"; | ||
| 172 | case OP_2 : return "2"; | ||
| 173 | case OP_3 : return "3"; | ||
| 174 | case OP_4 : return "4"; | ||
| 175 | case OP_5 : return "5"; | ||
| 176 | case OP_6 : return "6"; | ||
| 177 | case OP_7 : return "7"; | ||
| 178 | case OP_8 : return "8"; | ||
| 179 | case OP_9 : return "9"; | ||
| 180 | case OP_10 : return "10"; | ||
| 181 | case OP_11 : return "11"; | ||
| 182 | case OP_12 : return "12"; | ||
| 183 | case OP_13 : return "13"; | ||
| 184 | case OP_14 : return "14"; | ||
| 185 | case OP_15 : return "15"; | ||
| 186 | case OP_16 : return "16"; | ||
| 187 | |||
| 188 | // control | ||
| 189 | case OP_NOP : return "OP_NOP"; | ||
| 190 | case OP_VER : return "OP_VER"; | ||
| 191 | case OP_IF : return "OP_IF"; | ||
| 192 | case OP_NOTIF : return "OP_NOTIF"; | ||
| 193 | case OP_VERIF : return "OP_VERIF"; | ||
| 194 | case OP_VERNOTIF : return "OP_VERNOTIF"; | ||
| 195 | case OP_ELSE : return "OP_ELSE"; | ||
| 196 | case OP_ENDIF : return "OP_ENDIF"; | ||
| 197 | case OP_VERIFY : return "OP_VERIFY"; | ||
| 198 | case OP_RETURN : return "OP_RETURN"; | ||
| 199 | |||
| 200 | // stack ops | ||
| 201 | case OP_TOALTSTACK : return "OP_TOALTSTACK"; | ||
| 202 | case OP_FROMALTSTACK : return "OP_FROMALTSTACK"; | ||
| 203 | case OP_2DROP : return "OP_2DROP"; | ||
| 204 | case OP_2DUP : return "OP_2DUP"; | ||
| 205 | case OP_3DUP : return "OP_3DUP"; | ||
| 206 | case OP_2OVER : return "OP_2OVER"; | ||
| 207 | case OP_2ROT : return "OP_2ROT"; | ||
| 208 | case OP_2SWAP : return "OP_2SWAP"; | ||
| 209 | case OP_IFDUP : return "OP_IFDUP"; | ||
| 210 | case OP_DEPTH : return "OP_DEPTH"; | ||
| 211 | case OP_DROP : return "OP_DROP"; | ||
| 212 | case OP_DUP : return "OP_DUP"; | ||
| 213 | case OP_NIP : return "OP_NIP"; | ||
| 214 | case OP_OVER : return "OP_OVER"; | ||
| 215 | case OP_PICK : return "OP_PICK"; | ||
| 216 | case OP_ROLL : return "OP_ROLL"; | ||
| 217 | case OP_ROT : return "OP_ROT"; | ||
| 218 | case OP_SWAP : return "OP_SWAP"; | ||
| 219 | case OP_TUCK : return "OP_TUCK"; | ||
| 220 | |||
| 221 | // splice ops | ||
| 222 | case OP_CAT : return "OP_CAT"; | ||
| 223 | case OP_SUBSTR : return "OP_SUBSTR"; | ||
| 224 | case OP_LEFT : return "OP_LEFT"; | ||
| 225 | case OP_RIGHT : return "OP_RIGHT"; | ||
| 226 | case OP_SIZE : return "OP_SIZE"; | ||
| 227 | |||
| 228 | // bit logic | ||
| 229 | case OP_INVERT : return "OP_INVERT"; | ||
| 230 | case OP_AND : return "OP_AND"; | ||
| 231 | case OP_OR : return "OP_OR"; | ||
| 232 | case OP_XOR : return "OP_XOR"; | ||
| 233 | case OP_EQUAL : return "OP_EQUAL"; | ||
| 234 | case OP_EQUALVERIFY : return "OP_EQUALVERIFY"; | ||
| 235 | case OP_RESERVED1 : return "OP_RESERVED1"; | ||
| 236 | case OP_RESERVED2 : return "OP_RESERVED2"; | ||
| 237 | |||
| 238 | // numeric | ||
| 239 | case OP_1ADD : return "OP_1ADD"; | ||
| 240 | case OP_1SUB : return "OP_1SUB"; | ||
| 241 | case OP_2MUL : return "OP_2MUL"; | ||
| 242 | case OP_2DIV : return "OP_2DIV"; | ||
| 243 | case OP_NEGATE : return "OP_NEGATE"; | ||
| 244 | case OP_ABS : return "OP_ABS"; | ||
| 245 | case OP_NOT : return "OP_NOT"; | ||
| 246 | case OP_0NOTEQUAL : return "OP_0NOTEQUAL"; | ||
| 247 | case OP_ADD : return "OP_ADD"; | ||
| 248 | case OP_SUB : return "OP_SUB"; | ||
| 249 | case OP_MUL : return "OP_MUL"; | ||
| 250 | case OP_DIV : return "OP_DIV"; | ||
| 251 | case OP_MOD : return "OP_MOD"; | ||
| 252 | case OP_LSHIFT : return "OP_LSHIFT"; | ||
| 253 | case OP_RSHIFT : return "OP_RSHIFT"; | ||
| 254 | case OP_BOOLAND : return "OP_BOOLAND"; | ||
| 255 | case OP_BOOLOR : return "OP_BOOLOR"; | ||
| 256 | case OP_NUMEQUAL : return "OP_NUMEQUAL"; | ||
| 257 | case OP_NUMEQUALVERIFY : return "OP_NUMEQUALVERIFY"; | ||
| 258 | case OP_NUMNOTEQUAL : return "OP_NUMNOTEQUAL"; | ||
| 259 | case OP_LESSTHAN : return "OP_LESSTHAN"; | ||
| 260 | case OP_GREATERTHAN : return "OP_GREATERTHAN"; | ||
| 261 | case OP_LESSTHANOREQUAL : return "OP_LESSTHANOREQUAL"; | ||
| 262 | case OP_GREATERTHANOREQUAL : return "OP_GREATERTHANOREQUAL"; | ||
| 263 | case OP_MIN : return "OP_MIN"; | ||
| 264 | case OP_MAX : return "OP_MAX"; | ||
| 265 | case OP_WITHIN : return "OP_WITHIN"; | ||
| 266 | |||
| 267 | // crypto | ||
| 268 | case OP_RIPEMD160 : return "OP_RIPEMD160"; | ||
| 269 | case OP_SHA1 : return "OP_SHA1"; | ||
| 270 | case OP_SHA256 : return "OP_SHA256"; | ||
| 271 | case OP_HASH160 : return "OP_HASH160"; | ||
| 272 | case OP_HASH256 : return "OP_HASH256"; | ||
| 273 | case OP_CODESEPARATOR : return "OP_CODESEPARATOR"; | ||
| 274 | case OP_CHECKSIG : return "OP_CHECKSIG"; | ||
| 275 | case OP_CHECKSIGVERIFY : return "OP_CHECKSIGVERIFY"; | ||
| 276 | case OP_CHECKMULTISIG : return "OP_CHECKMULTISIG"; | ||
| 277 | case OP_CHECKMULTISIGVERIFY : return "OP_CHECKMULTISIGVERIFY"; | ||
| 278 | |||
| 279 | |||
| 280 | |||
| 281 | // multi-byte opcodes | ||
| 282 | case OP_SINGLEBYTE_END : return "OP_SINGLEBYTE_END"; | ||
| 283 | case OP_DOUBLEBYTE_BEGIN : return "OP_DOUBLEBYTE_BEGIN"; | ||
| 284 | case OP_PUBKEY : return "OP_PUBKEY"; | ||
| 285 | case OP_PUBKEYHASH : return "OP_PUBKEYHASH"; | ||
| 286 | |||
| 287 | |||
| 288 | |||
| 289 | case OP_INVALIDOPCODE : return "OP_INVALIDOPCODE"; | ||
| 290 | default: | ||
| 291 | return "UNKNOWN_OPCODE"; | ||
| 292 | } | ||
| 293 | }; | ||
| 294 | |||
| 295 | |||
| 296 | |||
| 297 | |||
| 298 | inline string ValueString(const vector<unsigned char>& vch) | ||
| 299 | { | ||
| 300 | if (vch.size() <= 4) | ||
| 301 | return strprintf("%d", CBigNum(vch).getint()); | ||
| 302 | else | ||
| 303 | return HexNumStr(vch.begin(), vch.end()); | ||
| 304 | //return string("(") + HexStr(vch.begin(), vch.end()) + string(")"); | ||
| 305 | } | ||
| 306 | |||
| 307 | inline string StackString(const vector<vector<unsigned char> >& vStack) | ||
| 308 | { | ||
| 309 | string str; | ||
| 310 | foreach(const vector<unsigned char>& vch, vStack) | ||
| 311 | { | ||
| 312 | if (!str.empty()) | ||
| 313 | str += " "; | ||
| 314 | str += ValueString(vch); | ||
| 315 | } | ||
| 316 | return str; | ||
| 317 | } | ||
| 318 | |||
| 319 | |||
| 320 | |||
| 321 | |||
| 322 | |||
| 323 | |||
| 324 | |||
| 325 | |||
| 326 | |||
| 327 | class CScript : public vector<unsigned char> | ||
| 328 | { | ||
| 329 | protected: | ||
| 330 | CScript& push_int64(int64 n) | ||
| 331 | { | ||
| 332 | if (n == -1 || (n >= 1 && n <= 16)) | ||
| 333 | { | ||
| 334 | push_back(n + (OP_1 - 1)); | ||
| 335 | } | ||
| 336 | else | ||
| 337 | { | ||
| 338 | CBigNum bn(n); | ||
| 339 | *this << bn.getvch(); | ||
| 340 | } | ||
| 341 | return (*this); | ||
| 342 | } | ||
| 343 | |||
| 344 | CScript& push_uint64(uint64 n) | ||
| 345 | { | ||
| 346 | if (n == -1 || (n >= 1 && n <= 16)) | ||
| 347 | { | ||
| 348 | push_back(n + (OP_1 - 1)); | ||
| 349 | } | ||
| 350 | else | ||
| 351 | { | ||
| 352 | CBigNum bn(n); | ||
| 353 | *this << bn.getvch(); | ||
| 354 | } | ||
| 355 | return (*this); | ||
| 356 | } | ||
| 357 | |||
| 358 | public: | ||
| 359 | CScript() { } | ||
| 360 | CScript(const CScript& b) : vector<unsigned char>(b.begin(), b.end()) { } | ||
| 361 | CScript(const_iterator pbegin, const_iterator pend) : vector<unsigned char>(pbegin, pend) { } | ||
| 362 | #ifndef _MSC_VER | ||
| 363 | CScript(const unsigned char* pbegin, const unsigned char* pend) : vector<unsigned char>(pbegin, pend) { } | ||
| 364 | #endif | ||
| 365 | |||
| 366 | CScript& operator+=(const CScript& b) | ||
| 367 | { | ||
| 368 | insert(end(), b.begin(), b.end()); | ||
| 369 | return *this; | ||
| 370 | } | ||
| 371 | |||
| 372 | friend CScript operator+(const CScript& a, const CScript& b) | ||
| 373 | { | ||
| 374 | CScript ret = a; | ||
| 375 | ret += b; | ||
| 376 | return (ret); | ||
| 377 | } | ||
| 378 | |||
| 379 | |||
| 380 | explicit CScript(char b) { operator<<(b); } | ||
| 381 | explicit CScript(short b) { operator<<(b); } | ||
| 382 | explicit CScript(int b) { operator<<(b); } | ||
| 383 | explicit CScript(long b) { operator<<(b); } | ||
| 384 | explicit CScript(int64 b) { operator<<(b); } | ||
| 385 | explicit CScript(unsigned char b) { operator<<(b); } | ||
| 386 | explicit CScript(unsigned int b) { operator<<(b); } | ||
| 387 | explicit CScript(unsigned short b) { operator<<(b); } | ||
| 388 | explicit CScript(unsigned long b) { operator<<(b); } | ||
| 389 | explicit CScript(uint64 b) { operator<<(b); } | ||
| 390 | |||
| 391 | explicit CScript(opcodetype b) { operator<<(b); } | ||
| 392 | explicit CScript(const uint256& b) { operator<<(b); } | ||
| 393 | explicit CScript(const CBigNum& b) { operator<<(b); } | ||
| 394 | explicit CScript(const vector<unsigned char>& b) { operator<<(b); } | ||
| 395 | |||
| 396 | |||
| 397 | CScript& operator<<(char b) { return (push_int64(b)); } | ||
| 398 | CScript& operator<<(short b) { return (push_int64(b)); } | ||
| 399 | CScript& operator<<(int b) { return (push_int64(b)); } | ||
| 400 | CScript& operator<<(long b) { return (push_int64(b)); } | ||
| 401 | CScript& operator<<(int64 b) { return (push_int64(b)); } | ||
| 402 | CScript& operator<<(unsigned char b) { return (push_uint64(b)); } | ||
| 403 | CScript& operator<<(unsigned int b) { return (push_uint64(b)); } | ||
| 404 | CScript& operator<<(unsigned short b) { return (push_uint64(b)); } | ||
| 405 | CScript& operator<<(unsigned long b) { return (push_uint64(b)); } | ||
| 406 | CScript& operator<<(uint64 b) { return (push_uint64(b)); } | ||
| 407 | |||
| 408 | CScript& operator<<(opcodetype opcode) | ||
| 409 | { | ||
| 410 | if (opcode <= OP_SINGLEBYTE_END) | ||
| 411 | { | ||
| 412 | insert(end(), (unsigned char)opcode); | ||
| 413 | } | ||
| 414 | else | ||
| 415 | { | ||
| 416 | assert(opcode >= OP_DOUBLEBYTE_BEGIN); | ||
| 417 | insert(end(), (unsigned char)(opcode >> 8)); | ||
| 418 | insert(end(), (unsigned char)(opcode & 0xFF)); | ||
| 419 | } | ||
| 420 | return (*this); | ||
| 421 | } | ||
| 422 | |||
| 423 | CScript& operator<<(const uint160& b) | ||
| 424 | { | ||
| 425 | insert(end(), sizeof(b)); | ||
| 426 | insert(end(), (unsigned char*)&b, (unsigned char*)&b + sizeof(b)); | ||
| 427 | return (*this); | ||
| 428 | } | ||
| 429 | |||
| 430 | CScript& operator<<(const uint256& b) | ||
| 431 | { | ||
| 432 | insert(end(), sizeof(b)); | ||
| 433 | insert(end(), (unsigned char*)&b, (unsigned char*)&b + sizeof(b)); | ||
| 434 | return (*this); | ||
| 435 | } | ||
| 436 | |||
| 437 | CScript& operator<<(const CBigNum& b) | ||
| 438 | { | ||
| 439 | *this << b.getvch(); | ||
| 440 | return (*this); | ||
| 441 | } | ||
| 442 | |||
| 443 | CScript& operator<<(const vector<unsigned char>& b) | ||
| 444 | { | ||
| 445 | if (b.size() < OP_PUSHDATA1) | ||
| 446 | { | ||
| 447 | insert(end(), (unsigned char)b.size()); | ||
| 448 | } | ||
| 449 | else if (b.size() <= 0xff) | ||
| 450 | { | ||
| 451 | insert(end(), OP_PUSHDATA1); | ||
| 452 | insert(end(), (unsigned char)b.size()); | ||
| 453 | } | ||
| 454 | else | ||
| 455 | { | ||
| 456 | insert(end(), OP_PUSHDATA2); | ||
| 457 | unsigned short nSize = b.size(); | ||
| 458 | insert(end(), (unsigned char*)&nSize, (unsigned char*)&nSize + sizeof(nSize)); | ||
| 459 | } | ||
| 460 | insert(end(), b.begin(), b.end()); | ||
| 461 | return (*this); | ||
| 462 | } | ||
| 463 | |||
| 464 | CScript& operator<<(const CScript& b) | ||
| 465 | { | ||
| 466 | // I'm not sure if this should push the script or concatenate scripts. | ||
| 467 | // If there's ever a use for pushing a script onto a script, delete this member fn | ||
| 468 | assert(("warning: pushing a CScript onto a CScript with << is probably not intended, use + to concatenate", false)); | ||
| 469 | return (*this); | ||
| 470 | } | ||
| 471 | |||
| 472 | |||
| 473 | bool GetOp(iterator& pc, opcodetype& opcodeRet, vector<unsigned char>& vchRet) | ||
| 474 | { | ||
| 475 | // This is why people hate C++ | ||
| 476 | const_iterator pc2 = pc; | ||
| 477 | bool fRet = GetOp(pc2, opcodeRet, vchRet); | ||
| 478 | pc = begin() + (pc2 - begin()); | ||
| 479 | return fRet; | ||
| 480 | } | ||
| 481 | |||
| 482 | bool GetOp(const_iterator& pc, opcodetype& opcodeRet, vector<unsigned char>& vchRet) const | ||
| 483 | { | ||
| 484 | opcodeRet = OP_INVALIDOPCODE; | ||
| 485 | vchRet.clear(); | ||
| 486 | if (pc >= end()) | ||
| 487 | return false; | ||
| 488 | |||
| 489 | // Read instruction | ||
| 490 | unsigned int opcode = *pc++; | ||
| 491 | if (opcode >= OP_SINGLEBYTE_END) | ||
| 492 | { | ||
| 493 | if (pc + 1 > end()) | ||
| 494 | return false; | ||
| 495 | opcode <<= 8; | ||
| 496 | opcode |= *pc++; | ||
| 497 | } | ||
| 498 | |||
| 499 | // Immediate operand | ||
| 500 | if (opcode <= OP_PUSHDATA4) | ||
| 501 | { | ||
| 502 | unsigned int nSize = opcode; | ||
| 503 | if (opcode == OP_PUSHDATA1) | ||
| 504 | { | ||
| 505 | if (pc + 1 > end()) | ||
| 506 | return false; | ||
| 507 | nSize = *pc++; | ||
| 508 | } | ||
| 509 | else if (opcode == OP_PUSHDATA2) | ||
| 510 | { | ||
| 511 | if (pc + 2 > end()) | ||
| 512 | return false; | ||
| 513 | nSize = 0; | ||
| 514 | memcpy(&nSize, &pc[0], 2); | ||
| 515 | pc += 2; | ||
| 516 | } | ||
| 517 | else if (opcode == OP_PUSHDATA4) | ||
| 518 | { | ||
| 519 | if (pc + 4 > end()) | ||
| 520 | return false; | ||
| 521 | memcpy(&nSize, &pc[0], 4); | ||
| 522 | pc += 4; | ||
| 523 | } | ||
| 524 | if (pc + nSize > end()) | ||
| 525 | return false; | ||
| 526 | vchRet.assign(pc, pc + nSize); | ||
| 527 | pc += nSize; | ||
| 528 | } | ||
| 529 | |||
| 530 | opcodeRet = (opcodetype)opcode; | ||
| 531 | return true; | ||
| 532 | } | ||
| 533 | |||
| 534 | |||
| 535 | void FindAndDelete(const CScript& b) | ||
| 536 | { | ||
| 537 | iterator pc = begin(); | ||
| 538 | opcodetype opcode; | ||
| 539 | vector<unsigned char> vchPushValue; | ||
| 540 | int count = 0; | ||
| 541 | do | ||
| 542 | { | ||
| 543 | while (end() - pc >= b.size() && memcmp(&pc[0], &b[0], b.size()) == 0) | ||
| 544 | { | ||
| 545 | erase(pc, pc + b.size()); | ||
| 546 | count++; | ||
| 547 | } | ||
| 548 | } | ||
| 549 | while (GetOp(pc, opcode, vchPushValue)); | ||
| 550 | //printf("FindAndDeleted deleted %d items\n", count); /// debug | ||
| 551 | } | ||
| 552 | |||
| 553 | |||
| 554 | void PrintHex() const | ||
| 555 | { | ||
| 556 | printf("CScript(%s)\n", HexStr(begin(), end()).c_str()); | ||
| 557 | } | ||
| 558 | |||
| 559 | string ToString() const | ||
| 560 | { | ||
| 561 | string str; | ||
| 562 | opcodetype opcode; | ||
| 563 | vector<unsigned char> vch; | ||
| 564 | const_iterator it = begin(); | ||
| 565 | while (GetOp(it, opcode, vch)) | ||
| 566 | { | ||
| 567 | if (!str.empty()) | ||
| 568 | str += " "; | ||
| 569 | if (opcode <= OP_PUSHDATA4) | ||
| 570 | str += ValueString(vch); | ||
| 571 | else | ||
| 572 | str += GetOpName(opcode); | ||
| 573 | } | ||
| 574 | return str; | ||
| 575 | } | ||
| 576 | |||
| 577 | void print() const | ||
| 578 | { | ||
| 579 | printf("%s\n", ToString().c_str()); | ||
| 580 | } | ||
| 581 | }; | ||
| 582 | |||
| 583 | |||
| 584 | |||
| 585 | |||
| 586 | |||
| 587 | |||
| 588 | |||
| 589 | |||
| 590 | bool EvalScript(const CScript& script, const CTransaction& txTo, unsigned int nIn, int nHashType=0, | ||
| 591 | vector<vector<unsigned char> >* pvStackRet=NULL); | ||
| 592 | uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType); | ||
| 593 | bool IsMine(const CScript& scriptPubKey); | ||
| 594 | bool ExtractPubKey(const CScript& scriptPubKey, bool fMineOnly, vector<unsigned char>& vchPubKeyRet); | ||
| 595 | bool ExtractHash160(const CScript& scriptPubKey, uint160& hash160Ret); | ||
| 596 | bool SignSignature(const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL, CScript scriptPrereq=CScript()); | ||
| 597 | bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsigned int nIn, int nHashType=0); | ||
diff --git a/src/serialize.h b/src/serialize.h new file mode 100644 index 0000000..0e03cf7 --- /dev/null +++ b/src/serialize.h | |||
| @@ -0,0 +1,1151 @@ | |||
| 1 | // Copyright (c) 2009 Satoshi Nakamoto | ||
| 2 | // Distributed under the MIT/X11 software license, see the accompanying | ||
| 3 | // file license.txt or http://www.opensource.org/licenses/mit-license.php. | ||
| 4 | |||
| 5 | #include <vector> | ||
| 6 | #include <map> | ||
| 7 | #include <boost/type_traits/is_fundamental.hpp> | ||
| 8 | #if defined(_MSC_VER) || defined(__BORLANDC__) | ||
| 9 | typedef __int64 int64; | ||
| 10 | typedef unsigned __int64 uint64; | ||
| 11 | #else | ||
| 12 | typedef long long int64; | ||
| 13 | typedef unsigned long long uint64; | ||
| 14 | #endif | ||
| 15 | #if defined(_MSC_VER) && _MSC_VER < 1300 | ||
| 16 | #define for if (false) ; else for | ||
| 17 | #endif | ||
| 18 | class CScript; | ||
| 19 | class CDataStream; | ||
| 20 | class CAutoFile; | ||
| 21 | |||
| 22 | static const int VERSION = 101; | ||
| 23 | |||
| 24 | |||
| 25 | |||
| 26 | |||
| 27 | |||
| 28 | ///////////////////////////////////////////////////////////////// | ||
| 29 | // | ||
| 30 | // Templates for serializing to anything that looks like a stream, | ||
| 31 | // i.e. anything that supports .read(char*, int) and .write(char*, int) | ||
| 32 | // | ||
| 33 | |||
| 34 | enum | ||
| 35 | { | ||
| 36 | // primary actions | ||
| 37 | SER_NETWORK = (1 << 0), | ||
| 38 | SER_DISK = (1 << 1), | ||
| 39 | SER_GETHASH = (1 << 2), | ||
| 40 | |||
| 41 | // modifiers | ||
| 42 | SER_SKIPSIG = (1 << 16), | ||
| 43 | SER_BLOCKHEADERONLY = (1 << 17), | ||
| 44 | }; | ||
| 45 | |||
| 46 | #define IMPLEMENT_SERIALIZE(statements) \ | ||
| 47 | unsigned int GetSerializeSize(int nType=0, int nVersion=VERSION) const \ | ||
| 48 | { \ | ||
| 49 | CSerActionGetSerializeSize ser_action; \ | ||
| 50 | const bool fGetSize = true; \ | ||
| 51 | const bool fWrite = false; \ | ||
| 52 | const bool fRead = false; \ | ||
| 53 | unsigned int nSerSize = 0; \ | ||
| 54 | ser_streamplaceholder s; \ | ||
| 55 | s.nType = nType; \ | ||
| 56 | s.nVersion = nVersion; \ | ||
| 57 | {statements} \ | ||
| 58 | return nSerSize; \ | ||
| 59 | } \ | ||
| 60 | template<typename Stream> \ | ||
| 61 | void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const \ | ||
| 62 | { \ | ||
| 63 | CSerActionSerialize ser_action; \ | ||
| 64 | const bool fGetSize = false; \ | ||
| 65 | const bool fWrite = true; \ | ||
| 66 | const bool fRead = false; \ | ||
| 67 | unsigned int nSerSize = 0; \ | ||
| 68 | {statements} \ | ||
| 69 | } \ | ||
| 70 | template<typename Stream> \ | ||
| 71 | void Unserialize(Stream& s, int nType=0, int nVersion=VERSION) \ | ||
| 72 | { \ | ||
| 73 | CSerActionUnserialize ser_action; \ | ||
| 74 | const bool fGetSize = false; \ | ||
| 75 | const bool fWrite = false; \ | ||
| 76 | const bool fRead = true; \ | ||
| 77 | unsigned int nSerSize = 0; \ | ||
| 78 | {statements} \ | ||
| 79 | } | ||
| 80 | |||
| 81 | #define READWRITE(obj) (nSerSize += ::SerReadWrite(s, (obj), nType, nVersion, ser_action)) | ||
| 82 | |||
| 83 | |||
| 84 | |||
| 85 | |||
| 86 | |||
| 87 | |||
| 88 | // | ||
| 89 | // Basic types | ||
| 90 | // | ||
| 91 | #define WRITEDATA(s, obj) s.write((char*)&(obj), sizeof(obj)) | ||
| 92 | #define READDATA(s, obj) s.read((char*)&(obj), sizeof(obj)) | ||
| 93 | |||
| 94 | inline unsigned int GetSerializeSize(char a, int, int=0) { return sizeof(a); } | ||
| 95 | inline unsigned int GetSerializeSize(signed char a, int, int=0) { return sizeof(a); } | ||
| 96 | inline unsigned int GetSerializeSize(unsigned char a, int, int=0) { return sizeof(a); } | ||
| 97 | inline unsigned int GetSerializeSize(signed short a, int, int=0) { return sizeof(a); } | ||
| 98 | inline unsigned int GetSerializeSize(unsigned short a, int, int=0) { return sizeof(a); } | ||
| 99 | inline unsigned int GetSerializeSize(signed int a, int, int=0) { return sizeof(a); } | ||
| 100 | inline unsigned int GetSerializeSize(unsigned int a, int, int=0) { return sizeof(a); } | ||
| 101 | inline unsigned int GetSerializeSize(signed long a, int, int=0) { return sizeof(a); } | ||
| 102 | inline unsigned int GetSerializeSize(unsigned long a, int, int=0) { return sizeof(a); } | ||
| 103 | inline unsigned int GetSerializeSize(int64 a, int, int=0) { return sizeof(a); } | ||
| 104 | inline unsigned int GetSerializeSize(uint64 a, int, int=0) { return sizeof(a); } | ||
| 105 | inline unsigned int GetSerializeSize(float a, int, int=0) { return sizeof(a); } | ||
| 106 | inline unsigned int GetSerializeSize(double a, int, int=0) { return sizeof(a); } | ||
| 107 | |||
| 108 | template<typename Stream> inline void Serialize(Stream& s, char a, int, int=0) { WRITEDATA(s, a); } | ||
| 109 | template<typename Stream> inline void Serialize(Stream& s, signed char a, int, int=0) { WRITEDATA(s, a); } | ||
| 110 | template<typename Stream> inline void Serialize(Stream& s, unsigned char a, int, int=0) { WRITEDATA(s, a); } | ||
| 111 | template<typename Stream> inline void Serialize(Stream& s, signed short a, int, int=0) { WRITEDATA(s, a); } | ||
| 112 | template<typename Stream> inline void Serialize(Stream& s, unsigned short a, int, int=0) { WRITEDATA(s, a); } | ||
| 113 | template<typename Stream> inline void Serialize(Stream& s, signed int a, int, int=0) { WRITEDATA(s, a); } | ||
| 114 | template<typename Stream> inline void Serialize(Stream& s, unsigned int a, int, int=0) { WRITEDATA(s, a); } | ||
| 115 | template<typename Stream> inline void Serialize(Stream& s, signed long a, int, int=0) { WRITEDATA(s, a); } | ||
| 116 | template<typename Stream> inline void Serialize(Stream& s, unsigned long a, int, int=0) { WRITEDATA(s, a); } | ||
| 117 | template<typename Stream> inline void Serialize(Stream& s, int64 a, int, int=0) { WRITEDATA(s, a); } | ||
| 118 | template<typename Stream> inline void Serialize(Stream& s, uint64 a, int, int=0) { WRITEDATA(s, a); } | ||
| 119 | template<typename Stream> inline void Serialize(Stream& s, float a, int, int=0) { WRITEDATA(s, a); } | ||
| 120 | template<typename Stream> inline void Serialize(Stream& s, double a, int, int=0) { WRITEDATA(s, a); } | ||
| 121 | |||
| 122 | template<typename Stream> inline void Unserialize(Stream& s, char& a, int, int=0) { READDATA(s, a); } | ||
| 123 | template<typename Stream> inline void Unserialize(Stream& s, signed char& a, int, int=0) { READDATA(s, a); } | ||
| 124 | template<typename Stream> inline void Unserialize(Stream& s, unsigned char& a, int, int=0) { READDATA(s, a); } | ||
| 125 | template<typename Stream> inline void Unserialize(Stream& s, signed short& a, int, int=0) { READDATA(s, a); } | ||
| 126 | template<typename Stream> inline void Unserialize(Stream& s, unsigned short& a, int, int=0) { READDATA(s, a); } | ||
| 127 | template<typename Stream> inline void Unserialize(Stream& s, signed int& a, int, int=0) { READDATA(s, a); } | ||
| 128 | template<typename Stream> inline void Unserialize(Stream& s, unsigned int& a, int, int=0) { READDATA(s, a); } | ||
| 129 | template<typename Stream> inline void Unserialize(Stream& s, signed long& a, int, int=0) { READDATA(s, a); } | ||
| 130 | template<typename Stream> inline void Unserialize(Stream& s, unsigned long& a, int, int=0) { READDATA(s, a); } | ||
| 131 | template<typename Stream> inline void Unserialize(Stream& s, int64& a, int, int=0) { READDATA(s, a); } | ||
| 132 | template<typename Stream> inline void Unserialize(Stream& s, uint64& a, int, int=0) { READDATA(s, a); } | ||
| 133 | template<typename Stream> inline void Unserialize(Stream& s, float& a, int, int=0) { READDATA(s, a); } | ||
| 134 | template<typename Stream> inline void Unserialize(Stream& s, double& a, int, int=0) { READDATA(s, a); } | ||
| 135 | |||
| 136 | inline unsigned int GetSerializeSize(bool a, int, int=0) { return sizeof(char); } | ||
| 137 | template<typename Stream> inline void Serialize(Stream& s, bool a, int, int=0) { char f=a; WRITEDATA(s, f); } | ||
| 138 | template<typename Stream> inline void Unserialize(Stream& s, bool& a, int, int=0) { char f; READDATA(s, f); a=f; } | ||
| 139 | |||
| 140 | |||
| 141 | |||
| 142 | |||
| 143 | |||
| 144 | |||
| 145 | // | ||
| 146 | // Compact size | ||
| 147 | // size < 253 -- 1 byte | ||
| 148 | // size <= USHRT_MAX -- 3 bytes (253 + 2 bytes) | ||
| 149 | // size <= UINT_MAX -- 5 bytes (254 + 4 bytes) | ||
| 150 | // size > UINT_MAX -- 9 bytes (255 + 8 bytes) | ||
| 151 | // | ||
| 152 | inline unsigned int GetSizeOfCompactSize(uint64 nSize) | ||
| 153 | { | ||
| 154 | if (nSize < UCHAR_MAX-2) return sizeof(unsigned char); | ||
| 155 | else if (nSize <= USHRT_MAX) return sizeof(unsigned char) + sizeof(unsigned short); | ||
| 156 | else if (nSize <= UINT_MAX) return sizeof(unsigned char) + sizeof(unsigned int); | ||
| 157 | else return sizeof(unsigned char) + sizeof(uint64); | ||
| 158 | } | ||
| 159 | |||
| 160 | template<typename Stream> | ||
| 161 | void WriteCompactSize(Stream& os, uint64 nSize) | ||
| 162 | { | ||
| 163 | if (nSize < UCHAR_MAX-2) | ||
| 164 | { | ||
| 165 | unsigned char chSize = nSize; | ||
| 166 | WRITEDATA(os, chSize); | ||
| 167 | } | ||
| 168 | else if (nSize <= USHRT_MAX) | ||
| 169 | { | ||
| 170 | unsigned char chSize = UCHAR_MAX-2; | ||
| 171 | unsigned short xSize = nSize; | ||
| 172 | WRITEDATA(os, chSize); | ||
| 173 | WRITEDATA(os, xSize); | ||
| 174 | } | ||
| 175 | else if (nSize <= UINT_MAX) | ||
| 176 | { | ||
| 177 | unsigned char chSize = UCHAR_MAX-1; | ||
| 178 | unsigned int xSize = nSize; | ||
| 179 | WRITEDATA(os, chSize); | ||
| 180 | WRITEDATA(os, xSize); | ||
| 181 | } | ||
| 182 | else | ||
| 183 | { | ||
| 184 | unsigned char chSize = UCHAR_MAX; | ||
| 185 | WRITEDATA(os, chSize); | ||
| 186 | WRITEDATA(os, nSize); | ||
| 187 | } | ||
| 188 | return; | ||
| 189 | } | ||
| 190 | |||
| 191 | template<typename Stream> | ||
| 192 | uint64 ReadCompactSize(Stream& is) | ||
| 193 | { | ||
| 194 | unsigned char chSize; | ||
| 195 | READDATA(is, chSize); | ||
| 196 | if (chSize < UCHAR_MAX-2) | ||
| 197 | { | ||
| 198 | return chSize; | ||
| 199 | } | ||
| 200 | else if (chSize == UCHAR_MAX-2) | ||
| 201 | { | ||
| 202 | unsigned short nSize; | ||
| 203 | READDATA(is, nSize); | ||
| 204 | return nSize; | ||
| 205 | } | ||
| 206 | else if (chSize == UCHAR_MAX-1) | ||
| 207 | { | ||
| 208 | unsigned int nSize; | ||
| 209 | READDATA(is, nSize); | ||
| 210 | return nSize; | ||
| 211 | } | ||
| 212 | else | ||
| 213 | { | ||
| 214 | uint64 nSize; | ||
| 215 | READDATA(is, nSize); | ||
| 216 | return nSize; | ||
| 217 | } | ||
| 218 | } | ||
| 219 | |||
| 220 | |||
| 221 | |||
| 222 | // | ||
| 223 | // Wrapper for serializing arrays and POD | ||
| 224 | // There's a clever template way to make arrays serialize normally, but MSVC6 doesn't support it | ||
| 225 | // | ||
| 226 | #define FLATDATA(obj) REF(CFlatData((char*)&(obj), (char*)&(obj) + sizeof(obj))) | ||
| 227 | class CFlatData | ||
| 228 | { | ||
| 229 | protected: | ||
| 230 | char* pbegin; | ||
| 231 | char* pend; | ||
| 232 | public: | ||
| 233 | CFlatData(void* pbeginIn, void* pendIn) : pbegin((char*)pbeginIn), pend((char*)pendIn) { } | ||
| 234 | char* begin() { return pbegin; } | ||
| 235 | const char* begin() const { return pbegin; } | ||
| 236 | char* end() { return pend; } | ||
| 237 | const char* end() const { return pend; } | ||
| 238 | |||
| 239 | unsigned int GetSerializeSize(int, int=0) const | ||
| 240 | { | ||
| 241 | return pend - pbegin; | ||
| 242 | } | ||
| 243 | |||
| 244 | template<typename Stream> | ||
| 245 | void Serialize(Stream& s, int, int=0) const | ||
| 246 | { | ||
| 247 | s.write(pbegin, pend - pbegin); | ||
| 248 | } | ||
| 249 | |||
| 250 | template<typename Stream> | ||
| 251 | void Unserialize(Stream& s, int, int=0) | ||
| 252 | { | ||
| 253 | s.read(pbegin, pend - pbegin); | ||
| 254 | } | ||
| 255 | }; | ||
| 256 | |||
| 257 | |||
| 258 | |||
| 259 | // | ||
| 260 | // string stored as a fixed length field | ||
| 261 | // | ||
| 262 | template<std::size_t LEN> | ||
| 263 | class CFixedFieldString | ||
| 264 | { | ||
| 265 | protected: | ||
| 266 | const string* pcstr; | ||
| 267 | string* pstr; | ||
| 268 | public: | ||
| 269 | explicit CFixedFieldString(const string& str) : pcstr(&str), pstr(NULL) { } | ||
| 270 | explicit CFixedFieldString(string& str) : pcstr(&str), pstr(&str) { } | ||
| 271 | |||
| 272 | unsigned int GetSerializeSize(int, int=0) const | ||
| 273 | { | ||
| 274 | return LEN; | ||
| 275 | } | ||
| 276 | |||
| 277 | template<typename Stream> | ||
| 278 | void Serialize(Stream& s, int, int=0) const | ||
| 279 | { | ||
| 280 | char pszBuf[LEN]; | ||
| 281 | strncpy(pszBuf, pcstr->c_str(), LEN); | ||
| 282 | s.write(pszBuf, LEN); | ||
| 283 | } | ||
| 284 | |||
| 285 | template<typename Stream> | ||
| 286 | void Unserialize(Stream& s, int, int=0) | ||
| 287 | { | ||
| 288 | if (pstr == NULL) | ||
| 289 | throw std::ios_base::failure("CFixedFieldString::Unserialize : trying to unserialize to const string"); | ||
| 290 | char pszBuf[LEN+1]; | ||
| 291 | s.read(pszBuf, LEN); | ||
| 292 | pszBuf[LEN] = '\0'; | ||
| 293 | *pstr = pszBuf; | ||
| 294 | } | ||
| 295 | }; | ||
| 296 | |||
| 297 | |||
| 298 | |||
| 299 | |||
| 300 | |||
| 301 | // | ||
| 302 | // Forward declarations | ||
| 303 | // | ||
| 304 | |||
| 305 | // string | ||
| 306 | template<typename C> unsigned int GetSerializeSize(const basic_string<C>& str, int, int=0); | ||
| 307 | template<typename Stream, typename C> void Serialize(Stream& os, const basic_string<C>& str, int, int=0); | ||
| 308 | template<typename Stream, typename C> void Unserialize(Stream& is, basic_string<C>& str, int, int=0); | ||
| 309 | |||
| 310 | // vector | ||
| 311 | template<typename T, typename A> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&); | ||
| 312 | template<typename T, typename A> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&); | ||
| 313 | template<typename T, typename A> inline unsigned int GetSerializeSize(const std::vector<T, A>& v, int nType, int nVersion=VERSION); | ||
| 314 | template<typename Stream, typename T, typename A> void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&); | ||
| 315 | template<typename Stream, typename T, typename A> void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&); | ||
| 316 | template<typename Stream, typename T, typename A> inline void Serialize(Stream& os, const std::vector<T, A>& v, int nType, int nVersion=VERSION); | ||
| 317 | template<typename Stream, typename T, typename A> void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&); | ||
| 318 | template<typename Stream, typename T, typename A> void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&); | ||
| 319 | template<typename Stream, typename T, typename A> inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersion=VERSION); | ||
| 320 | |||
| 321 | // others derived from vector | ||
| 322 | extern inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion=VERSION); | ||
| 323 | template<typename Stream> void Serialize(Stream& os, const CScript& v, int nType, int nVersion=VERSION); | ||
| 324 | template<typename Stream> void Unserialize(Stream& is, CScript& v, int nType, int nVersion=VERSION); | ||
| 325 | |||
| 326 | // pair | ||
| 327 | template<typename K, typename T> unsigned int GetSerializeSize(const std::pair<K, T>& item, int nType, int nVersion=VERSION); | ||
| 328 | template<typename Stream, typename K, typename T> void Serialize(Stream& os, const std::pair<K, T>& item, int nType, int nVersion=VERSION); | ||
| 329 | template<typename Stream, typename K, typename T> void Unserialize(Stream& is, std::pair<K, T>& item, int nType, int nVersion=VERSION); | ||
| 330 | |||
| 331 | // map | ||
| 332 | template<typename K, typename T, typename Pred, typename A> unsigned int GetSerializeSize(const std::map<K, T, Pred, A>& m, int nType, int nVersion=VERSION); | ||
| 333 | template<typename Stream, typename K, typename T, typename Pred, typename A> void Serialize(Stream& os, const std::map<K, T, Pred, A>& m, int nType, int nVersion=VERSION); | ||
| 334 | template<typename Stream, typename K, typename T, typename Pred, typename A> void Unserialize(Stream& is, std::map<K, T, Pred, A>& m, int nType, int nVersion=VERSION); | ||
| 335 | |||
| 336 | // set | ||
| 337 | template<typename K, typename Pred, typename A> unsigned int GetSerializeSize(const std::set<K, Pred, A>& m, int nType, int nVersion=VERSION); | ||
| 338 | template<typename Stream, typename K, typename Pred, typename A> void Serialize(Stream& os, const std::set<K, Pred, A>& m, int nType, int nVersion=VERSION); | ||
| 339 | template<typename Stream, typename K, typename Pred, typename A> void Unserialize(Stream& is, std::set<K, Pred, A>& m, int nType, int nVersion=VERSION); | ||
| 340 | |||
| 341 | |||
| 342 | |||
| 343 | |||
| 344 | |||
| 345 | // | ||
| 346 | // If none of the specialized versions above matched, default to calling member function. | ||
| 347 | // "int nType" is changed to "long nType" to keep from getting an ambiguous overload error. | ||
| 348 | // The compiler will only cast int to long if none of the other templates matched. | ||
| 349 | // Thanks to Boost serialization for this idea. | ||
| 350 | // | ||
| 351 | template<typename T> | ||
| 352 | inline unsigned int GetSerializeSize(const T& a, long nType, int nVersion=VERSION) | ||
| 353 | { | ||
| 354 | return a.GetSerializeSize((int)nType, nVersion); | ||
| 355 | } | ||
| 356 | |||
| 357 | template<typename Stream, typename T> | ||
| 358 | inline void Serialize(Stream& os, const T& a, long nType, int nVersion=VERSION) | ||
| 359 | { | ||
| 360 | a.Serialize(os, (int)nType, nVersion); | ||
| 361 | } | ||
| 362 | |||
| 363 | template<typename Stream, typename T> | ||
| 364 | inline void Unserialize(Stream& is, T& a, long nType, int nVersion=VERSION) | ||
| 365 | { | ||
| 366 | a.Unserialize(is, (int)nType, nVersion); | ||
| 367 | } | ||
| 368 | |||
| 369 | |||
| 370 | |||
| 371 | |||
| 372 | |||
| 373 | // | ||
| 374 | // string | ||
| 375 | // | ||
| 376 | template<typename C> | ||
| 377 | unsigned int GetSerializeSize(const basic_string<C>& str, int, int) | ||
| 378 | { | ||
| 379 | return GetSizeOfCompactSize(str.size()) + str.size() * sizeof(str[0]); | ||
| 380 | } | ||
| 381 | |||
| 382 | template<typename Stream, typename C> | ||
| 383 | void Serialize(Stream& os, const basic_string<C>& str, int, int) | ||
| 384 | { | ||
| 385 | WriteCompactSize(os, str.size()); | ||
| 386 | if (!str.empty()) | ||
| 387 | os.write((char*)&str[0], str.size() * sizeof(str[0])); | ||
| 388 | } | ||
| 389 | |||
| 390 | template<typename Stream, typename C> | ||
| 391 | void Unserialize(Stream& is, basic_string<C>& str, int, int) | ||
| 392 | { | ||
| 393 | unsigned int nSize = ReadCompactSize(is); | ||
| 394 | str.resize(nSize); | ||
| 395 | if (nSize != 0) | ||
| 396 | is.read((char*)&str[0], nSize * sizeof(str[0])); | ||
| 397 | } | ||
| 398 | |||
| 399 | |||
| 400 | |||
| 401 | // | ||
| 402 | // vector | ||
| 403 | // | ||
| 404 | template<typename T, typename A> | ||
| 405 | unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&) | ||
| 406 | { | ||
| 407 | return (GetSizeOfCompactSize(v.size()) + v.size() * sizeof(T)); | ||
| 408 | } | ||
| 409 | |||
| 410 | template<typename T, typename A> | ||
| 411 | unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&) | ||
| 412 | { | ||
| 413 | unsigned int nSize = GetSizeOfCompactSize(v.size()); | ||
| 414 | for (typename std::vector<T, A>::const_iterator vi = v.begin(); vi != v.end(); ++vi) | ||
| 415 | nSize += GetSerializeSize((*vi), nType, nVersion); | ||
| 416 | return nSize; | ||
| 417 | } | ||
| 418 | |||
| 419 | template<typename T, typename A> | ||
| 420 | inline unsigned int GetSerializeSize(const std::vector<T, A>& v, int nType, int nVersion) | ||
| 421 | { | ||
| 422 | return GetSerializeSize_impl(v, nType, nVersion, boost::is_fundamental<T>()); | ||
| 423 | } | ||
| 424 | |||
| 425 | |||
| 426 | template<typename Stream, typename T, typename A> | ||
| 427 | void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&) | ||
| 428 | { | ||
| 429 | WriteCompactSize(os, v.size()); | ||
| 430 | if (!v.empty()) | ||
| 431 | os.write((char*)&v[0], v.size() * sizeof(T)); | ||
| 432 | } | ||
| 433 | |||
| 434 | template<typename Stream, typename T, typename A> | ||
| 435 | void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&) | ||
| 436 | { | ||
| 437 | WriteCompactSize(os, v.size()); | ||
| 438 | for (typename std::vector<T, A>::const_iterator vi = v.begin(); vi != v.end(); ++vi) | ||
| 439 | ::Serialize(os, (*vi), nType, nVersion); | ||
| 440 | } | ||
| 441 | |||
| 442 | template<typename Stream, typename T, typename A> | ||
| 443 | inline void Serialize(Stream& os, const std::vector<T, A>& v, int nType, int nVersion) | ||
| 444 | { | ||
| 445 | Serialize_impl(os, v, nType, nVersion, boost::is_fundamental<T>()); | ||
| 446 | } | ||
| 447 | |||
| 448 | |||
| 449 | template<typename Stream, typename T, typename A> | ||
| 450 | void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&) | ||
| 451 | { | ||
| 452 | //unsigned int nSize = ReadCompactSize(is); | ||
| 453 | //v.resize(nSize); | ||
| 454 | //is.read((char*)&v[0], nSize * sizeof(T)); | ||
| 455 | |||
| 456 | // Limit size per read so bogus size value won't cause out of memory | ||
| 457 | v.clear(); | ||
| 458 | unsigned int nSize = ReadCompactSize(is); | ||
| 459 | unsigned int i = 0; | ||
| 460 | while (i < nSize) | ||
| 461 | { | ||
| 462 | unsigned int blk = min(nSize - i, 1 + 4999999 / sizeof(T)); | ||
| 463 | v.resize(i + blk); | ||
| 464 | is.read((char*)&v[i], blk * sizeof(T)); | ||
| 465 | i += blk; | ||
| 466 | } | ||
| 467 | } | ||
| 468 | |||
| 469 | template<typename Stream, typename T, typename A> | ||
| 470 | void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&) | ||
| 471 | { | ||
| 472 | //unsigned int nSize = ReadCompactSize(is); | ||
| 473 | //v.resize(nSize); | ||
| 474 | //for (std::vector<T, A>::iterator vi = v.begin(); vi != v.end(); ++vi) | ||
| 475 | // Unserialize(is, (*vi), nType, nVersion); | ||
| 476 | |||
| 477 | v.clear(); | ||
| 478 | unsigned int nSize = ReadCompactSize(is); | ||
| 479 | unsigned int i = 0; | ||
| 480 | unsigned int nMid = 0; | ||
| 481 | while (nMid < nSize) | ||
| 482 | { | ||
| 483 | nMid += 5000000 / sizeof(T); | ||
| 484 | if (nMid > nSize) | ||
| 485 | nMid = nSize; | ||
| 486 | v.resize(nMid); | ||
| 487 | for (; i < nMid; i++) | ||
| 488 | Unserialize(is, v[i], nType, nVersion); | ||
| 489 | } | ||
| 490 | } | ||
| 491 | |||
| 492 | template<typename Stream, typename T, typename A> | ||
| 493 | inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersion) | ||
| 494 | { | ||
| 495 | Unserialize_impl(is, v, nType, nVersion, boost::is_fundamental<T>()); | ||
| 496 | } | ||
| 497 | |||
| 498 | |||
| 499 | |||
| 500 | // | ||
| 501 | // others derived from vector | ||
| 502 | // | ||
| 503 | inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion) | ||
| 504 | { | ||
| 505 | return GetSerializeSize((const vector<unsigned char>&)v, nType, nVersion); | ||
| 506 | } | ||
| 507 | |||
| 508 | template<typename Stream> | ||
| 509 | void Serialize(Stream& os, const CScript& v, int nType, int nVersion) | ||
| 510 | { | ||
| 511 | Serialize(os, (const vector<unsigned char>&)v, nType, nVersion); | ||
| 512 | } | ||
| 513 | |||
| 514 | template<typename Stream> | ||
| 515 | void Unserialize(Stream& is, CScript& v, int nType, int nVersion) | ||
| 516 | { | ||
| 517 | Unserialize(is, (vector<unsigned char>&)v, nType, nVersion); | ||
| 518 | } | ||
| 519 | |||
| 520 | |||
| 521 | |||
| 522 | // | ||
| 523 | // pair | ||
| 524 | // | ||
| 525 | template<typename K, typename T> | ||
| 526 | unsigned int GetSerializeSize(const std::pair<K, T>& item, int nType, int nVersion) | ||
| 527 | { | ||
| 528 | return GetSerializeSize(item.first, nType, nVersion) + GetSerializeSize(item.second, nType, nVersion); | ||
| 529 | } | ||
| 530 | |||
| 531 | template<typename Stream, typename K, typename T> | ||
| 532 | void Serialize(Stream& os, const std::pair<K, T>& item, int nType, int nVersion) | ||
| 533 | { | ||
| 534 | Serialize(os, item.first, nType, nVersion); | ||
| 535 | Serialize(os, item.second, nType, nVersion); | ||
| 536 | } | ||
| 537 | |||
| 538 | template<typename Stream, typename K, typename T> | ||
| 539 | void Unserialize(Stream& is, std::pair<K, T>& item, int nType, int nVersion) | ||
| 540 | { | ||
| 541 | Unserialize(is, item.first, nType, nVersion); | ||
| 542 | Unserialize(is, item.second, nType, nVersion); | ||
| 543 | } | ||
| 544 | |||
| 545 | |||
| 546 | |||
| 547 | // | ||
| 548 | // map | ||
| 549 | // | ||
| 550 | template<typename K, typename T, typename Pred, typename A> | ||
| 551 | unsigned int GetSerializeSize(const std::map<K, T, Pred, A>& m, int nType, int nVersion) | ||
| 552 | { | ||
| 553 | unsigned int nSize = GetSizeOfCompactSize(m.size()); | ||
| 554 | for (typename std::map<K, T, Pred, A>::const_iterator mi = m.begin(); mi != m.end(); ++mi) | ||
| 555 | nSize += GetSerializeSize((*mi), nType, nVersion); | ||
| 556 | return nSize; | ||
| 557 | } | ||
| 558 | |||
| 559 | template<typename Stream, typename K, typename T, typename Pred, typename A> | ||
| 560 | void Serialize(Stream& os, const std::map<K, T, Pred, A>& m, int nType, int nVersion) | ||
| 561 | { | ||
| 562 | WriteCompactSize(os, m.size()); | ||
| 563 | for (typename std::map<K, T, Pred, A>::const_iterator mi = m.begin(); mi != m.end(); ++mi) | ||
| 564 | Serialize(os, (*mi), nType, nVersion); | ||
| 565 | } | ||
| 566 | |||
| 567 | template<typename Stream, typename K, typename T, typename Pred, typename A> | ||
| 568 | void Unserialize(Stream& is, std::map<K, T, Pred, A>& m, int nType, int nVersion) | ||
| 569 | { | ||
| 570 | m.clear(); | ||
| 571 | unsigned int nSize = ReadCompactSize(is); | ||
| 572 | typename std::map<K, T, Pred, A>::iterator mi = m.begin(); | ||
| 573 | for (unsigned int i = 0; i < nSize; i++) | ||
| 574 | { | ||
| 575 | pair<K, T> item; | ||
| 576 | Unserialize(is, item, nType, nVersion); | ||
| 577 | mi = m.insert(mi, item); | ||
| 578 | } | ||
| 579 | } | ||
| 580 | |||
| 581 | |||
| 582 | |||
| 583 | // | ||
| 584 | // set | ||
| 585 | // | ||
| 586 | template<typename K, typename Pred, typename A> | ||
| 587 | unsigned int GetSerializeSize(const std::set<K, Pred, A>& m, int nType, int nVersion) | ||
| 588 | { | ||
| 589 | unsigned int nSize = GetSizeOfCompactSize(m.size()); | ||
| 590 | for (typename std::set<K, Pred, A>::const_iterator it = m.begin(); it != m.end(); ++it) | ||
| 591 | nSize += GetSerializeSize((*it), nType, nVersion); | ||
| 592 | return nSize; | ||
| 593 | } | ||
| 594 | |||
| 595 | template<typename Stream, typename K, typename Pred, typename A> | ||
| 596 | void Serialize(Stream& os, const std::set<K, Pred, A>& m, int nType, int nVersion) | ||
| 597 | { | ||
| 598 | WriteCompactSize(os, m.size()); | ||
| 599 | for (typename std::set<K, Pred, A>::const_iterator it = m.begin(); it != m.end(); ++it) | ||
| 600 | Serialize(os, (*it), nType, nVersion); | ||
| 601 | } | ||
| 602 | |||
| 603 | template<typename Stream, typename K, typename Pred, typename A> | ||
| 604 | void Unserialize(Stream& is, std::set<K, Pred, A>& m, int nType, int nVersion) | ||
| 605 | { | ||
| 606 | m.clear(); | ||
| 607 | unsigned int nSize = ReadCompactSize(is); | ||
| 608 | typename std::set<K, Pred, A>::iterator it = m.begin(); | ||
| 609 | for (unsigned int i = 0; i < nSize; i++) | ||
| 610 | { | ||
| 611 | K key; | ||
| 612 | Unserialize(is, key, nType, nVersion); | ||
| 613 | it = m.insert(it, key); | ||
| 614 | } | ||
| 615 | } | ||
| 616 | |||
| 617 | |||
| 618 | |||
| 619 | // | ||
| 620 | // Support for IMPLEMENT_SERIALIZE and READWRITE macro | ||
| 621 | // | ||
| 622 | class CSerActionGetSerializeSize { }; | ||
| 623 | class CSerActionSerialize { }; | ||
| 624 | class CSerActionUnserialize { }; | ||
| 625 | |||
| 626 | template<typename Stream, typename T> | ||
| 627 | inline unsigned int SerReadWrite(Stream& s, const T& obj, int nType, int nVersion, CSerActionGetSerializeSize ser_action) | ||
| 628 | { | ||
| 629 | return ::GetSerializeSize(obj, nType, nVersion); | ||
| 630 | } | ||
| 631 | |||
| 632 | template<typename Stream, typename T> | ||
| 633 | inline unsigned int SerReadWrite(Stream& s, const T& obj, int nType, int nVersion, CSerActionSerialize ser_action) | ||
| 634 | { | ||
| 635 | ::Serialize(s, obj, nType, nVersion); | ||
| 636 | return 0; | ||
| 637 | } | ||
| 638 | |||
| 639 | template<typename Stream, typename T> | ||
| 640 | inline unsigned int SerReadWrite(Stream& s, T& obj, int nType, int nVersion, CSerActionUnserialize ser_action) | ||
| 641 | { | ||
| 642 | ::Unserialize(s, obj, nType, nVersion); | ||
| 643 | return 0; | ||
| 644 | } | ||
| 645 | |||
| 646 | struct ser_streamplaceholder | ||
| 647 | { | ||
| 648 | int nType; | ||
| 649 | int nVersion; | ||
| 650 | }; | ||
| 651 | |||
| 652 | |||
| 653 | |||
| 654 | |||
| 655 | |||
| 656 | |||
| 657 | |||
| 658 | |||
| 659 | |||
| 660 | // | ||
| 661 | // Allocator that clears its contents before deletion | ||
| 662 | // | ||
| 663 | template<typename T> | ||
| 664 | struct secure_allocator : public std::allocator<T> | ||
| 665 | { | ||
| 666 | // MSVC8 default copy constructor is broken | ||
| 667 | typedef std::allocator<T> base; | ||
| 668 | typedef typename base::size_type size_type; | ||
| 669 | typedef typename base::difference_type difference_type; | ||
| 670 | typedef typename base::pointer pointer; | ||
| 671 | typedef typename base::const_pointer const_pointer; | ||
| 672 | typedef typename base::reference reference; | ||
| 673 | typedef typename base::const_reference const_reference; | ||
| 674 | typedef typename base::value_type value_type; | ||
| 675 | secure_allocator() throw() {} | ||
| 676 | secure_allocator(const secure_allocator& a) throw() : base(a) {} | ||
| 677 | ~secure_allocator() throw() {} | ||
| 678 | template<typename _Other> struct rebind | ||
| 679 | { typedef secure_allocator<_Other> other; }; | ||
| 680 | |||
| 681 | void deallocate(T* p, std::size_t n) | ||
| 682 | { | ||
| 683 | if (p != NULL) | ||
| 684 | memset(p, 0, sizeof(T) * n); | ||
| 685 | allocator<T>::deallocate(p, n); | ||
| 686 | } | ||
| 687 | }; | ||
| 688 | |||
| 689 | |||
| 690 | |||
| 691 | // | ||
| 692 | // Double ended buffer combining vector and stream-like interfaces. | ||
| 693 | // >> and << read and write unformatted data using the above serialization templates. | ||
| 694 | // Fills with data in linear time; some stringstream implementations take N^2 time. | ||
| 695 | // | ||
| 696 | class CDataStream | ||
| 697 | { | ||
| 698 | protected: | ||
| 699 | typedef vector<char, secure_allocator<char> > vector_type; | ||
| 700 | vector_type vch; | ||
| 701 | unsigned int nReadPos; | ||
| 702 | short state; | ||
| 703 | short exceptmask; | ||
| 704 | public: | ||
| 705 | int nType; | ||
| 706 | int nVersion; | ||
| 707 | |||
| 708 | typedef vector_type::allocator_type allocator_type; | ||
| 709 | typedef vector_type::size_type size_type; | ||
| 710 | typedef vector_type::difference_type difference_type; | ||
| 711 | typedef vector_type::reference reference; | ||
| 712 | typedef vector_type::const_reference const_reference; | ||
| 713 | typedef vector_type::value_type value_type; | ||
| 714 | typedef vector_type::iterator iterator; | ||
| 715 | typedef vector_type::const_iterator const_iterator; | ||
| 716 | typedef vector_type::reverse_iterator reverse_iterator; | ||
| 717 | |||
| 718 | explicit CDataStream(int nTypeIn=0, int nVersionIn=VERSION) | ||
| 719 | { | ||
| 720 | Init(nTypeIn, nVersionIn); | ||
| 721 | } | ||
| 722 | |||
| 723 | CDataStream(const_iterator pbegin, const_iterator pend, int nTypeIn=0, int nVersionIn=VERSION) : vch(pbegin, pend) | ||
| 724 | { | ||
| 725 | Init(nTypeIn, nVersionIn); | ||
| 726 | } | ||
| 727 | |||
| 728 | #if !defined(_MSC_VER) || _MSC_VER >= 1300 | ||
| 729 | CDataStream(const char* pbegin, const char* pend, int nTypeIn=0, int nVersionIn=VERSION) : vch(pbegin, pend) | ||
| 730 | { | ||
| 731 | Init(nTypeIn, nVersionIn); | ||
| 732 | } | ||
| 733 | #endif | ||
| 734 | |||
| 735 | CDataStream(const vector_type& vchIn, int nTypeIn=0, int nVersionIn=VERSION) : vch(vchIn.begin(), vchIn.end()) | ||
| 736 | { | ||
| 737 | Init(nTypeIn, nVersionIn); | ||
| 738 | } | ||
| 739 | |||
| 740 | CDataStream(const vector<char>& vchIn, int nTypeIn=0, int nVersionIn=VERSION) : vch(vchIn.begin(), vchIn.end()) | ||
| 741 | { | ||
| 742 | Init(nTypeIn, nVersionIn); | ||
| 743 | } | ||
| 744 | |||
| 745 | CDataStream(const vector<unsigned char>& vchIn, int nTypeIn=0, int nVersionIn=VERSION) : vch((char*)&vchIn.begin()[0], (char*)&vchIn.end()[0]) | ||
| 746 | { | ||
| 747 | Init(nTypeIn, nVersionIn); | ||
| 748 | } | ||
| 749 | |||
| 750 | void Init(int nTypeIn=0, int nVersionIn=VERSION) | ||
| 751 | { | ||
| 752 | nReadPos = 0; | ||
| 753 | nType = nTypeIn; | ||
| 754 | nVersion = nVersionIn; | ||
| 755 | state = 0; | ||
| 756 | exceptmask = ios::badbit | ios::failbit; | ||
| 757 | } | ||
| 758 | |||
| 759 | CDataStream& operator+=(const CDataStream& b) | ||
| 760 | { | ||
| 761 | vch.insert(vch.end(), b.begin(), b.end()); | ||
| 762 | return *this; | ||
| 763 | } | ||
| 764 | |||
| 765 | friend CDataStream operator+(const CDataStream& a, const CDataStream& b) | ||
| 766 | { | ||
| 767 | CDataStream ret = a; | ||
| 768 | ret += b; | ||
| 769 | return (ret); | ||
| 770 | } | ||
| 771 | |||
| 772 | string str() const | ||
| 773 | { | ||
| 774 | return (string(begin(), end())); | ||
| 775 | } | ||
| 776 | |||
| 777 | |||
| 778 | // | ||
| 779 | // Vector subset | ||
| 780 | // | ||
| 781 | const_iterator begin() const { return vch.begin() + nReadPos; } | ||
| 782 | iterator begin() { return vch.begin() + nReadPos; } | ||
| 783 | const_iterator end() const { return vch.end(); } | ||
| 784 | iterator end() { return vch.end(); } | ||
| 785 | size_type size() const { return vch.size() - nReadPos; } | ||
| 786 | bool empty() const { return vch.size() == nReadPos; } | ||
| 787 | void resize(size_type n, value_type c=0) { vch.resize(n + nReadPos, c); } | ||
| 788 | void reserve(size_type n) { vch.reserve(n + nReadPos); } | ||
| 789 | const_reference operator[](size_type pos) const { return vch[pos + nReadPos]; } | ||
| 790 | reference operator[](size_type pos) { return vch[pos + nReadPos]; } | ||
| 791 | void clear() { vch.clear(); nReadPos = 0; } | ||
| 792 | iterator insert(iterator it, const char& x=char()) { return vch.insert(it, x); } | ||
| 793 | void insert(iterator it, size_type n, const char& x) { vch.insert(it, n, x); } | ||
| 794 | |||
| 795 | void insert(iterator it, const_iterator first, const_iterator last) | ||
| 796 | { | ||
| 797 | if (it == vch.begin() + nReadPos && last - first <= nReadPos) | ||
| 798 | { | ||
| 799 | // special case for inserting at the front when there's room | ||
| 800 | nReadPos -= (last - first); | ||
| 801 | memcpy(&vch[nReadPos], &first[0], last - first); | ||
| 802 | } | ||
| 803 | else | ||
| 804 | vch.insert(it, first, last); | ||
| 805 | } | ||
| 806 | |||
| 807 | #if !defined(_MSC_VER) || _MSC_VER >= 1300 | ||
| 808 | void insert(iterator it, const char* first, const char* last) | ||
| 809 | { | ||
| 810 | insert(it, (const_iterator)first, (const_iterator)last); | ||
| 811 | } | ||
| 812 | #endif | ||
| 813 | |||
| 814 | iterator erase(iterator it) | ||
| 815 | { | ||
| 816 | if (it == vch.begin() + nReadPos) | ||
| 817 | { | ||
| 818 | // special case for erasing from the front | ||
| 819 | if (++nReadPos >= vch.size()) | ||
| 820 | { | ||
| 821 | // whenever we reach the end, we take the opportunity to clear the buffer | ||
| 822 | nReadPos = 0; | ||
| 823 | return vch.erase(vch.begin(), vch.end()); | ||
| 824 | } | ||
| 825 | return vch.begin() + nReadPos; | ||
| 826 | } | ||
| 827 | else | ||
| 828 | return vch.erase(it); | ||
| 829 | } | ||
| 830 | |||
| 831 | iterator erase(iterator first, iterator last) | ||
| 832 | { | ||
| 833 | if (first == vch.begin() + nReadPos) | ||
| 834 | { | ||
| 835 | // special case for erasing from the front | ||
| 836 | if (last == vch.end()) | ||
| 837 | { | ||
| 838 | nReadPos = 0; | ||
| 839 | return vch.erase(vch.begin(), vch.end()); | ||
| 840 | } | ||
| 841 | else | ||
| 842 | { | ||
| 843 | nReadPos = (last - vch.begin()); | ||
| 844 | return last; | ||
| 845 | } | ||
| 846 | } | ||
| 847 | else | ||
| 848 | return vch.erase(first, last); | ||
| 849 | } | ||
| 850 | |||
| 851 | inline void Compact() | ||
| 852 | { | ||
| 853 | vch.erase(vch.begin(), vch.begin() + nReadPos); | ||
| 854 | nReadPos = 0; | ||
| 855 | } | ||
| 856 | |||
| 857 | bool Rewind(size_type n) | ||
| 858 | { | ||
| 859 | // Rewind by n characters if the buffer hasn't been compacted yet | ||
| 860 | if (n > nReadPos) | ||
| 861 | return false; | ||
| 862 | nReadPos -= n; | ||
| 863 | return true; | ||
| 864 | } | ||
| 865 | |||
| 866 | |||
| 867 | // | ||
| 868 | // Stream subset | ||
| 869 | // | ||
| 870 | void setstate(short bits, const char* psz) | ||
| 871 | { | ||
| 872 | state |= bits; | ||
| 873 | if (state & exceptmask) | ||
| 874 | throw std::ios_base::failure(psz); | ||
| 875 | } | ||
| 876 | |||
| 877 | bool eof() const { return size() == 0; } | ||
| 878 | bool fail() const { return state & (ios::badbit | ios::failbit); } | ||
| 879 | bool good() const { return !eof() && (state == 0); } | ||
| 880 | void clear(short n) { state = n; } // name conflict with vector clear() | ||
| 881 | short exceptions() { return exceptmask; } | ||
| 882 | short exceptions(short mask) { short prev = exceptmask; exceptmask = mask; setstate(0, "CDataStream"); return prev; } | ||
| 883 | CDataStream* rdbuf() { return this; } | ||
| 884 | int in_avail() { return size(); } | ||
| 885 | |||
| 886 | void SetType(int n) { nType = n; } | ||
| 887 | int GetType() { return nType; } | ||
| 888 | void SetVersion(int n) { nVersion = n; } | ||
| 889 | int GetVersion() { return nVersion; } | ||
| 890 | void ReadVersion() { *this >> nVersion; } | ||
| 891 | void WriteVersion() { *this << nVersion; } | ||
| 892 | |||
| 893 | CDataStream& read(char* pch, int nSize) | ||
| 894 | { | ||
| 895 | // Read from the beginning of the buffer | ||
| 896 | assert(nSize >= 0); | ||
| 897 | unsigned int nReadPosNext = nReadPos + nSize; | ||
| 898 | if (nReadPosNext >= vch.size()) | ||
| 899 | { | ||
| 900 | if (nReadPosNext > vch.size()) | ||
| 901 | { | ||
| 902 | setstate(ios::failbit, "CDataStream::read() : end of data"); | ||
| 903 | memset(pch, 0, nSize); | ||
| 904 | nSize = vch.size() - nReadPos; | ||
| 905 | } | ||
| 906 | memcpy(pch, &vch[nReadPos], nSize); | ||
| 907 | nReadPos = 0; | ||
| 908 | vch.clear(); | ||
| 909 | return (*this); | ||
| 910 | } | ||
| 911 | memcpy(pch, &vch[nReadPos], nSize); | ||
| 912 | nReadPos = nReadPosNext; | ||
| 913 | return (*this); | ||
| 914 | } | ||
| 915 | |||
| 916 | CDataStream& ignore(int nSize) | ||
| 917 | { | ||
| 918 | // Ignore from the beginning of the buffer | ||
| 919 | assert(nSize >= 0); | ||
| 920 | unsigned int nReadPosNext = nReadPos + nSize; | ||
| 921 | if (nReadPosNext >= vch.size()) | ||
| 922 | { | ||
| 923 | if (nReadPosNext > vch.size()) | ||
| 924 | { | ||
| 925 | setstate(ios::failbit, "CDataStream::ignore() : end of data"); | ||
| 926 | nSize = vch.size() - nReadPos; | ||
| 927 | } | ||
| 928 | nReadPos = 0; | ||
| 929 | vch.clear(); | ||
| 930 | return (*this); | ||
| 931 | } | ||
| 932 | nReadPos = nReadPosNext; | ||
| 933 | return (*this); | ||
| 934 | } | ||
| 935 | |||
| 936 | CDataStream& write(const char* pch, int nSize) | ||
| 937 | { | ||
| 938 | // Write to the end of the buffer | ||
| 939 | assert(nSize >= 0); | ||
| 940 | vch.insert(vch.end(), pch, pch + nSize); | ||
| 941 | return (*this); | ||
| 942 | } | ||
| 943 | |||
| 944 | template<typename Stream> | ||
| 945 | void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const | ||
| 946 | { | ||
| 947 | // Special case: stream << stream concatenates like stream += stream | ||
| 948 | if (!vch.empty()) | ||
| 949 | s.write((char*)&vch[0], vch.size() * sizeof(vch[0])); | ||
| 950 | } | ||
| 951 | |||
| 952 | template<typename T> | ||
| 953 | unsigned int GetSerializeSize(const T& obj) | ||
| 954 | { | ||
| 955 | // Tells the size of the object if serialized to this stream | ||
| 956 | return ::GetSerializeSize(obj, nType, nVersion); | ||
| 957 | } | ||
| 958 | |||
| 959 | template<typename T> | ||
| 960 | CDataStream& operator<<(const T& obj) | ||
| 961 | { | ||
| 962 | // Serialize to this stream | ||
| 963 | ::Serialize(*this, obj, nType, nVersion); | ||
| 964 | return (*this); | ||
| 965 | } | ||
| 966 | |||
| 967 | template<typename T> | ||
| 968 | CDataStream& operator>>(T& obj) | ||
| 969 | { | ||
| 970 | // Unserialize from this stream | ||
| 971 | ::Unserialize(*this, obj, nType, nVersion); | ||
| 972 | return (*this); | ||
| 973 | } | ||
| 974 | }; | ||
| 975 | |||
| 976 | #ifdef TESTCDATASTREAM | ||
| 977 | // VC6sp6 | ||
| 978 | // CDataStream: | ||
| 979 | // n=1000 0 seconds | ||
| 980 | // n=2000 0 seconds | ||
| 981 | // n=4000 0 seconds | ||
| 982 | // n=8000 0 seconds | ||
| 983 | // n=16000 0 seconds | ||
| 984 | // n=32000 0 seconds | ||
| 985 | // n=64000 1 seconds | ||
| 986 | // n=128000 1 seconds | ||
| 987 | // n=256000 2 seconds | ||
| 988 | // n=512000 4 seconds | ||
| 989 | // n=1024000 8 seconds | ||
| 990 | // n=2048000 16 seconds | ||
| 991 | // n=4096000 32 seconds | ||
| 992 | // stringstream: | ||
| 993 | // n=1000 1 seconds | ||
| 994 | // n=2000 1 seconds | ||
| 995 | // n=4000 13 seconds | ||
| 996 | // n=8000 87 seconds | ||
| 997 | // n=16000 400 seconds | ||
| 998 | // n=32000 1660 seconds | ||
| 999 | // n=64000 6749 seconds | ||
| 1000 | // n=128000 27241 seconds | ||
| 1001 | // n=256000 109804 seconds | ||
| 1002 | #include <iostream> | ||
| 1003 | int main(int argc, char *argv[]) | ||
| 1004 | { | ||
| 1005 | vector<unsigned char> vch(0xcc, 250); | ||
| 1006 | printf("CDataStream:\n"); | ||
| 1007 | for (int n = 1000; n <= 4500000; n *= 2) | ||
| 1008 | { | ||
| 1009 | CDataStream ss; | ||
| 1010 | time_t nStart = time(NULL); | ||
| 1011 | for (int i = 0; i < n; i++) | ||
| 1012 | ss.write((char*)&vch[0], vch.size()); | ||
| 1013 | printf("n=%-10d %d seconds\n", n, time(NULL) - nStart); | ||
| 1014 | } | ||
| 1015 | printf("stringstream:\n"); | ||
| 1016 | for (int n = 1000; n <= 4500000; n *= 2) | ||
| 1017 | { | ||
| 1018 | stringstream ss; | ||
| 1019 | time_t nStart = time(NULL); | ||
| 1020 | for (int i = 0; i < n; i++) | ||
| 1021 | ss.write((char*)&vch[0], vch.size()); | ||
| 1022 | printf("n=%-10d %d seconds\n", n, time(NULL) - nStart); | ||
| 1023 | } | ||
| 1024 | } | ||
| 1025 | #endif | ||
| 1026 | |||
| 1027 | |||
| 1028 | |||
| 1029 | |||
| 1030 | |||
| 1031 | |||
| 1032 | |||
| 1033 | |||
| 1034 | |||
| 1035 | |||
| 1036 | // | ||
| 1037 | // Automatic closing wrapper for FILE* | ||
| 1038 | // - Will automatically close the file when it goes out of scope if not null. | ||
| 1039 | // - If you're returning the file pointer, return file.release(). | ||
| 1040 | // - If you need to close the file early, use file.fclose() instead of fclose(file). | ||
| 1041 | // | ||
| 1042 | class CAutoFile | ||
| 1043 | { | ||
| 1044 | protected: | ||
| 1045 | FILE* file; | ||
| 1046 | short state; | ||
| 1047 | short exceptmask; | ||
| 1048 | public: | ||
| 1049 | int nType; | ||
| 1050 | int nVersion; | ||
| 1051 | |||
| 1052 | typedef FILE element_type; | ||
| 1053 | |||
| 1054 | CAutoFile(FILE* filenew=NULL, int nTypeIn=SER_DISK, int nVersionIn=VERSION) | ||
| 1055 | { | ||
| 1056 | file = filenew; | ||
| 1057 | nType = nTypeIn; | ||
| 1058 | nVersion = nVersionIn; | ||
| 1059 | state = 0; | ||
| 1060 | exceptmask = ios::badbit | ios::failbit; | ||
| 1061 | } | ||
| 1062 | |||
| 1063 | ~CAutoFile() | ||
| 1064 | { | ||
| 1065 | fclose(); | ||
| 1066 | } | ||
| 1067 | |||
| 1068 | void fclose() | ||
| 1069 | { | ||
| 1070 | if (file != NULL && file != stdin && file != stdout && file != stderr) | ||
| 1071 | ::fclose(file); | ||
| 1072 | file = NULL; | ||
| 1073 | } | ||
| 1074 | |||
| 1075 | FILE* release() { FILE* ret = file; file = NULL; return ret; } | ||
| 1076 | operator FILE*() { return file; } | ||
| 1077 | FILE* operator->() { return file; } | ||
| 1078 | FILE& operator*() { return *file; } | ||
| 1079 | FILE** operator&() { return &file; } | ||
| 1080 | FILE* operator=(FILE* pnew) { return file = pnew; } | ||
| 1081 | bool operator!() { return (file == NULL); } | ||
| 1082 | |||
| 1083 | |||
| 1084 | // | ||
| 1085 | // Stream subset | ||
| 1086 | // | ||
| 1087 | void setstate(short bits, const char* psz) | ||
| 1088 | { | ||
| 1089 | state |= bits; | ||
| 1090 | if (state & exceptmask) | ||
| 1091 | throw std::ios_base::failure(psz); | ||
| 1092 | } | ||
| 1093 | |||
| 1094 | bool fail() const { return state & (ios::badbit | ios::failbit); } | ||
| 1095 | bool good() const { return state == 0; } | ||
| 1096 | void clear(short n = 0) { state = n; } | ||
| 1097 | short exceptions() { return exceptmask; } | ||
| 1098 | short exceptions(short mask) { short prev = exceptmask; exceptmask = mask; setstate(0, "CAutoFile"); return prev; } | ||
| 1099 | |||
| 1100 | void SetType(int n) { nType = n; } | ||
| 1101 | int GetType() { return nType; } | ||
| 1102 | void SetVersion(int n) { nVersion = n; } | ||
| 1103 | int GetVersion() { return nVersion; } | ||
| 1104 | void ReadVersion() { *this >> nVersion; } | ||
| 1105 | void WriteVersion() { *this << nVersion; } | ||
| 1106 | |||
| 1107 | CAutoFile& read(char* pch, int nSize) | ||
| 1108 | { | ||
| 1109 | if (!file) | ||
| 1110 | throw std::ios_base::failure("CAutoFile::read : file handle is NULL"); | ||
| 1111 | if (fread(pch, 1, nSize, file) != nSize) | ||
| 1112 | setstate(ios::failbit, feof(file) ? "CAutoFile::read : end of file" : "CAutoFile::read : fread failed"); | ||
| 1113 | return (*this); | ||
| 1114 | } | ||
| 1115 | |||
| 1116 | CAutoFile& write(const char* pch, int nSize) | ||
| 1117 | { | ||
| 1118 | if (!file) | ||
| 1119 | throw std::ios_base::failure("CAutoFile::write : file handle is NULL"); | ||
| 1120 | if (fwrite(pch, 1, nSize, file) != nSize) | ||
| 1121 | setstate(ios::failbit, "CAutoFile::write : write failed"); | ||
| 1122 | return (*this); | ||
| 1123 | } | ||
| 1124 | |||
| 1125 | template<typename T> | ||
| 1126 | unsigned int GetSerializeSize(const T& obj) | ||
| 1127 | { | ||
| 1128 | // Tells the size of the object if serialized to this stream | ||
| 1129 | return ::GetSerializeSize(obj, nType, nVersion); | ||
| 1130 | } | ||
| 1131 | |||
| 1132 | template<typename T> | ||
| 1133 | CAutoFile& operator<<(const T& obj) | ||
| 1134 | { | ||
| 1135 | // Serialize to this stream | ||
| 1136 | if (!file) | ||
| 1137 | throw std::ios_base::failure("CAutoFile::operator<< : file handle is NULL"); | ||
| 1138 | ::Serialize(*this, obj, nType, nVersion); | ||
| 1139 | return (*this); | ||
| 1140 | } | ||
| 1141 | |||
| 1142 | template<typename T> | ||
| 1143 | CAutoFile& operator>>(T& obj) | ||
| 1144 | { | ||
| 1145 | // Unserialize from this stream | ||
| 1146 | if (!file) | ||
| 1147 | throw std::ios_base::failure("CAutoFile::operator>> : file handle is NULL"); | ||
| 1148 | ::Unserialize(*this, obj, nType, nVersion); | ||
| 1149 | return (*this); | ||
| 1150 | } | ||
| 1151 | }; | ||
diff --git a/src/sha.cpp b/src/sha.cpp new file mode 100644 index 0000000..e691674 --- /dev/null +++ b/src/sha.cpp | |||
| @@ -0,0 +1,554 @@ | |||
| 1 | // This file is public domain | ||
| 2 | // SHA routines extracted as a standalone file from: | ||
| 3 | // Crypto++: a C++ Class Library of Cryptographic Schemes | ||
| 4 | // Version 5.5.2 (9/24/2007) | ||
| 5 | // http://www.cryptopp.com | ||
| 6 | |||
| 7 | // sha.cpp - modified by Wei Dai from Steve Reid's public domain sha1.c | ||
| 8 | |||
| 9 | // Steve Reid implemented SHA-1. Wei Dai implemented SHA-2. | ||
| 10 | // Both are in the public domain. | ||
| 11 | |||
| 12 | #include <assert.h> | ||
| 13 | #include <memory.h> | ||
| 14 | #include "sha.h" | ||
| 15 | |||
| 16 | namespace CryptoPP | ||
| 17 | { | ||
| 18 | |||
| 19 | // start of Steve Reid's code | ||
| 20 | |||
| 21 | #define blk0(i) (W[i] = data[i]) | ||
| 22 | #define blk1(i) (W[i&15] = rotlFixed(W[(i+13)&15]^W[(i+8)&15]^W[(i+2)&15]^W[i&15],1)) | ||
| 23 | |||
| 24 | void SHA1::InitState(HashWordType *state) | ||
| 25 | { | ||
| 26 | state[0] = 0x67452301L; | ||
| 27 | state[1] = 0xEFCDAB89L; | ||
| 28 | state[2] = 0x98BADCFEL; | ||
| 29 | state[3] = 0x10325476L; | ||
| 30 | state[4] = 0xC3D2E1F0L; | ||
| 31 | } | ||
| 32 | |||
| 33 | #define f1(x,y,z) (z^(x&(y^z))) | ||
| 34 | #define f2(x,y,z) (x^y^z) | ||
| 35 | #define f3(x,y,z) ((x&y)|(z&(x|y))) | ||
| 36 | #define f4(x,y,z) (x^y^z) | ||
| 37 | |||
| 38 | /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ | ||
| 39 | #define R0(v,w,x,y,z,i) z+=f1(w,x,y)+blk0(i)+0x5A827999+rotlFixed(v,5);w=rotlFixed(w,30); | ||
| 40 | #define R1(v,w,x,y,z,i) z+=f1(w,x,y)+blk1(i)+0x5A827999+rotlFixed(v,5);w=rotlFixed(w,30); | ||
| 41 | #define R2(v,w,x,y,z,i) z+=f2(w,x,y)+blk1(i)+0x6ED9EBA1+rotlFixed(v,5);w=rotlFixed(w,30); | ||
| 42 | #define R3(v,w,x,y,z,i) z+=f3(w,x,y)+blk1(i)+0x8F1BBCDC+rotlFixed(v,5);w=rotlFixed(w,30); | ||
| 43 | #define R4(v,w,x,y,z,i) z+=f4(w,x,y)+blk1(i)+0xCA62C1D6+rotlFixed(v,5);w=rotlFixed(w,30); | ||
| 44 | |||
| 45 | void SHA1::Transform(word32 *state, const word32 *data) | ||
| 46 | { | ||
| 47 | word32 W[16]; | ||
| 48 | /* Copy context->state[] to working vars */ | ||
| 49 | word32 a = state[0]; | ||
| 50 | word32 b = state[1]; | ||
| 51 | word32 c = state[2]; | ||
| 52 | word32 d = state[3]; | ||
| 53 | word32 e = state[4]; | ||
| 54 | /* 4 rounds of 20 operations each. Loop unrolled. */ | ||
| 55 | R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); | ||
| 56 | R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); | ||
| 57 | R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); | ||
| 58 | R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); | ||
| 59 | R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); | ||
| 60 | R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); | ||
| 61 | R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); | ||
| 62 | R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); | ||
| 63 | R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); | ||
| 64 | R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); | ||
| 65 | R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); | ||
| 66 | R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); | ||
| 67 | R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); | ||
| 68 | R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); | ||
| 69 | R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); | ||
| 70 | R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); | ||
| 71 | R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); | ||
| 72 | R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); | ||
| 73 | R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); | ||
| 74 | R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); | ||
| 75 | /* Add the working vars back into context.state[] */ | ||
| 76 | state[0] += a; | ||
| 77 | state[1] += b; | ||
| 78 | state[2] += c; | ||
| 79 | state[3] += d; | ||
| 80 | state[4] += e; | ||
| 81 | } | ||
| 82 | |||
| 83 | // end of Steve Reid's code | ||
| 84 | |||
| 85 | // ************************************************************* | ||
| 86 | |||
| 87 | void SHA224::InitState(HashWordType *state) | ||
| 88 | { | ||
| 89 | static const word32 s[8] = {0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4}; | ||
| 90 | memcpy(state, s, sizeof(s)); | ||
| 91 | } | ||
| 92 | |||
| 93 | void SHA256::InitState(HashWordType *state) | ||
| 94 | { | ||
| 95 | static const word32 s[8] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19}; | ||
| 96 | memcpy(state, s, sizeof(s)); | ||
| 97 | } | ||
| 98 | |||
| 99 | static const word32 SHA256_K[64] = { | ||
| 100 | 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, | ||
| 101 | 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, | ||
| 102 | 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, | ||
| 103 | 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, | ||
| 104 | 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, | ||
| 105 | 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, | ||
| 106 | 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, | ||
| 107 | 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, | ||
| 108 | 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, | ||
| 109 | 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, | ||
| 110 | 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, | ||
| 111 | 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, | ||
| 112 | 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, | ||
| 113 | 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, | ||
| 114 | 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, | ||
| 115 | 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 | ||
| 116 | }; | ||
| 117 | |||
| 118 | #define blk2(i) (W[i&15]+=s1(W[(i-2)&15])+W[(i-7)&15]+s0(W[(i-15)&15])) | ||
| 119 | |||
| 120 | #define Ch(x,y,z) (z^(x&(y^z))) | ||
| 121 | #define Maj(x,y,z) ((x&y)|(z&(x|y))) | ||
| 122 | |||
| 123 | #define a(i) T[(0-i)&7] | ||
| 124 | #define b(i) T[(1-i)&7] | ||
| 125 | #define c(i) T[(2-i)&7] | ||
| 126 | #define d(i) T[(3-i)&7] | ||
| 127 | #define e(i) T[(4-i)&7] | ||
| 128 | #define f(i) T[(5-i)&7] | ||
| 129 | #define g(i) T[(6-i)&7] | ||
| 130 | #define h(i) T[(7-i)&7] | ||
| 131 | |||
| 132 | #define R(i) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+SHA256_K[i+j]+(j?blk2(i):blk0(i));\ | ||
| 133 | d(i)+=h(i);h(i)+=S0(a(i))+Maj(a(i),b(i),c(i)) | ||
| 134 | |||
| 135 | // for SHA256 | ||
| 136 | #define S0(x) (rotrFixed(x,2)^rotrFixed(x,13)^rotrFixed(x,22)) | ||
| 137 | #define S1(x) (rotrFixed(x,6)^rotrFixed(x,11)^rotrFixed(x,25)) | ||
| 138 | #define s0(x) (rotrFixed(x,7)^rotrFixed(x,18)^(x>>3)) | ||
| 139 | #define s1(x) (rotrFixed(x,17)^rotrFixed(x,19)^(x>>10)) | ||
| 140 | |||
| 141 | void SHA256::Transform(word32 *state, const word32 *data) | ||
| 142 | { | ||
| 143 | word32 W[16]; | ||
| 144 | word32 T[8]; | ||
| 145 | /* Copy context->state[] to working vars */ | ||
| 146 | memcpy(T, state, sizeof(T)); | ||
| 147 | /* 64 operations, partially loop unrolled */ | ||
| 148 | for (unsigned int j=0; j<64; j+=16) | ||
| 149 | { | ||
| 150 | R( 0); R( 1); R( 2); R( 3); | ||
| 151 | R( 4); R( 5); R( 6); R( 7); | ||
| 152 | R( 8); R( 9); R(10); R(11); | ||
| 153 | R(12); R(13); R(14); R(15); | ||
| 154 | } | ||
| 155 | /* Add the working vars back into context.state[] */ | ||
| 156 | state[0] += a(0); | ||
| 157 | state[1] += b(0); | ||
| 158 | state[2] += c(0); | ||
| 159 | state[3] += d(0); | ||
| 160 | state[4] += e(0); | ||
| 161 | state[5] += f(0); | ||
| 162 | state[6] += g(0); | ||
| 163 | state[7] += h(0); | ||
| 164 | } | ||
| 165 | |||
| 166 | /* | ||
| 167 | // smaller but slower | ||
| 168 | void SHA256_Transform(word32 *state, const word32 *data) | ||
| 169 | { | ||
| 170 | word32 T[20]; | ||
| 171 | word32 W[32]; | ||
| 172 | unsigned int i = 0, j = 0; | ||
| 173 | word32 *t = T+8; | ||
| 174 | |||
| 175 | memcpy(t, state, 8*4); | ||
| 176 | word32 e = t[4], a = t[0]; | ||
| 177 | |||
| 178 | do | ||
| 179 | { | ||
| 180 | word32 w = data[j]; | ||
| 181 | W[j] = w; | ||
| 182 | w += K[j]; | ||
| 183 | w += t[7]; | ||
| 184 | w += S1(e); | ||
| 185 | w += Ch(e, t[5], t[6]); | ||
| 186 | e = t[3] + w; | ||
| 187 | t[3] = t[3+8] = e; | ||
| 188 | w += S0(t[0]); | ||
| 189 | a = w + Maj(a, t[1], t[2]); | ||
| 190 | t[-1] = t[7] = a; | ||
| 191 | --t; | ||
| 192 | ++j; | ||
| 193 | if (j%8 == 0) | ||
| 194 | t += 8; | ||
| 195 | } while (j<16); | ||
| 196 | |||
| 197 | do | ||
| 198 | { | ||
| 199 | i = j&0xf; | ||
| 200 | word32 w = s1(W[i+16-2]) + s0(W[i+16-15]) + W[i] + W[i+16-7]; | ||
| 201 | W[i+16] = W[i] = w; | ||
| 202 | w += K[j]; | ||
| 203 | w += t[7]; | ||
| 204 | w += S1(e); | ||
| 205 | w += Ch(e, t[5], t[6]); | ||
| 206 | e = t[3] + w; | ||
| 207 | t[3] = t[3+8] = e; | ||
| 208 | w += S0(t[0]); | ||
| 209 | a = w + Maj(a, t[1], t[2]); | ||
| 210 | t[-1] = t[7] = a; | ||
| 211 | |||
| 212 | w = s1(W[(i+1)+16-2]) + s0(W[(i+1)+16-15]) + W[(i+1)] + W[(i+1)+16-7]; | ||
| 213 | W[(i+1)+16] = W[(i+1)] = w; | ||
| 214 | w += K[j+1]; | ||
| 215 | w += (t-1)[7]; | ||
| 216 | w += S1(e); | ||
| 217 | w += Ch(e, (t-1)[5], (t-1)[6]); | ||
| 218 | e = (t-1)[3] + w; | ||
| 219 | (t-1)[3] = (t-1)[3+8] = e; | ||
| 220 | w += S0((t-1)[0]); | ||
| 221 | a = w + Maj(a, (t-1)[1], (t-1)[2]); | ||
| 222 | (t-1)[-1] = (t-1)[7] = a; | ||
| 223 | |||
| 224 | t-=2; | ||
| 225 | j+=2; | ||
| 226 | if (j%8 == 0) | ||
| 227 | t += 8; | ||
| 228 | } while (j<64); | ||
| 229 | |||
| 230 | state[0] += a; | ||
| 231 | state[1] += t[1]; | ||
| 232 | state[2] += t[2]; | ||
| 233 | state[3] += t[3]; | ||
| 234 | state[4] += e; | ||
| 235 | state[5] += t[5]; | ||
| 236 | state[6] += t[6]; | ||
| 237 | state[7] += t[7]; | ||
| 238 | } | ||
| 239 | */ | ||
| 240 | |||
| 241 | #undef S0 | ||
| 242 | #undef S1 | ||
| 243 | #undef s0 | ||
| 244 | #undef s1 | ||
| 245 | #undef R | ||
| 246 | |||
| 247 | // ************************************************************* | ||
| 248 | |||
| 249 | #ifdef WORD64_AVAILABLE | ||
| 250 | |||
| 251 | void SHA384::InitState(HashWordType *state) | ||
| 252 | { | ||
| 253 | static const word64 s[8] = { | ||
| 254 | W64LIT(0xcbbb9d5dc1059ed8), W64LIT(0x629a292a367cd507), | ||
| 255 | W64LIT(0x9159015a3070dd17), W64LIT(0x152fecd8f70e5939), | ||
| 256 | W64LIT(0x67332667ffc00b31), W64LIT(0x8eb44a8768581511), | ||
| 257 | W64LIT(0xdb0c2e0d64f98fa7), W64LIT(0x47b5481dbefa4fa4)}; | ||
| 258 | memcpy(state, s, sizeof(s)); | ||
| 259 | } | ||
| 260 | |||
| 261 | void SHA512::InitState(HashWordType *state) | ||
| 262 | { | ||
| 263 | static const word64 s[8] = { | ||
| 264 | W64LIT(0x6a09e667f3bcc908), W64LIT(0xbb67ae8584caa73b), | ||
| 265 | W64LIT(0x3c6ef372fe94f82b), W64LIT(0xa54ff53a5f1d36f1), | ||
| 266 | W64LIT(0x510e527fade682d1), W64LIT(0x9b05688c2b3e6c1f), | ||
| 267 | W64LIT(0x1f83d9abfb41bd6b), W64LIT(0x5be0cd19137e2179)}; | ||
| 268 | memcpy(state, s, sizeof(s)); | ||
| 269 | } | ||
| 270 | |||
| 271 | CRYPTOPP_ALIGN_DATA(16) static const word64 SHA512_K[80] CRYPTOPP_SECTION_ALIGN16 = { | ||
| 272 | W64LIT(0x428a2f98d728ae22), W64LIT(0x7137449123ef65cd), | ||
| 273 | W64LIT(0xb5c0fbcfec4d3b2f), W64LIT(0xe9b5dba58189dbbc), | ||
| 274 | W64LIT(0x3956c25bf348b538), W64LIT(0x59f111f1b605d019), | ||
| 275 | W64LIT(0x923f82a4af194f9b), W64LIT(0xab1c5ed5da6d8118), | ||
| 276 | W64LIT(0xd807aa98a3030242), W64LIT(0x12835b0145706fbe), | ||
| 277 | W64LIT(0x243185be4ee4b28c), W64LIT(0x550c7dc3d5ffb4e2), | ||
| 278 | W64LIT(0x72be5d74f27b896f), W64LIT(0x80deb1fe3b1696b1), | ||
| 279 | W64LIT(0x9bdc06a725c71235), W64LIT(0xc19bf174cf692694), | ||
| 280 | W64LIT(0xe49b69c19ef14ad2), W64LIT(0xefbe4786384f25e3), | ||
| 281 | W64LIT(0x0fc19dc68b8cd5b5), W64LIT(0x240ca1cc77ac9c65), | ||
| 282 | W64LIT(0x2de92c6f592b0275), W64LIT(0x4a7484aa6ea6e483), | ||
| 283 | W64LIT(0x5cb0a9dcbd41fbd4), W64LIT(0x76f988da831153b5), | ||
| 284 | W64LIT(0x983e5152ee66dfab), W64LIT(0xa831c66d2db43210), | ||
| 285 | W64LIT(0xb00327c898fb213f), W64LIT(0xbf597fc7beef0ee4), | ||
| 286 | W64LIT(0xc6e00bf33da88fc2), W64LIT(0xd5a79147930aa725), | ||
| 287 | W64LIT(0x06ca6351e003826f), W64LIT(0x142929670a0e6e70), | ||
| 288 | W64LIT(0x27b70a8546d22ffc), W64LIT(0x2e1b21385c26c926), | ||
| 289 | W64LIT(0x4d2c6dfc5ac42aed), W64LIT(0x53380d139d95b3df), | ||
| 290 | W64LIT(0x650a73548baf63de), W64LIT(0x766a0abb3c77b2a8), | ||
| 291 | W64LIT(0x81c2c92e47edaee6), W64LIT(0x92722c851482353b), | ||
| 292 | W64LIT(0xa2bfe8a14cf10364), W64LIT(0xa81a664bbc423001), | ||
| 293 | W64LIT(0xc24b8b70d0f89791), W64LIT(0xc76c51a30654be30), | ||
| 294 | W64LIT(0xd192e819d6ef5218), W64LIT(0xd69906245565a910), | ||
| 295 | W64LIT(0xf40e35855771202a), W64LIT(0x106aa07032bbd1b8), | ||
| 296 | W64LIT(0x19a4c116b8d2d0c8), W64LIT(0x1e376c085141ab53), | ||
| 297 | W64LIT(0x2748774cdf8eeb99), W64LIT(0x34b0bcb5e19b48a8), | ||
| 298 | W64LIT(0x391c0cb3c5c95a63), W64LIT(0x4ed8aa4ae3418acb), | ||
| 299 | W64LIT(0x5b9cca4f7763e373), W64LIT(0x682e6ff3d6b2b8a3), | ||
| 300 | W64LIT(0x748f82ee5defb2fc), W64LIT(0x78a5636f43172f60), | ||
| 301 | W64LIT(0x84c87814a1f0ab72), W64LIT(0x8cc702081a6439ec), | ||
| 302 | W64LIT(0x90befffa23631e28), W64LIT(0xa4506cebde82bde9), | ||
| 303 | W64LIT(0xbef9a3f7b2c67915), W64LIT(0xc67178f2e372532b), | ||
| 304 | W64LIT(0xca273eceea26619c), W64LIT(0xd186b8c721c0c207), | ||
| 305 | W64LIT(0xeada7dd6cde0eb1e), W64LIT(0xf57d4f7fee6ed178), | ||
| 306 | W64LIT(0x06f067aa72176fba), W64LIT(0x0a637dc5a2c898a6), | ||
| 307 | W64LIT(0x113f9804bef90dae), W64LIT(0x1b710b35131c471b), | ||
| 308 | W64LIT(0x28db77f523047d84), W64LIT(0x32caab7b40c72493), | ||
| 309 | W64LIT(0x3c9ebe0a15c9bebc), W64LIT(0x431d67c49c100d4c), | ||
| 310 | W64LIT(0x4cc5d4becb3e42b6), W64LIT(0x597f299cfc657e2a), | ||
| 311 | W64LIT(0x5fcb6fab3ad6faec), W64LIT(0x6c44198c4a475817) | ||
| 312 | }; | ||
| 313 | |||
| 314 | #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && CRYPTOPP_BOOL_X86 | ||
| 315 | // put assembly version in separate function, otherwise MSVC 2005 SP1 doesn't generate correct code for the non-assembly version | ||
| 316 | CRYPTOPP_NAKED static void CRYPTOPP_FASTCALL SHA512_SSE2_Transform(word64 *state, const word64 *data) | ||
| 317 | { | ||
| 318 | #ifdef __GNUC__ | ||
| 319 | __asm__ __volatile__ | ||
| 320 | ( | ||
| 321 | ".intel_syntax noprefix;" | ||
| 322 | AS1( push ebx) | ||
| 323 | AS2( mov ebx, eax) | ||
| 324 | #else | ||
| 325 | AS1( push ebx) | ||
| 326 | AS1( push esi) | ||
| 327 | AS1( push edi) | ||
| 328 | AS2( lea ebx, SHA512_K) | ||
| 329 | #endif | ||
| 330 | |||
| 331 | AS2( mov eax, esp) | ||
| 332 | AS2( and esp, 0xfffffff0) | ||
| 333 | AS2( sub esp, 27*16) // 17*16 for expanded data, 20*8 for state | ||
| 334 | AS1( push eax) | ||
| 335 | AS2( xor eax, eax) | ||
| 336 | AS2( lea edi, [esp+4+8*8]) // start at middle of state buffer. will decrement pointer each round to avoid copying | ||
| 337 | AS2( lea esi, [esp+4+20*8+8]) // 16-byte alignment, then add 8 | ||
| 338 | |||
| 339 | AS2( movq mm4, [ecx+0*8]) | ||
| 340 | AS2( movq [edi+0*8], mm4) | ||
| 341 | AS2( movq mm0, [ecx+1*8]) | ||
| 342 | AS2( movq [edi+1*8], mm0) | ||
| 343 | AS2( movq mm0, [ecx+2*8]) | ||
| 344 | AS2( movq [edi+2*8], mm0) | ||
| 345 | AS2( movq mm0, [ecx+3*8]) | ||
| 346 | AS2( movq [edi+3*8], mm0) | ||
| 347 | AS2( movq mm5, [ecx+4*8]) | ||
| 348 | AS2( movq [edi+4*8], mm5) | ||
| 349 | AS2( movq mm0, [ecx+5*8]) | ||
| 350 | AS2( movq [edi+5*8], mm0) | ||
| 351 | AS2( movq mm0, [ecx+6*8]) | ||
| 352 | AS2( movq [edi+6*8], mm0) | ||
| 353 | AS2( movq mm0, [ecx+7*8]) | ||
| 354 | AS2( movq [edi+7*8], mm0) | ||
| 355 | ASJ( jmp, 0, f) | ||
| 356 | |||
| 357 | #define SSE2_S0_S1(r, a, b, c) \ | ||
| 358 | AS2( movq mm6, r)\ | ||
| 359 | AS2( psrlq r, a)\ | ||
| 360 | AS2( movq mm7, r)\ | ||
| 361 | AS2( psllq mm6, 64-c)\ | ||
| 362 | AS2( pxor mm7, mm6)\ | ||
| 363 | AS2( psrlq r, b-a)\ | ||
| 364 | AS2( pxor mm7, r)\ | ||
| 365 | AS2( psllq mm6, c-b)\ | ||
| 366 | AS2( pxor mm7, mm6)\ | ||
| 367 | AS2( psrlq r, c-b)\ | ||
| 368 | AS2( pxor r, mm7)\ | ||
| 369 | AS2( psllq mm6, b-a)\ | ||
| 370 | AS2( pxor r, mm6) | ||
| 371 | |||
| 372 | #define SSE2_s0(r, a, b, c) \ | ||
| 373 | AS2( movdqa xmm6, r)\ | ||
| 374 | AS2( psrlq r, a)\ | ||
| 375 | AS2( movdqa xmm7, r)\ | ||
| 376 | AS2( psllq xmm6, 64-c)\ | ||
| 377 | AS2( pxor xmm7, xmm6)\ | ||
| 378 | AS2( psrlq r, b-a)\ | ||
| 379 | AS2( pxor xmm7, r)\ | ||
| 380 | AS2( psrlq r, c-b)\ | ||
| 381 | AS2( pxor r, xmm7)\ | ||
| 382 | AS2( psllq xmm6, c-a)\ | ||
| 383 | AS2( pxor r, xmm6) | ||
| 384 | |||
| 385 | #define SSE2_s1(r, a, b, c) \ | ||
| 386 | AS2( movdqa xmm6, r)\ | ||
| 387 | AS2( psrlq r, a)\ | ||
| 388 | AS2( movdqa xmm7, r)\ | ||
| 389 | AS2( psllq xmm6, 64-c)\ | ||
| 390 | AS2( pxor xmm7, xmm6)\ | ||
| 391 | AS2( psrlq r, b-a)\ | ||
| 392 | AS2( pxor xmm7, r)\ | ||
| 393 | AS2( psllq xmm6, c-b)\ | ||
| 394 | AS2( pxor xmm7, xmm6)\ | ||
| 395 | AS2( psrlq r, c-b)\ | ||
| 396 | AS2( pxor r, xmm7) | ||
| 397 | |||
| 398 | ASL(SHA512_Round) | ||
| 399 | // k + w is in mm0, a is in mm4, e is in mm5 | ||
| 400 | AS2( paddq mm0, [edi+7*8]) // h | ||
| 401 | AS2( movq mm2, [edi+5*8]) // f | ||
| 402 | AS2( movq mm3, [edi+6*8]) // g | ||
| 403 | AS2( pxor mm2, mm3) | ||
| 404 | AS2( pand mm2, mm5) | ||
| 405 | SSE2_S0_S1(mm5,14,18,41) | ||
| 406 | AS2( pxor mm2, mm3) | ||
| 407 | AS2( paddq mm0, mm2) // h += Ch(e,f,g) | ||
| 408 | AS2( paddq mm5, mm0) // h += S1(e) | ||
| 409 | AS2( movq mm2, [edi+1*8]) // b | ||
| 410 | AS2( movq mm1, mm2) | ||
| 411 | AS2( por mm2, mm4) | ||
| 412 | AS2( pand mm2, [edi+2*8]) // c | ||
| 413 | AS2( pand mm1, mm4) | ||
| 414 | AS2( por mm1, mm2) | ||
| 415 | AS2( paddq mm1, mm5) // temp = h + Maj(a,b,c) | ||
| 416 | AS2( paddq mm5, [edi+3*8]) // e = d + h | ||
| 417 | AS2( movq [edi+3*8], mm5) | ||
| 418 | AS2( movq [edi+11*8], mm5) | ||
| 419 | SSE2_S0_S1(mm4,28,34,39) // S0(a) | ||
| 420 | AS2( paddq mm4, mm1) // a = temp + S0(a) | ||
| 421 | AS2( movq [edi-8], mm4) | ||
| 422 | AS2( movq [edi+7*8], mm4) | ||
| 423 | AS1( ret) | ||
| 424 | |||
| 425 | // first 16 rounds | ||
| 426 | ASL(0) | ||
| 427 | AS2( movq mm0, [edx+eax*8]) | ||
| 428 | AS2( movq [esi+eax*8], mm0) | ||
| 429 | AS2( movq [esi+eax*8+16*8], mm0) | ||
| 430 | AS2( paddq mm0, [ebx+eax*8]) | ||
| 431 | ASC( call, SHA512_Round) | ||
| 432 | AS1( inc eax) | ||
| 433 | AS2( sub edi, 8) | ||
| 434 | AS2( test eax, 7) | ||
| 435 | ASJ( jnz, 0, b) | ||
| 436 | AS2( add edi, 8*8) | ||
| 437 | AS2( cmp eax, 16) | ||
| 438 | ASJ( jne, 0, b) | ||
| 439 | |||
| 440 | // rest of the rounds | ||
| 441 | AS2( movdqu xmm0, [esi+(16-2)*8]) | ||
| 442 | ASL(1) | ||
| 443 | // data expansion, W[i-2] already in xmm0 | ||
| 444 | AS2( movdqu xmm3, [esi]) | ||
| 445 | AS2( paddq xmm3, [esi+(16-7)*8]) | ||
| 446 | AS2( movdqa xmm2, [esi+(16-15)*8]) | ||
| 447 | SSE2_s1(xmm0, 6, 19, 61) | ||
| 448 | AS2( paddq xmm0, xmm3) | ||
| 449 | SSE2_s0(xmm2, 1, 7, 8) | ||
| 450 | AS2( paddq xmm0, xmm2) | ||
| 451 | AS2( movdq2q mm0, xmm0) | ||
| 452 | AS2( movhlps xmm1, xmm0) | ||
| 453 | AS2( paddq mm0, [ebx+eax*8]) | ||
| 454 | AS2( movlps [esi], xmm0) | ||
| 455 | AS2( movlps [esi+8], xmm1) | ||
| 456 | AS2( movlps [esi+8*16], xmm0) | ||
| 457 | AS2( movlps [esi+8*17], xmm1) | ||
| 458 | // 2 rounds | ||
| 459 | ASC( call, SHA512_Round) | ||
| 460 | AS2( sub edi, 8) | ||
| 461 | AS2( movdq2q mm0, xmm1) | ||
| 462 | AS2( paddq mm0, [ebx+eax*8+8]) | ||
| 463 | ASC( call, SHA512_Round) | ||
| 464 | // update indices and loop | ||
| 465 | AS2( add esi, 16) | ||
| 466 | AS2( add eax, 2) | ||
| 467 | AS2( sub edi, 8) | ||
| 468 | AS2( test eax, 7) | ||
| 469 | ASJ( jnz, 1, b) | ||
| 470 | // do housekeeping every 8 rounds | ||
| 471 | AS2( mov esi, 0xf) | ||
| 472 | AS2( and esi, eax) | ||
| 473 | AS2( lea esi, [esp+4+20*8+8+esi*8]) | ||
| 474 | AS2( add edi, 8*8) | ||
| 475 | AS2( cmp eax, 80) | ||
| 476 | ASJ( jne, 1, b) | ||
| 477 | |||
| 478 | #define SSE2_CombineState(i) \ | ||
| 479 | AS2( movq mm0, [edi+i*8])\ | ||
| 480 | AS2( paddq mm0, [ecx+i*8])\ | ||
| 481 | AS2( movq [ecx+i*8], mm0) | ||
| 482 | |||
| 483 | SSE2_CombineState(0) | ||
| 484 | SSE2_CombineState(1) | ||
| 485 | SSE2_CombineState(2) | ||
| 486 | SSE2_CombineState(3) | ||
| 487 | SSE2_CombineState(4) | ||
| 488 | SSE2_CombineState(5) | ||
| 489 | SSE2_CombineState(6) | ||
| 490 | SSE2_CombineState(7) | ||
| 491 | |||
| 492 | AS1( pop esp) | ||
| 493 | AS1( emms) | ||
| 494 | |||
| 495 | #if defined(__GNUC__) | ||
| 496 | AS1( pop ebx) | ||
| 497 | ".att_syntax prefix;" | ||
| 498 | : | ||
| 499 | : "a" (SHA512_K), "c" (state), "d" (data) | ||
| 500 | : "%esi", "%edi", "memory", "cc" | ||
| 501 | ); | ||
| 502 | #else | ||
| 503 | AS1( pop edi) | ||
| 504 | AS1( pop esi) | ||
| 505 | AS1( pop ebx) | ||
| 506 | AS1( ret) | ||
| 507 | #endif | ||
| 508 | } | ||
| 509 | #endif // #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE | ||
| 510 | |||
| 511 | void SHA512::Transform(word64 *state, const word64 *data) | ||
| 512 | { | ||
| 513 | #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && CRYPTOPP_BOOL_X86 | ||
| 514 | if (HasSSE2()) | ||
| 515 | { | ||
| 516 | SHA512_SSE2_Transform(state, data); | ||
| 517 | return; | ||
| 518 | } | ||
| 519 | #endif | ||
| 520 | |||
| 521 | #define S0(x) (rotrFixed(x,28)^rotrFixed(x,34)^rotrFixed(x,39)) | ||
| 522 | #define S1(x) (rotrFixed(x,14)^rotrFixed(x,18)^rotrFixed(x,41)) | ||
| 523 | #define s0(x) (rotrFixed(x,1)^rotrFixed(x,8)^(x>>7)) | ||
| 524 | #define s1(x) (rotrFixed(x,19)^rotrFixed(x,61)^(x>>6)) | ||
| 525 | |||
| 526 | #define R(i) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+SHA512_K[i+j]+(j?blk2(i):blk0(i));\ | ||
| 527 | d(i)+=h(i);h(i)+=S0(a(i))+Maj(a(i),b(i),c(i)) | ||
| 528 | |||
| 529 | word64 W[16]; | ||
| 530 | word64 T[8]; | ||
| 531 | /* Copy context->state[] to working vars */ | ||
| 532 | memcpy(T, state, sizeof(T)); | ||
| 533 | /* 80 operations, partially loop unrolled */ | ||
| 534 | for (unsigned int j=0; j<80; j+=16) | ||
| 535 | { | ||
| 536 | R( 0); R( 1); R( 2); R( 3); | ||
| 537 | R( 4); R( 5); R( 6); R( 7); | ||
| 538 | R( 8); R( 9); R(10); R(11); | ||
| 539 | R(12); R(13); R(14); R(15); | ||
| 540 | } | ||
| 541 | /* Add the working vars back into context.state[] */ | ||
| 542 | state[0] += a(0); | ||
| 543 | state[1] += b(0); | ||
| 544 | state[2] += c(0); | ||
| 545 | state[3] += d(0); | ||
| 546 | state[4] += e(0); | ||
| 547 | state[5] += f(0); | ||
| 548 | state[6] += g(0); | ||
| 549 | state[7] += h(0); | ||
| 550 | } | ||
| 551 | |||
| 552 | #endif | ||
| 553 | |||
| 554 | } | ||
diff --git a/src/sha.h b/src/sha.h new file mode 100644 index 0000000..e3af7b4 --- /dev/null +++ b/src/sha.h | |||
| @@ -0,0 +1,177 @@ | |||
| 1 | // This file is public domain | ||
| 2 | // SHA routines extracted as a standalone file from: | ||
| 3 | // Crypto++: a C++ Class Library of Cryptographic Schemes | ||
| 4 | // Version 5.5.2 (9/24/2007) | ||
| 5 | // http://www.cryptopp.com | ||
| 6 | #ifndef CRYPTOPP_SHA_H | ||
| 7 | #define CRYPTOPP_SHA_H | ||
| 8 | #include <stdlib.h> | ||
| 9 | |||
| 10 | namespace CryptoPP | ||
| 11 | { | ||
| 12 | |||
| 13 | // | ||
| 14 | // Dependencies | ||
| 15 | // | ||
| 16 | |||
| 17 | typedef unsigned char byte; | ||
| 18 | typedef unsigned short word16; | ||
| 19 | typedef unsigned int word32; | ||
| 20 | #if defined(_MSC_VER) || defined(__BORLANDC__) | ||
| 21 | typedef unsigned __int64 word64; | ||
| 22 | #else | ||
| 23 | typedef unsigned long long word64; | ||
| 24 | #endif | ||
| 25 | |||
| 26 | template <class T> inline T rotlFixed(T x, unsigned int y) | ||
| 27 | { | ||
| 28 | assert(y < sizeof(T)*8); | ||
| 29 | return T((x<<y) | (x>>(sizeof(T)*8-y))); | ||
| 30 | } | ||
| 31 | |||
| 32 | template <class T> inline T rotrFixed(T x, unsigned int y) | ||
| 33 | { | ||
| 34 | assert(y < sizeof(T)*8); | ||
| 35 | return T((x>>y) | (x<<(sizeof(T)*8-y))); | ||
| 36 | } | ||
| 37 | |||
| 38 | // ************** endian reversal *************** | ||
| 39 | |||
| 40 | #ifdef _MSC_VER | ||
| 41 | #if _MSC_VER >= 1400 | ||
| 42 | #define CRYPTOPP_FAST_ROTATE(x) 1 | ||
| 43 | #elif _MSC_VER >= 1300 | ||
| 44 | #define CRYPTOPP_FAST_ROTATE(x) ((x) == 32 | (x) == 64) | ||
| 45 | #else | ||
| 46 | #define CRYPTOPP_FAST_ROTATE(x) ((x) == 32) | ||
| 47 | #endif | ||
| 48 | #elif (defined(__MWERKS__) && TARGET_CPU_PPC) || \ | ||
| 49 | (defined(__GNUC__) && (defined(_ARCH_PWR2) || defined(_ARCH_PWR) || defined(_ARCH_PPC) || defined(_ARCH_PPC64) || defined(_ARCH_COM))) | ||
| 50 | #define CRYPTOPP_FAST_ROTATE(x) ((x) == 32) | ||
| 51 | #elif defined(__GNUC__) && (CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X86) // depend on GCC's peephole optimization to generate rotate instructions | ||
| 52 | #define CRYPTOPP_FAST_ROTATE(x) 1 | ||
| 53 | #else | ||
| 54 | #define CRYPTOPP_FAST_ROTATE(x) 0 | ||
| 55 | #endif | ||
| 56 | |||
| 57 | inline byte ByteReverse(byte value) | ||
| 58 | { | ||
| 59 | return value; | ||
| 60 | } | ||
| 61 | |||
| 62 | inline word16 ByteReverse(word16 value) | ||
| 63 | { | ||
| 64 | #ifdef CRYPTOPP_BYTESWAP_AVAILABLE | ||
| 65 | return bswap_16(value); | ||
| 66 | #elif defined(_MSC_VER) && _MSC_VER >= 1300 | ||
| 67 | return _byteswap_ushort(value); | ||
| 68 | #else | ||
| 69 | return rotlFixed(value, 8U); | ||
| 70 | #endif | ||
| 71 | } | ||
| 72 | |||
| 73 | inline word32 ByteReverse(word32 value) | ||
| 74 | { | ||
| 75 | #if defined(__GNUC__) | ||
| 76 | __asm__ ("bswap %0" : "=r" (value) : "0" (value)); | ||
| 77 | return value; | ||
| 78 | #elif defined(CRYPTOPP_BYTESWAP_AVAILABLE) | ||
| 79 | return bswap_32(value); | ||
| 80 | #elif defined(__MWERKS__) && TARGET_CPU_PPC | ||
| 81 | return (word32)__lwbrx(&value,0); | ||
| 82 | #elif _MSC_VER >= 1400 || (_MSC_VER >= 1300 && !defined(_DLL)) | ||
| 83 | return _byteswap_ulong(value); | ||
| 84 | #elif CRYPTOPP_FAST_ROTATE(32) | ||
| 85 | // 5 instructions with rotate instruction, 9 without | ||
| 86 | return (rotrFixed(value, 8U) & 0xff00ff00) | (rotlFixed(value, 8U) & 0x00ff00ff); | ||
| 87 | #else | ||
| 88 | // 6 instructions with rotate instruction, 8 without | ||
| 89 | value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8); | ||
| 90 | return rotlFixed(value, 16U); | ||
| 91 | #endif | ||
| 92 | } | ||
| 93 | |||
| 94 | #ifdef WORD64_AVAILABLE | ||
| 95 | inline word64 ByteReverse(word64 value) | ||
| 96 | { | ||
| 97 | #if defined(__GNUC__) && defined(__x86_64__) | ||
| 98 | __asm__ ("bswap %0" : "=r" (value) : "0" (value)); | ||
| 99 | return value; | ||
| 100 | #elif defined(CRYPTOPP_BYTESWAP_AVAILABLE) | ||
| 101 | return bswap_64(value); | ||
| 102 | #elif defined(_MSC_VER) && _MSC_VER >= 1300 | ||
| 103 | return _byteswap_uint64(value); | ||
| 104 | #elif defined(CRYPTOPP_SLOW_WORD64) | ||
| 105 | return (word64(ByteReverse(word32(value))) << 32) | ByteReverse(word32(value>>32)); | ||
| 106 | #else | ||
| 107 | value = ((value & W64LIT(0xFF00FF00FF00FF00)) >> 8) | ((value & W64LIT(0x00FF00FF00FF00FF)) << 8); | ||
| 108 | value = ((value & W64LIT(0xFFFF0000FFFF0000)) >> 16) | ((value & W64LIT(0x0000FFFF0000FFFF)) << 16); | ||
| 109 | return rotlFixed(value, 32U); | ||
| 110 | #endif | ||
| 111 | } | ||
| 112 | #endif | ||
| 113 | |||
| 114 | |||
| 115 | // | ||
| 116 | // SHA | ||
| 117 | // | ||
| 118 | |||
| 119 | // http://www.weidai.com/scan-mirror/md.html#SHA-1 | ||
| 120 | class SHA1 | ||
| 121 | { | ||
| 122 | public: | ||
| 123 | typedef word32 HashWordType; | ||
| 124 | static void InitState(word32 *state); | ||
| 125 | static void Transform(word32 *digest, const word32 *data); | ||
| 126 | static const char * StaticAlgorithmName() {return "SHA-1";} | ||
| 127 | }; | ||
| 128 | |||
| 129 | typedef SHA1 SHA; // for backwards compatibility | ||
| 130 | |||
| 131 | // implements the SHA-256 standard | ||
| 132 | class SHA256 | ||
| 133 | { | ||
| 134 | public: | ||
| 135 | typedef word32 HashWordType; | ||
| 136 | static void InitState(word32 *state); | ||
| 137 | static void Transform(word32 *digest, const word32 *data); | ||
| 138 | static const char * StaticAlgorithmName() {return "SHA-256";} | ||
| 139 | }; | ||
| 140 | |||
| 141 | // implements the SHA-224 standard | ||
| 142 | class SHA224 | ||
| 143 | { | ||
| 144 | public: | ||
| 145 | typedef word32 HashWordType; | ||
| 146 | static void InitState(word32 *state); | ||
| 147 | static void Transform(word32 *digest, const word32 *data) {SHA256::Transform(digest, data);} | ||
| 148 | static const char * StaticAlgorithmName() {return "SHA-224";} | ||
| 149 | }; | ||
| 150 | |||
| 151 | #ifdef WORD64_AVAILABLE | ||
| 152 | |||
| 153 | // implements the SHA-512 standard | ||
| 154 | class SHA512 | ||
| 155 | { | ||
| 156 | public: | ||
| 157 | typedef word64 HashWordType; | ||
| 158 | static void InitState(word64 *state); | ||
| 159 | static void Transform(word64 *digest, const word64 *data); | ||
| 160 | static const char * StaticAlgorithmName() {return "SHA-512";} | ||
| 161 | }; | ||
| 162 | |||
| 163 | // implements the SHA-384 standard | ||
| 164 | class SHA384 | ||
| 165 | { | ||
| 166 | public: | ||
| 167 | typedef word64 HashWordType; | ||
| 168 | static void InitState(word64 *state); | ||
| 169 | static void Transform(word64 *digest, const word64 *data) {SHA512::Transform(digest, data);} | ||
| 170 | static const char * StaticAlgorithmName() {return "SHA-384";} | ||
| 171 | }; | ||
| 172 | |||
| 173 | #endif | ||
| 174 | |||
| 175 | } | ||
| 176 | |||
| 177 | #endif | ||
diff --git a/src/test_btfaddr.cpp b/src/test_btfaddr.cpp new file mode 100644 index 0000000..b40dcc1 --- /dev/null +++ b/src/test_btfaddr.cpp | |||
| @@ -0,0 +1,142 @@ | |||
| 1 | // Standalone tests for btfaddr (ported from Itzal hidden.rs tests). | ||
| 2 | // Build (UCRT64): | ||
| 3 | // g++ -std=gnu++14 -DSECP256K1_STATIC -I../deps/include test_btfaddr.cpp btfaddr.cpp \ | ||
| 4 | // -L../deps/lib -lsecp256k1 -lssl -lcrypto -o test_btfaddr.exe | ||
| 5 | |||
| 6 | #include "btfaddr.h" | ||
| 7 | #include <openssl/rand.h> | ||
| 8 | #define SECP256K1_STATIC | ||
| 9 | #include <secp256k1.h> | ||
| 10 | #include <secp256k1_schnorrsig.h> | ||
| 11 | #include <secp256k1_extrakeys.h> | ||
| 12 | #include <nlohmann/json.hpp> | ||
| 13 | #include <cstdio> | ||
| 14 | #include <cstring> | ||
| 15 | #include <string> | ||
| 16 | |||
| 17 | using json = nlohmann::json; | ||
| 18 | |||
| 19 | static int g_fail = 0; | ||
| 20 | #define CHECK(cond, name) do { \ | ||
| 21 | if (cond) { printf(" ok %s\n", name); } \ | ||
| 22 | else { printf(" FAIL %s\n", name); g_fail++; } } while(0) | ||
| 23 | |||
| 24 | static std::string ToUpper(const std::string& s) | ||
| 25 | { | ||
| 26 | std::string r = s; | ||
| 27 | for (char& c : r) c = (char)toupper((unsigned char)c); | ||
| 28 | return r; | ||
| 29 | } | ||
| 30 | |||
| 31 | int main() | ||
| 32 | { | ||
| 33 | secp256k1_context* ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); | ||
| 34 | unsigned char seed[32]; RAND_bytes(seed, 32); secp256k1_context_randomize(ctx, seed); | ||
| 35 | |||
| 36 | printf("base32_roundtrips\n"); | ||
| 37 | { | ||
| 38 | std::vector<std::vector<unsigned char>> cases; | ||
| 39 | std::string txt = "hello btf shadow 0123456789"; | ||
| 40 | cases.push_back(std::vector<unsigned char>(txt.begin(), txt.end())); | ||
| 41 | cases.push_back(std::vector<unsigned char>(34, 0x00)); | ||
| 42 | cases.push_back(std::vector<unsigned char>(34, 0xff)); | ||
| 43 | for (auto& data : cases) | ||
| 44 | { | ||
| 45 | std::string enc = btf::Base32Encode(data.data(), data.size()); | ||
| 46 | std::vector<unsigned char> dec; | ||
| 47 | bool ok = btf::Base32Decode(enc, dec); | ||
| 48 | // decode may include trailing partial byte handling; compare the meaningful prefix | ||
| 49 | CHECK(ok && dec.size() >= data.size() && | ||
| 50 | memcmp(dec.data(), data.data(), data.size()) == 0, "roundtrip"); | ||
| 51 | } | ||
| 52 | } | ||
| 53 | |||
| 54 | printf("address_roundtrips_and_is_lowercase_hostname\n"); | ||
| 55 | { | ||
| 56 | unsigned char pk[32]; memset(pk, 7, 32); | ||
| 57 | std::string a = btf::Address(pk); | ||
| 58 | CHECK(a.size() > 4 && a.compare(a.size()-4, 4, ".btf") == 0, "ends with .btf"); | ||
| 59 | CHECK(btf::IsBtf(a), "IsBtf true"); | ||
| 60 | std::string label = a.substr(0, a.size()-4); | ||
| 61 | bool lc = true; | ||
| 62 | for (unsigned char c : label) | ||
| 63 | if (!((c >= 'a' && c <= 'z') || (c >= '2' && c <= '7'))) lc = false; | ||
| 64 | CHECK(lc, "label is lowercase base32 hostname"); | ||
| 65 | unsigned char out[32]; | ||
| 66 | CHECK(btf::ParseAddress(a, out) && memcmp(out, pk, 32) == 0, "parse round-trips"); | ||
| 67 | CHECK(btf::ParseAddress(ToUpper(a), out) && memcmp(out, pk, 32) == 0, "parse case-insensitive"); | ||
| 68 | } | ||
| 69 | |||
| 70 | printf("rejects_tampered_address\n"); | ||
| 71 | { | ||
| 72 | unsigned char pk[32]; memset(pk, 9, 32); | ||
| 73 | std::string a = btf::Address(pk); | ||
| 74 | std::string t = a; | ||
| 75 | t[0] = (t[0] == 'a') ? 'b' : 'a'; | ||
| 76 | unsigned char out[32]; | ||
| 77 | CHECK(!(btf::ParseAddress(t, out) && memcmp(out, pk, 32) == 0), "tampered address rejected"); | ||
| 78 | } | ||
| 79 | |||
| 80 | printf("rejects_non_btf\n"); | ||
| 81 | { | ||
| 82 | unsigned char out[32]; | ||
| 83 | CHECK(!btf::IsBtf("example.com"), "example.com not btf"); | ||
| 84 | CHECK(!btf::ParseAddress("example.com", out), "parse example.com fails"); | ||
| 85 | CHECK(!btf::ParseAddress("not-base-32-!!!.btf", out), "parse invalid base32 fails"); | ||
| 86 | } | ||
| 87 | |||
| 88 | const std::string ENC_HEX = "aabbccddeeff00112233445566778899aabbccddeeff00112233445566778899"; | ||
| 89 | |||
| 90 | // helper: fresh keypair -> (seckey, xonly pubkey) | ||
| 91 | auto newKey = [&](unsigned char sk[32], unsigned char pk[32]) { | ||
| 92 | do { RAND_bytes(sk, 32); } while (!secp256k1_ec_seckey_verify(ctx, sk)); | ||
| 93 | secp256k1_keypair kp; secp256k1_keypair_create(ctx, &kp, sk); | ||
| 94 | secp256k1_xonly_pubkey xp; secp256k1_keypair_xonly_pub(ctx, &xp, NULL, &kp); | ||
| 95 | secp256k1_xonly_pubkey_serialize(ctx, pk, &xp); | ||
| 96 | }; | ||
| 97 | |||
| 98 | printf("descriptor_signs_and_self_certifies\n"); | ||
| 99 | { | ||
| 100 | unsigned char sk[32], pk[32]; newKey(sk, pk); | ||
| 101 | std::string d = btf::SignDescriptor(ctx, sk, ENC_HEX, "meeting-node-abc", 1000); | ||
| 102 | CHECK(!d.empty(), "sign produced descriptor"); | ||
| 103 | btf::Descriptor got; | ||
| 104 | CHECK(btf::VerifyDescriptor(ctx, d, pk, got), "own key verifies"); | ||
| 105 | CHECK(got.meeting_node == "meeting-node-abc" && got.enc == ENC_HEX && got.created == 1000, "fields match"); | ||
| 106 | unsigned char sk2[32], pk2[32]; newKey(sk2, pk2); | ||
| 107 | btf::Descriptor bad; | ||
| 108 | CHECK(!btf::VerifyDescriptor(ctx, d, pk2, bad), "different key rejected"); | ||
| 109 | } | ||
| 110 | |||
| 111 | printf("descriptor_rejects_tampering\n"); | ||
| 112 | { | ||
| 113 | unsigned char sk[32], pk[32]; newKey(sk, pk); | ||
| 114 | std::string d = btf::SignDescriptor(ctx, sk, ENC_HEX, "node-1", 5); | ||
| 115 | json j = json::parse(d); j["meeting_node"] = "evil-node"; | ||
| 116 | btf::Descriptor o; | ||
| 117 | CHECK(!btf::VerifyDescriptor(ctx, j.dump(), pk, o), "tampered meeting_node rejected"); | ||
| 118 | json j2 = json::parse(d); j2["enc"] = "00000000000000000000000000000000000000000000000000000000deadbeef"; | ||
| 119 | CHECK(!btf::VerifyDescriptor(ctx, j2.dump(), pk, o), "tampered enc rejected"); | ||
| 120 | } | ||
| 121 | |||
| 122 | printf("full_resolve_chain_from_address\n"); | ||
| 123 | { | ||
| 124 | unsigned char sk[32], pk[32]; newKey(sk, pk); | ||
| 125 | std::string addr = btf::Address(pk); | ||
| 126 | unsigned char resolved[32]; | ||
| 127 | CHECK(btf::ParseAddress(addr, resolved), "address parses"); | ||
| 128 | std::string d = btf::SignDescriptor(ctx, sk, ENC_HEX, "meeting", 1); | ||
| 129 | btf::Descriptor o; | ||
| 130 | CHECK(btf::VerifyDescriptor(ctx, d, resolved, o), "descriptor verifies under resolved key"); | ||
| 131 | } | ||
| 132 | |||
| 133 | // Show a sample address so we can eyeball the format | ||
| 134 | { | ||
| 135 | unsigned char sk[32], pk[32]; newKey(sk, pk); | ||
| 136 | printf("\nsample .btf address:\n %s\n", btf::Address(pk).c_str()); | ||
| 137 | } | ||
| 138 | |||
| 139 | printf("\n%s (%d failures)\n", g_fail == 0 ? "ALL TESTS PASSED" : "TESTS FAILED", g_fail); | ||
| 140 | secp256k1_context_destroy(ctx); | ||
| 141 | return g_fail == 0 ? 0 : 1; | ||
| 142 | } | ||
diff --git a/src/test_btfchan.cpp b/src/test_btfchan.cpp new file mode 100644 index 0000000..5a66560 --- /dev/null +++ b/src/test_btfchan.cpp | |||
| @@ -0,0 +1,83 @@ | |||
| 1 | // Standalone tests for btfchan (ported from Itzal echan.rs behavior). | ||
| 2 | // Build (UCRT64): | ||
| 3 | // g++ -std=gnu++14 test_btfchan.cpp btfchan.cpp -lsodium -o test_btfchan.exe | ||
| 4 | |||
| 5 | #include "btfchan.h" | ||
| 6 | #include <cstdio> | ||
| 7 | #include <cstring> | ||
| 8 | #include <string> | ||
| 9 | #include <vector> | ||
| 10 | |||
| 11 | using namespace btf; | ||
| 12 | static int g_fail = 0; | ||
| 13 | #define CHECK(cond, name) do { \ | ||
| 14 | if (cond) { printf(" ok %s\n", name); } \ | ||
| 15 | else { printf(" FAIL %s\n", name); g_fail++; } } while(0) | ||
| 16 | |||
| 17 | int main() | ||
| 18 | { | ||
| 19 | if (!ChanInit()) { printf("sodium init failed\n"); return 2; } | ||
| 20 | |||
| 21 | // Endpoint (service) has a static keypair; client only knows the static pub. | ||
| 22 | unsigned char ep_pk[32], ep_sk[32]; | ||
| 23 | ChanKeypair(ep_pk, ep_sk); | ||
| 24 | |||
| 25 | printf("handshake_derives_same_key\n"); | ||
| 26 | unsigned char eph_pub[32], k_client[32], k_endpoint[32]; | ||
| 27 | CHECK(ChanClientHandshake(ep_pk, eph_pub, k_client), "client handshake ok"); | ||
| 28 | CHECK(ChanEndpointHandshake(eph_pub, ep_sk, k_endpoint), "endpoint handshake ok"); | ||
| 29 | CHECK(memcmp(k_client, k_endpoint, 32) == 0, "both sides derive the SAME shared key"); | ||
| 30 | |||
| 31 | printf("encrypt_decrypt_roundtrip\n"); | ||
| 32 | { | ||
| 33 | std::string msg = "one CPU one vote -- blinded over the wire"; | ||
| 34 | std::vector<unsigned char> frame = ChanEncryptFrame(k_client, | ||
| 35 | (const unsigned char*)msg.data(), msg.size()); | ||
| 36 | // frame = [len:4][nonce:24][ct||tag] | ||
| 37 | size_t bodylen = (frame[0]<<24)|(frame[1]<<16)|(frame[2]<<8)|frame[3]; | ||
| 38 | CHECK(bodylen == frame.size() - 4, "length prefix correct"); | ||
| 39 | std::vector<unsigned char> pt; | ||
| 40 | CHECK(ChanDecryptBody(k_endpoint, &frame[4], bodylen, pt), "endpoint decrypts"); | ||
| 41 | CHECK(pt.size() == msg.size() && memcmp(pt.data(), msg.data(), msg.size()) == 0, "plaintext matches"); | ||
| 42 | } | ||
| 43 | |||
| 44 | printf("tampered_ciphertext_fails\n"); | ||
| 45 | { | ||
| 46 | std::string msg = "secret block"; | ||
| 47 | std::vector<unsigned char> frame = ChanEncryptFrame(k_client, | ||
| 48 | (const unsigned char*)msg.data(), msg.size()); | ||
| 49 | size_t bodylen = frame.size() - 4; | ||
| 50 | frame[frame.size()-1] ^= 0x01; // flip a bit in the tag/ciphertext | ||
| 51 | std::vector<unsigned char> pt; | ||
| 52 | CHECK(!ChanDecryptBody(k_endpoint, &frame[4], bodylen, pt), "tampered frame rejected"); | ||
| 53 | } | ||
| 54 | |||
| 55 | printf("wrong_key_fails\n"); | ||
| 56 | { | ||
| 57 | unsigned char other_pk[32], other_sk[32]; | ||
| 58 | ChanKeypair(other_pk, other_sk); | ||
| 59 | unsigned char eph2[32], kbad[32]; | ||
| 60 | ChanClientHandshake(other_pk, eph2, kbad); // box to a DIFFERENT endpoint | ||
| 61 | std::string msg = "for someone else"; | ||
| 62 | std::vector<unsigned char> frame = ChanEncryptFrame(kbad, | ||
| 63 | (const unsigned char*)msg.data(), msg.size()); | ||
| 64 | size_t bodylen = frame.size() - 4; | ||
| 65 | std::vector<unsigned char> pt; | ||
| 66 | CHECK(!ChanDecryptBody(k_endpoint, &frame[4], bodylen, pt), "our endpoint can't open someone else's box"); | ||
| 67 | } | ||
| 68 | |||
| 69 | printf("empty_and_large_payloads\n"); | ||
| 70 | { | ||
| 71 | std::vector<unsigned char> empty; | ||
| 72 | std::vector<unsigned char> f0 = ChanEncryptFrame(k_client, NULL, 0); | ||
| 73 | std::vector<unsigned char> o0; | ||
| 74 | CHECK(ChanDecryptBody(k_endpoint, &f0[4], f0.size()-4, o0) && o0.empty(), "empty payload roundtrips"); | ||
| 75 | std::vector<unsigned char> big(200000, 0xAB); | ||
| 76 | std::vector<unsigned char> fb = ChanEncryptFrame(k_client, big.data(), big.size()); | ||
| 77 | std::vector<unsigned char> ob; | ||
| 78 | CHECK(ChanDecryptBody(k_endpoint, &fb[4], fb.size()-4, ob) && ob == big, "200KB payload roundtrips"); | ||
| 79 | } | ||
| 80 | |||
| 81 | printf("\n%s (%d failures)\n", g_fail == 0 ? "ALL TESTS PASSED" : "TESTS FAILED", g_fail); | ||
| 82 | return g_fail == 0 ? 0 : 1; | ||
| 83 | } | ||
diff --git a/src/test_btfrv.cpp b/src/test_btfrv.cpp new file mode 100644 index 0000000..291e660 --- /dev/null +++ b/src/test_btfrv.cpp | |||
| @@ -0,0 +1,116 @@ | |||
| 1 | // Standalone loopback test of the rendezvous transport + echan on top. | ||
| 2 | // A relay, a service and a client all run in one process on 127.0.0.1 (a unit | ||
| 3 | // test of the protocol logic -- NOT a network/LAN test). Proves: service | ||
| 4 | // registers, client pairs by pubkey through the relay, and they exchange data | ||
| 5 | // end-to-end encrypted so the relay only ever forwards ciphertext. | ||
| 6 | // | ||
| 7 | // Build (UCRT64): | ||
| 8 | // g++ -std=gnu++14 test_btfrv.cpp btfrv.cpp btfchan.cpp -lsodium -lws2_32 -o test_btfrv.exe | ||
| 9 | |||
| 10 | #include "btfrv.h" | ||
| 11 | #include "btfchan.h" | ||
| 12 | #include <cstdio> | ||
| 13 | #include <cstring> | ||
| 14 | #include <string> | ||
| 15 | #include <vector> | ||
| 16 | #include <thread> | ||
| 17 | #include <chrono> | ||
| 18 | |||
| 19 | using namespace btf; | ||
| 20 | static int g_fail = 0; | ||
| 21 | #define CHECK(cond, name) do { \ | ||
| 22 | if (cond) { printf(" ok %s\n", name); } \ | ||
| 23 | else { printf(" FAIL %s\n", name); g_fail++; } } while(0) | ||
| 24 | |||
| 25 | static const unsigned short PORT = 18443; | ||
| 26 | |||
| 27 | // echan framing over a rendezvous socket | ||
| 28 | static bool WriteFrame(RvSocket s, const unsigned char shared[32], const std::string& pt) | ||
| 29 | { | ||
| 30 | std::vector<unsigned char> f = ChanEncryptFrame(shared, (const unsigned char*)pt.data(), pt.size()); | ||
| 31 | return RvWriteN(s, f.data(), (int)f.size()); | ||
| 32 | } | ||
| 33 | static bool ReadFrame(RvSocket s, const unsigned char shared[32], std::string& out) | ||
| 34 | { | ||
| 35 | unsigned char len[4]; | ||
| 36 | if (!RvReadN(s, len, 4)) return false; | ||
| 37 | size_t n = ((size_t)len[0]<<24)|((size_t)len[1]<<16)|((size_t)len[2]<<8)|len[3]; | ||
| 38 | if (n == 0 || n > (1u<<20)) return false; | ||
| 39 | std::vector<unsigned char> body(n); | ||
| 40 | if (!RvReadN(s, body.data(), (int)n)) return false; | ||
| 41 | std::vector<unsigned char> pt; | ||
| 42 | if (!ChanDecryptBody(shared, body.data(), (int)n, pt)) return false; | ||
| 43 | out.assign((char*)pt.data(), pt.size()); | ||
| 44 | return true; | ||
| 45 | } | ||
| 46 | |||
| 47 | static std::string g_svcGot; | ||
| 48 | static bool g_svcOk = false; | ||
| 49 | |||
| 50 | static void ServiceThread(std::vector<unsigned char> pairing_id, std::vector<unsigned char> svc_enc_sk) | ||
| 51 | { | ||
| 52 | RvSocket s = RvServiceRegister("127.0.0.1", PORT, pairing_id.data()); | ||
| 53 | if (s == RV_INVALID) return; | ||
| 54 | // read the client's ephemeral x25519 public key | ||
| 55 | unsigned char eph[32]; | ||
| 56 | if (!RvReadN(s, eph, 32)) { RvClose(s); return; } | ||
| 57 | unsigned char shared[32]; | ||
| 58 | if (!ChanEndpointHandshake(eph, svc_enc_sk.data(), shared)) { RvClose(s); return; } | ||
| 59 | std::string msg; | ||
| 60 | if (!ReadFrame(s, shared, msg)) { RvClose(s); return; } | ||
| 61 | g_svcGot = msg; | ||
| 62 | WriteFrame(s, shared, std::string("block accepted: ") + msg); | ||
| 63 | g_svcOk = true; | ||
| 64 | RvClose(s); | ||
| 65 | } | ||
| 66 | |||
| 67 | int main() | ||
| 68 | { | ||
| 69 | if (!ChanInit() || !RvInit()) { printf("init failed\n"); return 2; } | ||
| 70 | |||
| 71 | // service identity: a 32-byte .btf pairing id + an x25519 enc keypair | ||
| 72 | unsigned char svc_enc_pk[32], svc_enc_sk[32]; | ||
| 73 | ChanKeypair(svc_enc_pk, svc_enc_sk); | ||
| 74 | std::vector<unsigned char> pairing_id(32); | ||
| 75 | for (int i = 0; i < 32; i++) pairing_id[i] = (unsigned char)(i * 7 + 1); | ||
| 76 | |||
| 77 | printf("rendezvous_relay_pairs_and_forwards_encrypted\n"); | ||
| 78 | |||
| 79 | std::thread relay([]{ RvRelayRun(PORT); }); | ||
| 80 | std::this_thread::sleep_for(std::chrono::milliseconds(300)); // let it bind | ||
| 81 | |||
| 82 | std::thread svc(ServiceThread, pairing_id, std::vector<unsigned char>(svc_enc_sk, svc_enc_sk+32)); | ||
| 83 | std::this_thread::sleep_for(std::chrono::milliseconds(300)); // let service register | ||
| 84 | |||
| 85 | // client dials the pairing id through the relay | ||
| 86 | RvSocket c = RvClientConnect("127.0.0.1", PORT, pairing_id.data()); | ||
| 87 | CHECK(c != RV_INVALID, "client paired to service via relay"); | ||
| 88 | if (c != RV_INVALID) | ||
| 89 | { | ||
| 90 | unsigned char eph_pub[32], shared_client[32]; | ||
| 91 | CHECK(ChanClientHandshake(svc_enc_pk, eph_pub, shared_client), "client handshake"); | ||
| 92 | CHECK(RvWriteN(c, eph_pub, 32), "client sends ephemeral pubkey"); | ||
| 93 | CHECK(WriteFrame(c, shared_client, "hello one-cpu-one-vote"), "client sends encrypted frame"); | ||
| 94 | std::string reply; | ||
| 95 | CHECK(ReadFrame(c, shared_client, reply), "client reads encrypted reply"); | ||
| 96 | CHECK(reply == "block accepted: hello one-cpu-one-vote", "end-to-end message round-trips through relay"); | ||
| 97 | RvClose(c); | ||
| 98 | } | ||
| 99 | |||
| 100 | svc.join(); | ||
| 101 | CHECK(g_svcOk && g_svcGot == "hello one-cpu-one-vote", "service received the decrypted plaintext"); | ||
| 102 | |||
| 103 | printf("unknown_pubkey_is_rejected\n"); | ||
| 104 | { | ||
| 105 | unsigned char other[32]; | ||
| 106 | for (int i = 0; i < 32; i++) other[i] = 0xEE; | ||
| 107 | RvSocket bad = RvClientConnect("127.0.0.1", PORT, other); | ||
| 108 | CHECK(bad == RV_INVALID, "client for unregistered .btf is rejected"); | ||
| 109 | } | ||
| 110 | |||
| 111 | RvRelayStop(); | ||
| 112 | relay.join(); | ||
| 113 | |||
| 114 | printf("\n%s (%d failures)\n", g_fail == 0 ? "ALL TESTS PASSED" : "TESTS FAILED", g_fail); | ||
| 115 | return g_fail == 0 ? 0 : 1; | ||
| 116 | } | ||
diff --git a/src/test_btftunnel.cpp b/src/test_btftunnel.cpp new file mode 100644 index 0000000..df01da8 --- /dev/null +++ b/src/test_btftunnel.cpp | |||
| @@ -0,0 +1,97 @@ | |||
| 1 | // Full-stack loopback test of the anonymous tunnel: relay + service + client in | ||
| 2 | // one process on 127.0.0.1 (unit test of the logic, NOT a LAN/network test). | ||
| 3 | // The app-facing sockets are plain TCP; the wire between them is echan over the | ||
| 4 | // rendezvous relay. Proves CNode can use a .btf peer as an ordinary socket. | ||
| 5 | // | ||
| 6 | // Build (UCRT64): | ||
| 7 | // g++ -std=gnu++14 test_btftunnel.cpp btftunnel.cpp btfrv.cpp btfchan.cpp -lsodium -lws2_32 -o test_btftunnel.exe | ||
| 8 | |||
| 9 | #include "btftunnel.h" | ||
| 10 | #include "btfrv.h" | ||
| 11 | #include "btfchan.h" | ||
| 12 | #include <winsock2.h> | ||
| 13 | #include <cstdio> | ||
| 14 | #include <cstring> | ||
| 15 | #include <string> | ||
| 16 | #include <vector> | ||
| 17 | #include <thread> | ||
| 18 | #include <chrono> | ||
| 19 | |||
| 20 | using namespace btf; | ||
| 21 | static int g_fail = 0; | ||
| 22 | #define CHECK(cond, name) do { \ | ||
| 23 | if (cond) { printf(" ok %s\n", name); } \ | ||
| 24 | else { printf(" FAIL %s\n", name); g_fail++; } } while(0) | ||
| 25 | |||
| 26 | static const unsigned short PORT = 18444; | ||
| 27 | |||
| 28 | static bool RecvN(btf_socket_t s, void* buf, int n) | ||
| 29 | { | ||
| 30 | char* p = (char*)buf; int off = 0; | ||
| 31 | while (off < n) { int r = recv((SOCKET)s, p + off, n - off, 0); if (r <= 0) return false; off += r; } | ||
| 32 | return true; | ||
| 33 | } | ||
| 34 | static bool SendN(btf_socket_t s, const void* buf, int n) | ||
| 35 | { | ||
| 36 | const char* p = (const char*)buf; int off = 0; | ||
| 37 | while (off < n) { int r = send((SOCKET)s, p + off, n - off, 0); if (r <= 0) return false; off += r; } | ||
| 38 | return true; | ||
| 39 | } | ||
| 40 | |||
| 41 | static bool g_svcOk = false; | ||
| 42 | static std::string g_svcGot; | ||
| 43 | |||
| 44 | static void ServiceThread(std::vector<unsigned char> pairing_id, std::vector<unsigned char> enc_sk, int msglen) | ||
| 45 | { | ||
| 46 | RvSocket rv = RvServiceRegister("127.0.0.1", PORT, pairing_id.data()); | ||
| 47 | if (rv == RV_INVALID) return; | ||
| 48 | btf_socket_t app = BtfServiceWrap(rv, enc_sk.data()); | ||
| 49 | if (app == INVALID_SOCKET) return; | ||
| 50 | // Read the client's plaintext message and echo it back (as a normal socket). | ||
| 51 | std::vector<char> buf(msglen); | ||
| 52 | if (!RecvN(app, buf.data(), msglen)) { closesocket((SOCKET)app); return; } | ||
| 53 | g_svcGot.assign(buf.data(), msglen); | ||
| 54 | g_svcOk = SendN(app, buf.data(), msglen); | ||
| 55 | closesocket((SOCKET)app); | ||
| 56 | } | ||
| 57 | |||
| 58 | int main() | ||
| 59 | { | ||
| 60 | if (!TunnelInit()) { printf("init failed\n"); return 2; } | ||
| 61 | |||
| 62 | unsigned char svc_enc_pk[32], svc_enc_sk[32]; | ||
| 63 | ChanKeypair(svc_enc_pk, svc_enc_sk); | ||
| 64 | std::vector<unsigned char> pairing_id(32); | ||
| 65 | for (int i = 0; i < 32; i++) pairing_id[i] = (unsigned char)(i * 3 + 5); | ||
| 66 | |||
| 67 | std::string msg = "hello one-cpu-one-vote via anonymous .btf tunnel"; | ||
| 68 | int msglen = (int)msg.size(); | ||
| 69 | |||
| 70 | printf("anonymous_tunnel_full_stack\n"); | ||
| 71 | |||
| 72 | std::thread relay([]{ RvRelayRun(PORT); }); | ||
| 73 | std::this_thread::sleep_for(std::chrono::milliseconds(300)); | ||
| 74 | std::thread svc(ServiceThread, pairing_id, | ||
| 75 | std::vector<unsigned char>(svc_enc_sk, svc_enc_sk+32), msglen); | ||
| 76 | std::this_thread::sleep_for(std::chrono::milliseconds(300)); | ||
| 77 | |||
| 78 | btf_socket_t app = BtfClientTunnel("127.0.0.1", PORT, pairing_id.data(), svc_enc_pk); | ||
| 79 | CHECK(app != INVALID_SOCKET, "client built anonymous tunnel to service"); | ||
| 80 | if (app != INVALID_SOCKET) | ||
| 81 | { | ||
| 82 | CHECK(SendN(app, msg.data(), msglen), "app writes plaintext to the tunnel socket"); | ||
| 83 | std::vector<char> echo(msglen); | ||
| 84 | CHECK(RecvN(app, echo.data(), msglen), "app reads echo from the tunnel socket"); | ||
| 85 | CHECK(std::string(echo.data(), msglen) == msg, "plaintext round-trips end-to-end through the relay"); | ||
| 86 | closesocket((SOCKET)app); | ||
| 87 | } | ||
| 88 | |||
| 89 | svc.join(); | ||
| 90 | CHECK(g_svcOk && g_svcGot == msg, "service saw the correct decrypted plaintext"); | ||
| 91 | |||
| 92 | RvRelayStop(); | ||
| 93 | relay.join(); | ||
| 94 | |||
| 95 | printf("\n%s (%d failures)\n", g_fail == 0 ? "ALL TESTS PASSED" : "TESTS FAILED", g_fail); | ||
| 96 | return g_fail == 0 ? 0 : 1; | ||
| 97 | } | ||
diff --git a/src/test_relayproc.cpp b/src/test_relayproc.cpp new file mode 100644 index 0000000..f9d7f07 --- /dev/null +++ b/src/test_relayproc.cpp | |||
| @@ -0,0 +1,68 @@ | |||
| 1 | // Tests the tunnel against a SEPARATE running bitflashd relay process (not an | ||
| 2 | // in-process relay) -- i.e. exactly the VPS deployment shape, on loopback. | ||
| 3 | // Usage: test_relayproc.exe <port> (a bitflashd must already listen there) | ||
| 4 | // | ||
| 5 | // Build: g++ -std=gnu++14 -O2 -pthread test_relayproc.cpp btftunnel.cpp btfrv.cpp btfchan.cpp -lsodium -lws2_32 -o test_relayproc.exe | ||
| 6 | |||
| 7 | #include "btftunnel.h" | ||
| 8 | #include "btfrv.h" | ||
| 9 | #include "btfchan.h" | ||
| 10 | #include <winsock2.h> | ||
| 11 | #include <cstdio> | ||
| 12 | #include <cstdlib> | ||
| 13 | #include <cstring> | ||
| 14 | #include <string> | ||
| 15 | #include <vector> | ||
| 16 | #include <thread> | ||
| 17 | #include <chrono> | ||
| 18 | |||
| 19 | using namespace btf; | ||
| 20 | static int g_fail = 0; | ||
| 21 | #define CHECK(c,n) do{ if(c){printf(" ok %s\n",n);} else {printf(" FAIL %s\n",n); g_fail++;} }while(0) | ||
| 22 | |||
| 23 | static unsigned short PORT = 18446; | ||
| 24 | static const char* HOST = "127.0.0.1"; | ||
| 25 | static bool RecvN(SOCKET s, void* b, int n){char*p=(char*)b;int o=0;while(o<n){int r=recv(s,p+o,n-o,0);if(r<=0)return false;o+=r;}return true;} | ||
| 26 | static bool SendN(SOCKET s, const void* b, int n){const char*p=(const char*)b;int o=0;while(o<n){int r=send(s,p+o,n-o,0);if(r<=0)return false;o+=r;}return true;} | ||
| 27 | |||
| 28 | static bool g_ok=false; static std::string g_got; | ||
| 29 | static void Service(std::vector<unsigned char> id, std::vector<unsigned char> sk, int len) | ||
| 30 | { | ||
| 31 | RvSocket rv = RvServiceRegister(HOST, PORT, id.data()); | ||
| 32 | if (rv==RV_INVALID) return; | ||
| 33 | btf_socket_t app = BtfServiceWrap(rv, sk.data()); | ||
| 34 | if (app==INVALID_SOCKET) return; | ||
| 35 | std::vector<char> buf(len); | ||
| 36 | if(!RecvN((SOCKET)app, buf.data(), len)){closesocket((SOCKET)app);return;} | ||
| 37 | g_got.assign(buf.data(), len); | ||
| 38 | g_ok = SendN((SOCKET)app, buf.data(), len); | ||
| 39 | closesocket((SOCKET)app); | ||
| 40 | } | ||
| 41 | |||
| 42 | int main(int argc, char* argv[]) | ||
| 43 | { | ||
| 44 | if (argc>=2) HOST=argv[1]; if (argc>=3) PORT=(unsigned short)atoi(argv[2]); | ||
| 45 | if(!TunnelInit()){printf("init failed\n");return 2;} | ||
| 46 | unsigned char pk[32], sk[32]; ChanKeypair(pk,sk); | ||
| 47 | std::vector<unsigned char> id(32); for(int i=0;i<32;i++) id[i]=(unsigned char)(i*11+3); | ||
| 48 | std::string msg="anonymous hop through a real bitflashd relay process"; | ||
| 49 | int len=(int)msg.size(); | ||
| 50 | |||
| 51 | printf("tunnel_through_external_relay_process (port %u)\n", PORT); | ||
| 52 | std::thread svc(Service, id, std::vector<unsigned char>(sk,sk+32), len); | ||
| 53 | std::this_thread::sleep_for(std::chrono::milliseconds(400)); | ||
| 54 | |||
| 55 | btf_socket_t app = BtfClientTunnel(HOST, PORT, id.data(), pk); | ||
| 56 | CHECK(app!=INVALID_SOCKET, "client tunneled through the running bitflashd"); | ||
| 57 | if(app!=INVALID_SOCKET){ | ||
| 58 | CHECK(SendN((SOCKET)app,msg.data(),len), "app writes plaintext"); | ||
| 59 | std::vector<char> echo(len); | ||
| 60 | CHECK(RecvN((SOCKET)app,echo.data(),len), "app reads echo"); | ||
| 61 | CHECK(std::string(echo.data(),len)==msg, "round-trips end-to-end via the relay process"); | ||
| 62 | closesocket((SOCKET)app); | ||
| 63 | } | ||
| 64 | svc.join(); | ||
| 65 | CHECK(g_ok && g_got==msg, "service saw correct plaintext"); | ||
| 66 | printf("\n%s (%d failures)\n", g_fail==0?"ALL TESTS PASSED":"TESTS FAILED", g_fail); | ||
| 67 | return g_fail==0?0:1; | ||
| 68 | } | ||
diff --git a/src/ui.cpp b/src/ui.cpp new file mode 100644 index 0000000..3e734a5 --- /dev/null +++ b/src/ui.cpp | |||
| @@ -0,0 +1,3265 @@ | |||
| 1 | // Copyright (c) 2009 Satoshi Nakamoto | ||
| 2 | // Distributed under the MIT/X11 software license, see the accompanying | ||
| 3 | // file license.txt or http://www.opensource.org/licenses/mit-license.php. | ||
| 4 | |||
| 5 | #include "headers.h" | ||
| 6 | #ifdef _MSC_VER | ||
| 7 | #include <crtdbg.h> | ||
| 8 | #endif | ||
| 9 | |||
| 10 | |||
| 11 | |||
| 12 | DEFINE_EVENT_TYPE(wxEVT_CROSSTHREADCALL) | ||
| 13 | |||
| 14 | // wx3 is Unicode: conversion bridges for the C functions inherited from 2009 | ||
| 15 | static inline bool ParseMoney(const wxString& str, int64& nRet) | ||
| 16 | { | ||
| 17 | return ParseMoney(std::string(str.mb_str()).c_str(), nRet); | ||
| 18 | } | ||
| 19 | DEFINE_EVENT_TYPE(wxEVT_REPLY1) | ||
| 20 | DEFINE_EVENT_TYPE(wxEVT_REPLY2) | ||
| 21 | DEFINE_EVENT_TYPE(wxEVT_REPLY3) | ||
| 22 | DEFINE_EVENT_TYPE(wxEVT_TABLEADDED) | ||
| 23 | DEFINE_EVENT_TYPE(wxEVT_TABLEUPDATED) | ||
| 24 | DEFINE_EVENT_TYPE(wxEVT_TABLEDELETED) | ||
| 25 | |||
| 26 | CMainFrame* pframeMain = NULL; | ||
| 27 | map<string, string> mapAddressBook; | ||
| 28 | |||
| 29 | |||
| 30 | void ThreadRequestProductDetails(void* parg); | ||
| 31 | void ThreadRandSendTest(void* parg); | ||
| 32 | bool fRandSendTest = false; | ||
| 33 | void RandSend(); | ||
| 34 | |||
| 35 | |||
| 36 | |||
| 37 | |||
| 38 | |||
| 39 | |||
| 40 | ////////////////////////////////////////////////////////////////////////////// | ||
| 41 | // | ||
| 42 | // Util | ||
| 43 | // | ||
| 44 | |||
| 45 | void HandleCtrlA(wxKeyEvent& event) | ||
| 46 | { | ||
| 47 | // Ctrl-a select all | ||
| 48 | wxTextCtrl* textCtrl = (wxTextCtrl*)event.GetEventObject(); | ||
| 49 | if (event.GetModifiers() == wxMOD_CONTROL && event.GetKeyCode() == 'A') | ||
| 50 | textCtrl->SetSelection(-1, -1); | ||
| 51 | event.Skip(); | ||
| 52 | } | ||
| 53 | |||
| 54 | bool Is24HourTime() | ||
| 55 | { | ||
| 56 | //char pszHourFormat[256]; | ||
| 57 | //pszHourFormat[0] = '\0'; | ||
| 58 | //GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_ITIME, pszHourFormat, 256); | ||
| 59 | //return (pszHourFormat[0] != '0'); | ||
| 60 | return true; | ||
| 61 | } | ||
| 62 | |||
| 63 | string DateStr(int64 nTime) | ||
| 64 | { | ||
| 65 | return (string)wxDateTime((time_t)nTime).FormatDate(); | ||
| 66 | } | ||
| 67 | |||
| 68 | string DateTimeStr(int64 nTime) | ||
| 69 | { | ||
| 70 | wxDateTime datetime((time_t)nTime); | ||
| 71 | if (Is24HourTime()) | ||
| 72 | return (string)datetime.Format("%x %H:%M"); | ||
| 73 | else | ||
| 74 | return (string)datetime.Format("%x ") + itostr((datetime.GetHour() + 11) % 12 + 1) + (string)datetime.Format(":%M %p"); | ||
| 75 | } | ||
| 76 | |||
| 77 | wxString GetItemText(wxListCtrl* listCtrl, int nIndex, int nColumn) | ||
| 78 | { | ||
| 79 | // Helper to simplify access to listctrl | ||
| 80 | wxListItem item; | ||
| 81 | item.m_itemId = nIndex; | ||
| 82 | item.m_col = nColumn; | ||
| 83 | item.m_mask = wxLIST_MASK_TEXT; | ||
| 84 | if (!listCtrl->GetItem(item)) | ||
| 85 | return ""; | ||
| 86 | return item.GetText(); | ||
| 87 | } | ||
| 88 | |||
| 89 | int InsertLine(wxListCtrl* listCtrl, const wxString& str0, const wxString& str1) | ||
| 90 | { | ||
| 91 | int nIndex = listCtrl->InsertItem(listCtrl->GetItemCount(), str0); | ||
| 92 | listCtrl->SetItem(nIndex, 1, str1); | ||
| 93 | return nIndex; | ||
| 94 | } | ||
| 95 | |||
| 96 | int InsertLine(wxListCtrl* listCtrl, const wxString& str0, const wxString& str1, const wxString& str2, const wxString& str3, const wxString& str4) | ||
| 97 | { | ||
| 98 | int nIndex = listCtrl->InsertItem(listCtrl->GetItemCount(), str0); | ||
| 99 | listCtrl->SetItem(nIndex, 1, str1); | ||
| 100 | listCtrl->SetItem(nIndex, 2, str2); | ||
| 101 | listCtrl->SetItem(nIndex, 3, str3); | ||
| 102 | listCtrl->SetItem(nIndex, 4, str4); | ||
| 103 | return nIndex; | ||
| 104 | } | ||
| 105 | |||
| 106 | int InsertLine(wxListCtrl* listCtrl, void* pdata, const wxString& str0, const wxString& str1, const wxString& str2, const wxString& str3, const wxString& str4) | ||
| 107 | { | ||
| 108 | int nIndex = listCtrl->InsertItem(listCtrl->GetItemCount(), str0); | ||
| 109 | listCtrl->SetItemPtrData(nIndex, (wxUIntPtr)pdata); | ||
| 110 | listCtrl->SetItem(nIndex, 1, str1); | ||
| 111 | listCtrl->SetItem(nIndex, 2, str2); | ||
| 112 | listCtrl->SetItem(nIndex, 3, str3); | ||
| 113 | listCtrl->SetItem(nIndex, 4, str4); | ||
| 114 | return nIndex; | ||
| 115 | } | ||
| 116 | |||
| 117 | void SetSelection(wxListCtrl* listCtrl, int nIndex) | ||
| 118 | { | ||
| 119 | int nSize = listCtrl->GetItemCount(); | ||
| 120 | long nState = (wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED); | ||
| 121 | for (int i = 0; i < nSize; i++) | ||
| 122 | listCtrl->SetItemState(i, (i == nIndex ? nState : 0), nState); | ||
| 123 | } | ||
| 124 | |||
| 125 | int GetSelection(wxListCtrl* listCtrl) | ||
| 126 | { | ||
| 127 | int nSize = listCtrl->GetItemCount(); | ||
| 128 | for (int i = 0; i < nSize; i++) | ||
| 129 | if (listCtrl->GetItemState(i, wxLIST_STATE_FOCUSED)) | ||
| 130 | return i; | ||
| 131 | return -1; | ||
| 132 | } | ||
| 133 | |||
| 134 | |||
| 135 | string HtmlEscape(const char* psz, bool fMultiLine=false) | ||
| 136 | { | ||
| 137 | int len = 0; | ||
| 138 | for (const char* p = psz; *p; p++) | ||
| 139 | { | ||
| 140 | if (*p == '<') len += 4; | ||
| 141 | else if (*p == '>') len += 4; | ||
| 142 | else if (*p == '&') len += 5; | ||
| 143 | else if (*p == '"') len += 6; | ||
| 144 | else if (*p == ' ' && p > psz && p[-1] == ' ' && p[1] == ' ') len += 6; | ||
| 145 | else if (*p == '\n' && fMultiLine) len += 5; | ||
| 146 | else | ||
| 147 | len++; | ||
| 148 | } | ||
| 149 | string str; | ||
| 150 | str.reserve(len); | ||
| 151 | for (const char* p = psz; *p; p++) | ||
| 152 | { | ||
| 153 | if (*p == '<') str += "<"; | ||
| 154 | else if (*p == '>') str += ">"; | ||
| 155 | else if (*p == '&') str += "&"; | ||
| 156 | else if (*p == '"') str += """; | ||
| 157 | else if (*p == ' ' && p > psz && p[-1] == ' ' && p[1] == ' ') str += " "; | ||
| 158 | else if (*p == '\n' && fMultiLine) str += "<br>\n"; | ||
| 159 | else | ||
| 160 | str += *p; | ||
| 161 | } | ||
| 162 | return str; | ||
| 163 | } | ||
| 164 | |||
| 165 | string HtmlEscape(const string& str, bool fMultiLine=false) | ||
| 166 | { | ||
| 167 | return HtmlEscape(str.c_str(), fMultiLine); | ||
| 168 | } | ||
| 169 | |||
| 170 | void AddToMyProducts(CProduct product) | ||
| 171 | { | ||
| 172 | CProduct& productInsert = mapMyProducts[product.GetHash()]; | ||
| 173 | productInsert = product; | ||
| 174 | InsertLine(pframeMain->m_listCtrlProductsSent, &productInsert, | ||
| 175 | product.mapValue["category"], | ||
| 176 | product.mapValue["title"].substr(0, 100), | ||
| 177 | product.mapValue["description"].substr(0, 100), | ||
| 178 | product.mapValue["price"], | ||
| 179 | ""); | ||
| 180 | } | ||
| 181 | |||
| 182 | |||
| 183 | |||
| 184 | |||
| 185 | |||
| 186 | |||
| 187 | ////////////////////////////////////////////////////////////////////////////// | ||
| 188 | // | ||
| 189 | // Custom events | ||
| 190 | // | ||
| 191 | |||
| 192 | set<void*> setCallbackAvailable; | ||
| 193 | CCriticalSection cs_setCallbackAvailable; | ||
| 194 | |||
| 195 | void AddCallbackAvailable(void* p) | ||
| 196 | { | ||
| 197 | CRITICAL_BLOCK(cs_setCallbackAvailable) | ||
| 198 | setCallbackAvailable.insert(p); | ||
| 199 | } | ||
| 200 | |||
| 201 | void RemoveCallbackAvailable(void* p) | ||
| 202 | { | ||
| 203 | CRITICAL_BLOCK(cs_setCallbackAvailable) | ||
| 204 | setCallbackAvailable.erase(p); | ||
| 205 | } | ||
| 206 | |||
| 207 | bool IsCallbackAvailable(void* p) | ||
| 208 | { | ||
| 209 | CRITICAL_BLOCK(cs_setCallbackAvailable) | ||
| 210 | return setCallbackAvailable.count(p); | ||
| 211 | return false; | ||
| 212 | } | ||
| 213 | |||
| 214 | template<typename T> | ||
| 215 | void AddPendingCustomEvent(wxEvtHandler* pevthandler, int nEventID, const T pbeginIn, const T pendIn) | ||
| 216 | { | ||
| 217 | if (!pevthandler) | ||
| 218 | return; | ||
| 219 | |||
| 220 | const char* pbegin = (pendIn != pbeginIn) ? (const char*)&pbeginIn[0] : NULL; | ||
| 221 | const char* pend = pbegin + (pendIn - pbeginIn) * sizeof(pbeginIn[0]); | ||
| 222 | wxCommandEvent event(nEventID); | ||
| 223 | // wxString in wx3 is Unicode and does not carry raw bytes; | ||
| 224 | // the serialized data travels in a buffer that the receiver frees | ||
| 225 | event.SetClientData(new std::string(pbegin, pend)); | ||
| 226 | |||
| 227 | pevthandler->AddPendingEvent(event); | ||
| 228 | } | ||
| 229 | |||
| 230 | template<class T> | ||
| 231 | void AddPendingCustomEvent(wxEvtHandler* pevthandler, int nEventID, const T& obj) | ||
| 232 | { | ||
| 233 | CDataStream ss; | ||
| 234 | ss << obj; | ||
| 235 | AddPendingCustomEvent(pevthandler, nEventID, ss.begin(), ss.end()); | ||
| 236 | } | ||
| 237 | |||
| 238 | void AddPendingReplyEvent1(void* pevthandler, CDataStream& vRecv) | ||
| 239 | { | ||
| 240 | if (IsCallbackAvailable(pevthandler)) | ||
| 241 | AddPendingCustomEvent((wxEvtHandler*)pevthandler, wxEVT_REPLY1, vRecv.begin(), vRecv.end()); | ||
| 242 | } | ||
| 243 | |||
| 244 | void AddPendingReplyEvent2(void* pevthandler, CDataStream& vRecv) | ||
| 245 | { | ||
| 246 | if (IsCallbackAvailable(pevthandler)) | ||
| 247 | AddPendingCustomEvent((wxEvtHandler*)pevthandler, wxEVT_REPLY2, vRecv.begin(), vRecv.end()); | ||
| 248 | } | ||
| 249 | |||
| 250 | void AddPendingReplyEvent3(void* pevthandler, CDataStream& vRecv) | ||
| 251 | { | ||
| 252 | if (IsCallbackAvailable(pevthandler)) | ||
| 253 | AddPendingCustomEvent((wxEvtHandler*)pevthandler, wxEVT_REPLY3, vRecv.begin(), vRecv.end()); | ||
| 254 | } | ||
| 255 | |||
| 256 | CDataStream GetStreamFromEvent(const wxCommandEvent& event) | ||
| 257 | { | ||
| 258 | std::string* pstrData = (std::string*)event.GetClientData(); | ||
| 259 | if (pstrData == NULL) | ||
| 260 | return CDataStream(SER_NETWORK); | ||
| 261 | CDataStream ss(pstrData->data(), pstrData->data() + pstrData->size(), SER_NETWORK); | ||
| 262 | delete pstrData; | ||
| 263 | ((wxCommandEvent&)event).SetClientData(NULL); | ||
| 264 | return ss; | ||
| 265 | } | ||
| 266 | |||
| 267 | |||
| 268 | |||
| 269 | |||
| 270 | |||
| 271 | |||
| 272 | |||
| 273 | ////////////////////////////////////////////////////////////////////////////// | ||
| 274 | // | ||
| 275 | // CMainFrame | ||
| 276 | // | ||
| 277 | |||
| 278 | CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) | ||
| 279 | { | ||
| 280 | Connect(wxEVT_CROSSTHREADCALL, wxCommandEventHandler(CMainFrame::OnCrossThreadCall), NULL, this); | ||
| 281 | |||
| 282 | // Init | ||
| 283 | fRefreshListCtrl = false; | ||
| 284 | fRefreshListCtrlRunning = false; | ||
| 285 | fOnSetFocusAddress = false; | ||
| 286 | pindexBestLast = NULL; | ||
| 287 | m_choiceFilter->SetSelection(0); | ||
| 288 | m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " "); | ||
| 289 | m_listCtrl->SetFocus(); | ||
| 290 | SetIcon(wxICON(bitcoin)); | ||
| 291 | m_menuOptions->Check(wxID_OPTIONSGENERATEBITCOINS, fGenerateBitcoins); | ||
| 292 | |||
| 293 | // Init toolbar with transparency masked bitmaps | ||
| 294 | m_toolBar->ClearTools(); | ||
| 295 | |||
| 296 | //// shouldn't have to do mask separately anymore, bitmap alpha support added in wx 2.8.9, | ||
| 297 | wxBitmap bmpSend(wxT("send20"), wxBITMAP_TYPE_RESOURCE); | ||
| 298 | bmpSend.SetMask(new wxMask(wxBitmap(wxT("send20mask"), wxBITMAP_TYPE_RESOURCE))); | ||
| 299 | m_toolBar->AddTool(wxID_BUTTONSEND, wxT("&Send Coins"), bmpSend, wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString); | ||
| 300 | |||
| 301 | wxBitmap bmpAddressBook(wxT("addressbook20"), wxBITMAP_TYPE_RESOURCE); | ||
| 302 | bmpAddressBook.SetMask(new wxMask(wxBitmap(wxT("addressbook20mask"), wxBITMAP_TYPE_RESOURCE))); | ||
| 303 | m_toolBar->AddTool(wxID_BUTTONRECEIVE, wxT("&Address Book"), bmpAddressBook, wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString); | ||
| 304 | |||
| 305 | m_toolBar->Realize(); | ||
| 306 | |||
| 307 | // Init column headers | ||
| 308 | int nDateWidth = DateTimeStr(1229413914).size() * 6 + 8; | ||
| 309 | m_listCtrl->InsertColumn(0, "", wxLIST_FORMAT_LEFT, 0); | ||
| 310 | m_listCtrl->InsertColumn(1, "", wxLIST_FORMAT_LEFT, 0); | ||
| 311 | m_listCtrl->InsertColumn(2, "Status", wxLIST_FORMAT_LEFT, 90); | ||
| 312 | m_listCtrl->InsertColumn(3, "Date", wxLIST_FORMAT_LEFT, nDateWidth); | ||
| 313 | m_listCtrl->InsertColumn(4, "Description", wxLIST_FORMAT_LEFT, 409 - nDateWidth); | ||
| 314 | m_listCtrl->InsertColumn(5, "Debit", wxLIST_FORMAT_RIGHT, 79); | ||
| 315 | m_listCtrl->InsertColumn(6, "Credit", wxLIST_FORMAT_RIGHT, 79); | ||
| 316 | |||
| 317 | //m_listCtrlProductsSent->InsertColumn(0, "Category", wxLIST_FORMAT_LEFT, 100); | ||
| 318 | //m_listCtrlProductsSent->InsertColumn(1, "Title", wxLIST_FORMAT_LEFT, 100); | ||
| 319 | //m_listCtrlProductsSent->InsertColumn(2, "Description", wxLIST_FORMAT_LEFT, 100); | ||
| 320 | //m_listCtrlProductsSent->InsertColumn(3, "Price", wxLIST_FORMAT_LEFT, 100); | ||
| 321 | //m_listCtrlProductsSent->InsertColumn(4, "", wxLIST_FORMAT_LEFT, 100); | ||
| 322 | |||
| 323 | //m_listCtrlOrdersSent->InsertColumn(0, "Time", wxLIST_FORMAT_LEFT, 100); | ||
| 324 | //m_listCtrlOrdersSent->InsertColumn(1, "Price", wxLIST_FORMAT_LEFT, 100); | ||
| 325 | //m_listCtrlOrdersSent->InsertColumn(2, "", wxLIST_FORMAT_LEFT, 100); | ||
| 326 | //m_listCtrlOrdersSent->InsertColumn(3, "", wxLIST_FORMAT_LEFT, 100); | ||
| 327 | //m_listCtrlOrdersSent->InsertColumn(4, "", wxLIST_FORMAT_LEFT, 100); | ||
| 328 | |||
| 329 | //m_listCtrlOrdersReceived->InsertColumn(0, "Time", wxLIST_FORMAT_LEFT, 100); | ||
| 330 | //m_listCtrlOrdersReceived->InsertColumn(1, "Price", wxLIST_FORMAT_LEFT, 100); | ||
| 331 | //m_listCtrlOrdersReceived->InsertColumn(2, "Payment Status", wxLIST_FORMAT_LEFT, 100); | ||
| 332 | //m_listCtrlOrdersReceived->InsertColumn(3, "", wxLIST_FORMAT_LEFT, 100); | ||
| 333 | //m_listCtrlOrdersReceived->InsertColumn(4, "", wxLIST_FORMAT_LEFT, 100); | ||
| 334 | |||
| 335 | // Init status bar | ||
| 336 | int pnWidths[3] = { -100, 81, 286 }; | ||
| 337 | m_statusBar->SetFieldsCount(3, pnWidths); | ||
| 338 | |||
| 339 | // Fill your address text box | ||
| 340 | vector<unsigned char> vchPubKey; | ||
| 341 | if (CWalletDB("r").ReadDefaultKey(vchPubKey)) | ||
| 342 | m_textCtrlAddress->SetValue(PubKeyToAddress(vchPubKey)); | ||
| 343 | |||
| 344 | // Fill listctrl with wallet transactions | ||
| 345 | RefreshListCtrl(); | ||
| 346 | } | ||
| 347 | |||
| 348 | CMainFrame::~CMainFrame() | ||
| 349 | { | ||
| 350 | pframeMain = NULL; | ||
| 351 | } | ||
| 352 | |||
| 353 | void Shutdown(void* parg) | ||
| 354 | { | ||
| 355 | static CCriticalSection cs_Shutdown; | ||
| 356 | CRITICAL_BLOCK(cs_Shutdown) | ||
| 357 | { | ||
| 358 | fShutdown = true; | ||
| 359 | nTransactionsUpdated++; | ||
| 360 | DBFlush(false); | ||
| 361 | StopNode(); | ||
| 362 | DBFlush(true); | ||
| 363 | |||
| 364 | printf("Bitcoin exiting\n"); | ||
| 365 | exit(0); | ||
| 366 | } | ||
| 367 | } | ||
| 368 | |||
| 369 | void CMainFrame::OnClose(wxCloseEvent& event) | ||
| 370 | { | ||
| 371 | Destroy(); | ||
| 372 | _beginthread(Shutdown, 0, NULL); | ||
| 373 | } | ||
| 374 | |||
| 375 | void CMainFrame::OnMouseEvents(wxMouseEvent& event) | ||
| 376 | { | ||
| 377 | RandAddSeed(); | ||
| 378 | RAND_add(&event.m_x, sizeof(event.m_x), 0.25); | ||
| 379 | RAND_add(&event.m_y, sizeof(event.m_y), 0.25); | ||
| 380 | } | ||
| 381 | |||
| 382 | void CMainFrame::OnListColBeginDrag(wxListEvent& event) | ||
| 383 | { | ||
| 384 | // Hidden columns not resizeable | ||
| 385 | if (event.GetColumn() <= 1 && !fDebug) | ||
| 386 | event.Veto(); | ||
| 387 | } | ||
| 388 | |||
| 389 | void CMainFrame::InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSort, const wxString& str2, const wxString& str3, const wxString& str4, const wxString& str5, const wxString& str6) | ||
| 390 | { | ||
| 391 | string str0 = strSort; | ||
| 392 | long nData = *(long*)&hashKey; | ||
| 393 | |||
| 394 | if (fNew) | ||
| 395 | { | ||
| 396 | nIndex = m_listCtrl->InsertItem(0, str0); | ||
| 397 | } | ||
| 398 | else | ||
| 399 | { | ||
| 400 | if (nIndex == -1) | ||
| 401 | { | ||
| 402 | // Find item | ||
| 403 | while ((nIndex = m_listCtrl->FindItem(nIndex, nData)) != -1) | ||
| 404 | if (GetItemText(m_listCtrl, nIndex, 1) == hashKey.ToString()) | ||
| 405 | break; | ||
| 406 | if (nIndex == -1) | ||
| 407 | { | ||
| 408 | printf("CMainFrame::InsertLine : Couldn't find item to be updated\n"); | ||
| 409 | return; | ||
| 410 | } | ||
| 411 | } | ||
| 412 | |||
| 413 | // If sort key changed, must delete and reinsert to make it relocate | ||
| 414 | if (GetItemText(m_listCtrl, nIndex, 0) != str0) | ||
| 415 | { | ||
| 416 | m_listCtrl->DeleteItem(nIndex); | ||
| 417 | nIndex = m_listCtrl->InsertItem(0, str0); | ||
| 418 | } | ||
| 419 | } | ||
| 420 | |||
| 421 | m_listCtrl->SetItem(nIndex, 1, hashKey.ToString()); | ||
| 422 | m_listCtrl->SetItem(nIndex, 2, str2); | ||
| 423 | m_listCtrl->SetItem(nIndex, 3, str3); | ||
| 424 | m_listCtrl->SetItem(nIndex, 4, str4); | ||
| 425 | m_listCtrl->SetItem(nIndex, 5, str5); | ||
| 426 | m_listCtrl->SetItem(nIndex, 6, str6); | ||
| 427 | m_listCtrl->SetItemData(nIndex, nData); | ||
| 428 | } | ||
| 429 | |||
| 430 | string FormatTxStatus(const CWalletTx& wtx) | ||
| 431 | { | ||
| 432 | // Status | ||
| 433 | int nDepth = wtx.GetDepthInMainChain(); | ||
| 434 | if (!wtx.IsFinal()) | ||
| 435 | return strprintf("Open for %d blocks", nBestHeight - wtx.nLockTime); | ||
| 436 | else if (nDepth < 6) | ||
| 437 | return strprintf("%d/unconfirmed", nDepth); | ||
| 438 | else | ||
| 439 | return strprintf("%d blocks", nDepth); | ||
| 440 | } | ||
| 441 | |||
| 442 | void CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) | ||
| 443 | { | ||
| 444 | int64 nTime = wtx.nTimeDisplayed = wtx.GetTxTime(); | ||
| 445 | int64 nCredit = wtx.GetCredit(); | ||
| 446 | int64 nDebit = wtx.GetDebit(); | ||
| 447 | int64 nNet = nCredit - nDebit; | ||
| 448 | uint256 hash = wtx.GetHash(); | ||
| 449 | string strStatus = FormatTxStatus(wtx); | ||
| 450 | map<string, string> mapValue = wtx.mapValue; | ||
| 451 | |||
| 452 | // Find the block the tx is in | ||
| 453 | CBlockIndex* pindex = NULL; | ||
| 454 | map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(wtx.hashBlock); | ||
| 455 | if (mi != mapBlockIndex.end()) | ||
| 456 | pindex = (*mi).second; | ||
| 457 | |||
| 458 | // Sort order, unrecorded transactions sort to the top | ||
| 459 | string strSort = strprintf("%010d-%01d-%010u", | ||
| 460 | (pindex ? pindex->nHeight : INT_MAX), | ||
| 461 | (wtx.IsCoinBase() ? 1 : 0), | ||
| 462 | wtx.nTimeReceived); | ||
| 463 | |||
| 464 | // Insert line | ||
| 465 | if (nNet > 0 || wtx.IsCoinBase()) | ||
| 466 | { | ||
| 467 | // | ||
| 468 | // Credit | ||
| 469 | // | ||
| 470 | string strDescription; | ||
| 471 | |||
| 472 | if (wtx.IsCoinBase()) | ||
| 473 | { | ||
| 474 | // Coinbase | ||
| 475 | strDescription = "Generated"; | ||
| 476 | if (nCredit == 0) | ||
| 477 | { | ||
| 478 | int64 nUnmatured = 0; | ||
| 479 | foreach(const CTxOut& txout, wtx.vout) | ||
| 480 | nUnmatured += txout.GetCredit(); | ||
| 481 | if (wtx.IsInMainChain()) | ||
| 482 | strDescription += strprintf(" (%s matures in %d blocks)", FormatMoney(nUnmatured).c_str(), wtx.GetBlocksToMaturity()); | ||
| 483 | else | ||
| 484 | strDescription += " (not accepted)"; | ||
| 485 | } | ||
| 486 | } | ||
| 487 | else if (!mapValue["from"].empty() || !mapValue["message"].empty()) | ||
| 488 | { | ||
| 489 | // Online transaction | ||
| 490 | if (!mapValue["from"].empty()) | ||
| 491 | strDescription += "From: " + mapValue["from"]; | ||
| 492 | if (!mapValue["message"].empty()) | ||
| 493 | { | ||
| 494 | if (!strDescription.empty()) | ||
| 495 | strDescription += " - "; | ||
| 496 | strDescription += mapValue["message"]; | ||
| 497 | } | ||
| 498 | } | ||
| 499 | else | ||
| 500 | { | ||
| 501 | // Offline transaction | ||
| 502 | foreach(const CTxOut& txout, wtx.vout) | ||
| 503 | { | ||
| 504 | if (txout.IsMine()) | ||
| 505 | { | ||
| 506 | vector<unsigned char> vchPubKey; | ||
| 507 | if (ExtractPubKey(txout.scriptPubKey, true, vchPubKey)) | ||
| 508 | { | ||
| 509 | string strAddress = PubKeyToAddress(vchPubKey); | ||
| 510 | if (mapAddressBook.count(strAddress)) | ||
| 511 | { | ||
| 512 | strDescription += "Received with: "; | ||
| 513 | if (!mapAddressBook[strAddress].empty()) | ||
| 514 | strDescription += mapAddressBook[strAddress] + " "; | ||
| 515 | strDescription += strAddress; | ||
| 516 | } | ||
| 517 | } | ||
| 518 | break; | ||
| 519 | } | ||
| 520 | } | ||
| 521 | } | ||
| 522 | |||
| 523 | string strDescription2; | ||
| 524 | foreach(int c, strDescription) | ||
| 525 | if (c >= ' ') | ||
| 526 | strDescription2 += c; | ||
| 527 | |||
| 528 | InsertLine(fNew, nIndex, hash, strSort, | ||
| 529 | strStatus, | ||
| 530 | nTime ? DateTimeStr(nTime) : "", | ||
| 531 | strDescription2, | ||
| 532 | "", | ||
| 533 | FormatMoney(nNet, true)); | ||
| 534 | } | ||
| 535 | else | ||
| 536 | { | ||
| 537 | bool fAllFromMe = true; | ||
| 538 | foreach(const CTxIn& txin, wtx.vin) | ||
| 539 | fAllFromMe = fAllFromMe && txin.IsMine(); | ||
| 540 | |||
| 541 | bool fAllToMe = true; | ||
| 542 | foreach(const CTxOut& txout, wtx.vout) | ||
| 543 | fAllToMe = fAllToMe && txout.IsMine(); | ||
| 544 | |||
| 545 | if (fAllFromMe && fAllToMe) | ||
| 546 | { | ||
| 547 | // Payment to self | ||
| 548 | int64 nValue = wtx.vout[0].nValue; | ||
| 549 | InsertLine(fNew, nIndex, hash, strSort, | ||
| 550 | strStatus, | ||
| 551 | nTime ? DateTimeStr(nTime) : "", | ||
| 552 | "Payment to yourself", | ||
| 553 | FormatMoney(nNet - nValue, true), | ||
| 554 | FormatMoney(nValue, true)); | ||
| 555 | } | ||
| 556 | else if (fAllFromMe) | ||
| 557 | { | ||
| 558 | // | ||
| 559 | // Debit | ||
| 560 | // | ||
| 561 | int64 nTxFee = nDebit - wtx.GetValueOut(); | ||
| 562 | for (int nOut = 0; nOut < wtx.vout.size(); nOut++) | ||
| 563 | { | ||
| 564 | const CTxOut& txout = wtx.vout[nOut]; | ||
| 565 | if (txout.IsMine()) | ||
| 566 | continue; | ||
| 567 | |||
| 568 | string strAddress; | ||
| 569 | if (!mapValue["to"].empty()) | ||
| 570 | { | ||
| 571 | // Online transaction | ||
| 572 | strAddress = mapValue["to"]; | ||
| 573 | } | ||
| 574 | else | ||
| 575 | { | ||
| 576 | // Offline transaction | ||
| 577 | uint160 hash160; | ||
| 578 | if (ExtractHash160(txout.scriptPubKey, hash160)) | ||
| 579 | strAddress = Hash160ToAddress(hash160); | ||
| 580 | } | ||
| 581 | |||
| 582 | string strDescription = "To: "; | ||
| 583 | if (mapAddressBook.count(strAddress) && !mapAddressBook[strAddress].empty()) | ||
| 584 | strDescription += mapAddressBook[strAddress] + " "; | ||
| 585 | strDescription += strAddress; | ||
| 586 | if (!mapValue["message"].empty()) | ||
| 587 | { | ||
| 588 | if (!strDescription.empty()) | ||
| 589 | strDescription += " - "; | ||
| 590 | strDescription += mapValue["message"]; | ||
| 591 | } | ||
| 592 | |||
| 593 | string strDescription2; | ||
| 594 | foreach(int c, strDescription) | ||
| 595 | if (c >= ' ') | ||
| 596 | strDescription2 += c; | ||
| 597 | |||
| 598 | int64 nValue = txout.nValue; | ||
| 599 | if (nOut == 0 && nTxFee > 0) | ||
| 600 | nValue += nTxFee; | ||
| 601 | |||
| 602 | InsertLine(fNew, nIndex, hash, strprintf("%s-%d", strSort.c_str(), nOut), | ||
| 603 | strStatus, | ||
| 604 | nTime ? DateTimeStr(nTime) : "", | ||
| 605 | strDescription2, | ||
| 606 | FormatMoney(-nValue, true), | ||
| 607 | ""); | ||
| 608 | } | ||
| 609 | } | ||
| 610 | else | ||
| 611 | { | ||
| 612 | // | ||
| 613 | // Mixed debit transaction, can't break down payees | ||
| 614 | // | ||
| 615 | bool fAllMine = true; | ||
| 616 | foreach(const CTxOut& txout, wtx.vout) | ||
| 617 | fAllMine = fAllMine && txout.IsMine(); | ||
| 618 | foreach(const CTxIn& txin, wtx.vin) | ||
| 619 | fAllMine = fAllMine && txin.IsMine(); | ||
| 620 | |||
| 621 | InsertLine(fNew, nIndex, hash, strSort, | ||
| 622 | strStatus, | ||
| 623 | nTime ? DateTimeStr(nTime) : "", | ||
| 624 | "", | ||
| 625 | FormatMoney(nNet, true), | ||
| 626 | ""); | ||
| 627 | } | ||
| 628 | } | ||
| 629 | } | ||
| 630 | |||
| 631 | void CMainFrame::RefreshStatus() | ||
| 632 | { | ||
| 633 | static int nLastTop; | ||
| 634 | int nTop = m_listCtrl->GetTopItem(); | ||
| 635 | if (nTop == nLastTop && pindexBestLast == pindexBest) | ||
| 636 | return; | ||
| 637 | |||
| 638 | TRY_CRITICAL_BLOCK(cs_mapWallet) | ||
| 639 | { | ||
| 640 | int nStart = nTop; | ||
| 641 | int nEnd = min(nStart + 100, m_listCtrl->GetItemCount()); | ||
| 642 | if (pindexBestLast == pindexBest) | ||
| 643 | { | ||
| 644 | if (nStart >= nLastTop && nStart < nLastTop + 100) | ||
| 645 | nStart = nLastTop + 100; | ||
| 646 | if (nEnd >= nLastTop && nEnd < nLastTop + 100) | ||
| 647 | nEnd = nLastTop; | ||
| 648 | } | ||
| 649 | nLastTop = nTop; | ||
| 650 | pindexBestLast = pindexBest; | ||
| 651 | |||
| 652 | for (int nIndex = nStart; nIndex < nEnd; nIndex++) | ||
| 653 | { | ||
| 654 | uint256 hash((string)GetItemText(m_listCtrl, nIndex, 1)); | ||
| 655 | map<uint256, CWalletTx>::iterator mi = mapWallet.find(hash); | ||
| 656 | if (mi == mapWallet.end()) | ||
| 657 | { | ||
| 658 | printf("CMainFrame::RefreshStatus() : tx not found in mapWallet\n"); | ||
| 659 | continue; | ||
| 660 | } | ||
| 661 | const CWalletTx& wtx = (*mi).second; | ||
| 662 | if (wtx.IsCoinBase() || wtx.GetTxTime() != wtx.nTimeDisplayed) | ||
| 663 | InsertTransaction(wtx, false, nIndex); | ||
| 664 | else | ||
| 665 | m_listCtrl->SetItem(nIndex, 2, FormatTxStatus(wtx)); | ||
| 666 | } | ||
| 667 | } | ||
| 668 | } | ||
| 669 | |||
| 670 | void CMainFrame::RefreshListCtrl() | ||
| 671 | { | ||
| 672 | fRefreshListCtrl = true; | ||
| 673 | ::wxWakeUpIdle(); | ||
| 674 | } | ||
| 675 | |||
| 676 | void CMainFrame::OnIdle(wxIdleEvent& event) | ||
| 677 | { | ||
| 678 | if (fRefreshListCtrl) | ||
| 679 | { | ||
| 680 | // Collect list of wallet transactions and sort newest first | ||
| 681 | bool fEntered = false; | ||
| 682 | vector<pair<unsigned int, uint256> > vSorted; | ||
| 683 | TRY_CRITICAL_BLOCK(cs_mapWallet) | ||
| 684 | { | ||
| 685 | printf("RefreshListCtrl starting\n"); | ||
| 686 | fEntered = true; | ||
| 687 | fRefreshListCtrl = false; | ||
| 688 | vWalletUpdated.clear(); | ||
| 689 | |||
| 690 | // Do the newest transactions first | ||
| 691 | vSorted.reserve(mapWallet.size()); | ||
| 692 | for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) | ||
| 693 | { | ||
| 694 | const CWalletTx& wtx = (*it).second; | ||
| 695 | unsigned int nTime = UINT_MAX - wtx.GetTxTime(); | ||
| 696 | vSorted.push_back(make_pair(nTime, (*it).first)); | ||
| 697 | } | ||
| 698 | m_listCtrl->DeleteAllItems(); | ||
| 699 | } | ||
| 700 | if (!fEntered) | ||
| 701 | return; | ||
| 702 | |||
| 703 | sort(vSorted.begin(), vSorted.end()); | ||
| 704 | |||
| 705 | // Fill list control | ||
| 706 | for (int i = 0; i < vSorted.size();) | ||
| 707 | { | ||
| 708 | if (fShutdown) | ||
| 709 | return; | ||
| 710 | bool fEntered = false; | ||
| 711 | TRY_CRITICAL_BLOCK(cs_mapWallet) | ||
| 712 | { | ||
| 713 | fEntered = true; | ||
| 714 | uint256& hash = vSorted[i++].second; | ||
| 715 | map<uint256, CWalletTx>::iterator mi = mapWallet.find(hash); | ||
| 716 | if (mi != mapWallet.end()) | ||
| 717 | InsertTransaction((*mi).second, true); | ||
| 718 | } | ||
| 719 | if (!fEntered || i == 100 || i % 500 == 0) | ||
| 720 | wxYield(); | ||
| 721 | } | ||
| 722 | |||
| 723 | printf("RefreshListCtrl done\n"); | ||
| 724 | } | ||
| 725 | else | ||
| 726 | { | ||
| 727 | // Check for time updates | ||
| 728 | static int64 nLastTime; | ||
| 729 | if (GetTime() > nLastTime + 30) | ||
| 730 | { | ||
| 731 | TRY_CRITICAL_BLOCK(cs_mapWallet) | ||
| 732 | { | ||
| 733 | nLastTime = GetTime(); | ||
| 734 | for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) | ||
| 735 | { | ||
| 736 | CWalletTx& wtx = (*it).second; | ||
| 737 | if (wtx.nTimeDisplayed && wtx.nTimeDisplayed != wtx.GetTxTime()) | ||
| 738 | InsertTransaction(wtx, false); | ||
| 739 | } | ||
| 740 | } | ||
| 741 | } | ||
| 742 | } | ||
| 743 | } | ||
| 744 | |||
| 745 | void CMainFrame::OnPaint(wxPaintEvent& event) | ||
| 746 | { | ||
| 747 | event.Skip(); | ||
| 748 | } | ||
| 749 | |||
| 750 | void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) | ||
| 751 | { | ||
| 752 | // Update listctrl contents | ||
| 753 | if (!vWalletUpdated.empty()) | ||
| 754 | { | ||
| 755 | TRY_CRITICAL_BLOCK(cs_mapWallet) | ||
| 756 | { | ||
| 757 | pair<uint256, bool> item; | ||
| 758 | foreach(item, vWalletUpdated) | ||
| 759 | { | ||
| 760 | bool fNew = item.second; | ||
| 761 | map<uint256, CWalletTx>::iterator mi = mapWallet.find(item.first); | ||
| 762 | if (mi != mapWallet.end()) | ||
| 763 | { | ||
| 764 | printf("vWalletUpdated: %s %s\n", (*mi).second.GetHash().ToString().substr(0,6).c_str(), fNew ? "new" : ""); | ||
| 765 | InsertTransaction((*mi).second, fNew); | ||
| 766 | } | ||
| 767 | } | ||
| 768 | m_listCtrl->ScrollList(0, INT_MAX); | ||
| 769 | vWalletUpdated.clear(); | ||
| 770 | } | ||
| 771 | } | ||
| 772 | |||
| 773 | // Update status column of visible items only | ||
| 774 | RefreshStatus(); | ||
| 775 | |||
| 776 | // Update status bar | ||
| 777 | string strGen = ""; | ||
| 778 | if (fGenerateBitcoins) | ||
| 779 | strGen = " Generating"; | ||
| 780 | if (fGenerateBitcoins && vNodes.empty()) | ||
| 781 | strGen = "(not connected)"; | ||
| 782 | m_statusBar->SetStatusText(strGen, 1); | ||
| 783 | |||
| 784 | string strStatus = strprintf(" %d connections %d blocks %d transactions", vNodes.size(), nBestHeight + 1, m_listCtrl->GetItemCount()); | ||
| 785 | m_statusBar->SetStatusText(strStatus, 2); | ||
| 786 | |||
| 787 | // Balance total | ||
| 788 | TRY_CRITICAL_BLOCK(cs_mapWallet) | ||
| 789 | m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " "); | ||
| 790 | |||
| 791 | m_listCtrl->OnPaint(event); | ||
| 792 | } | ||
| 793 | |||
| 794 | void CrossThreadCall(wxCommandEvent& event) | ||
| 795 | { | ||
| 796 | if (pframeMain) | ||
| 797 | pframeMain->GetEventHandler()->AddPendingEvent(event); | ||
| 798 | } | ||
| 799 | |||
| 800 | void CrossThreadCall(int nID, void* pdata) | ||
| 801 | { | ||
| 802 | wxCommandEvent event; | ||
| 803 | event.SetInt(nID); | ||
| 804 | event.SetClientData(pdata); | ||
| 805 | if (pframeMain) | ||
| 806 | pframeMain->GetEventHandler()->AddPendingEvent(event); | ||
| 807 | } | ||
| 808 | |||
| 809 | void CMainFrame::OnCrossThreadCall(wxCommandEvent& event) | ||
| 810 | { | ||
| 811 | void* pdata = event.GetClientData(); | ||
| 812 | switch (event.GetInt()) | ||
| 813 | { | ||
| 814 | case UICALL_ADDORDER: | ||
| 815 | { | ||
| 816 | break; | ||
| 817 | } | ||
| 818 | |||
| 819 | case UICALL_UPDATEORDER: | ||
| 820 | { | ||
| 821 | break; | ||
| 822 | } | ||
| 823 | } | ||
| 824 | } | ||
| 825 | |||
| 826 | void CMainFrame::OnMenuFileExit(wxCommandEvent& event) | ||
| 827 | { | ||
| 828 | Close(true); | ||
| 829 | } | ||
| 830 | |||
| 831 | void CMainFrame::OnMenuOptionsGenerate(wxCommandEvent& event) | ||
| 832 | { | ||
| 833 | fGenerateBitcoins = event.IsChecked(); | ||
| 834 | nTransactionsUpdated++; | ||
| 835 | CWalletDB().WriteSetting("fGenerateBitcoins", fGenerateBitcoins); | ||
| 836 | |||
| 837 | if (fGenerateBitcoins) | ||
| 838 | if (_beginthread(ThreadBitcoinMiner, 0, NULL) == -1) | ||
| 839 | printf("Error: _beginthread(ThreadBitcoinMiner) failed\n"); | ||
| 840 | |||
| 841 | Refresh(); | ||
| 842 | Update(); | ||
| 843 | } | ||
| 844 | |||
| 845 | void CMainFrame::OnMenuOptionsOptions(wxCommandEvent& event) | ||
| 846 | { | ||
| 847 | COptionsDialog dialog(this); | ||
| 848 | dialog.ShowModal(); | ||
| 849 | } | ||
| 850 | |||
| 851 | void CMainFrame::OnMenuHelpAbout(wxCommandEvent& event) | ||
| 852 | { | ||
| 853 | CAboutDialog dialog(this); | ||
| 854 | dialog.ShowModal(); | ||
| 855 | } | ||
| 856 | |||
| 857 | void CMainFrame::OnButtonSend(wxCommandEvent& event) | ||
| 858 | { | ||
| 859 | /// debug test | ||
| 860 | if (fRandSendTest) | ||
| 861 | { | ||
| 862 | RandSend(); | ||
| 863 | return; | ||
| 864 | } | ||
| 865 | |||
| 866 | // Toolbar: Send | ||
| 867 | CSendDialog dialog(this); | ||
| 868 | dialog.ShowModal(); | ||
| 869 | } | ||
| 870 | |||
| 871 | void CMainFrame::OnButtonAddressBook(wxCommandEvent& event) | ||
| 872 | { | ||
| 873 | // Toolbar: Address Book | ||
| 874 | CAddressBookDialog dialogAddr(this, "", false); | ||
| 875 | if (dialogAddr.ShowModal() == 2) | ||
| 876 | { | ||
| 877 | // Send | ||
| 878 | CSendDialog dialogSend(this, dialogAddr.GetAddress()); | ||
| 879 | dialogSend.ShowModal(); | ||
| 880 | } | ||
| 881 | } | ||
| 882 | |||
| 883 | void CMainFrame::OnSetFocusAddress(wxFocusEvent& event) | ||
| 884 | { | ||
| 885 | // Automatically select-all when entering window | ||
| 886 | m_textCtrlAddress->SetSelection(-1, -1); | ||
| 887 | fOnSetFocusAddress = true; | ||
| 888 | event.Skip(); | ||
| 889 | } | ||
| 890 | |||
| 891 | void CMainFrame::OnMouseEventsAddress(wxMouseEvent& event) | ||
| 892 | { | ||
| 893 | if (fOnSetFocusAddress) | ||
| 894 | m_textCtrlAddress->SetSelection(-1, -1); | ||
| 895 | fOnSetFocusAddress = false; | ||
| 896 | event.Skip(); | ||
| 897 | } | ||
| 898 | |||
| 899 | void CMainFrame::OnButtonCopy(wxCommandEvent& event) | ||
| 900 | { | ||
| 901 | // Copy address box to clipboard | ||
| 902 | if (wxTheClipboard->Open()) | ||
| 903 | { | ||
| 904 | wxTheClipboard->SetData(new wxTextDataObject(m_textCtrlAddress->GetValue())); | ||
| 905 | wxTheClipboard->Close(); | ||
| 906 | } | ||
| 907 | } | ||
| 908 | |||
| 909 | void CMainFrame::OnButtonChange(wxCommandEvent& event) | ||
| 910 | { | ||
| 911 | CYourAddressDialog dialog(this, string(m_textCtrlAddress->GetValue())); | ||
| 912 | if (!dialog.ShowModal()) | ||
| 913 | return; | ||
| 914 | string strAddress = (string)dialog.GetAddress(); | ||
| 915 | if (strAddress != m_textCtrlAddress->GetValue()) | ||
| 916 | { | ||
| 917 | uint160 hash160; | ||
| 918 | if (!AddressToHash160(strAddress, hash160)) | ||
| 919 | return; | ||
| 920 | if (!mapPubKeys.count(hash160)) | ||
| 921 | return; | ||
| 922 | CWalletDB().WriteDefaultKey(mapPubKeys[hash160]); | ||
| 923 | m_textCtrlAddress->SetValue(strAddress); | ||
| 924 | } | ||
| 925 | } | ||
| 926 | |||
| 927 | void CMainFrame::OnListItemActivatedAllTransactions(wxListEvent& event) | ||
| 928 | { | ||
| 929 | uint256 hash((string)GetItemText(m_listCtrl, event.GetIndex(), 1)); | ||
| 930 | CWalletTx wtx; | ||
| 931 | CRITICAL_BLOCK(cs_mapWallet) | ||
| 932 | { | ||
| 933 | map<uint256, CWalletTx>::iterator mi = mapWallet.find(hash); | ||
| 934 | if (mi == mapWallet.end()) | ||
| 935 | { | ||
| 936 | printf("CMainFrame::OnListItemActivatedAllTransactions() : tx not found in mapWallet\n"); | ||
| 937 | return; | ||
| 938 | } | ||
| 939 | wtx = (*mi).second; | ||
| 940 | } | ||
| 941 | CTxDetailsDialog dialog(this, wtx); | ||
| 942 | dialog.ShowModal(); | ||
| 943 | //CTxDetailsDialog* pdialog = new CTxDetailsDialog(this, wtx); | ||
| 944 | //pdialog->Show(); | ||
| 945 | } | ||
| 946 | |||
| 947 | void CMainFrame::OnListItemActivatedProductsSent(wxListEvent& event) | ||
| 948 | { | ||
| 949 | CProduct& product = *(CProduct*)event.GetItem().GetData(); | ||
| 950 | CEditProductDialog* pdialog = new CEditProductDialog(this); | ||
| 951 | pdialog->SetProduct(product); | ||
| 952 | pdialog->Show(); | ||
| 953 | } | ||
| 954 | |||
| 955 | void CMainFrame::OnListItemActivatedOrdersSent(wxListEvent& event) | ||
| 956 | { | ||
| 957 | CWalletTx& order = *(CWalletTx*)event.GetItem().GetData(); | ||
| 958 | CViewOrderDialog* pdialog = new CViewOrderDialog(this, order, false); | ||
| 959 | pdialog->Show(); | ||
| 960 | } | ||
| 961 | |||
| 962 | void CMainFrame::OnListItemActivatedOrdersReceived(wxListEvent& event) | ||
| 963 | { | ||
| 964 | CWalletTx& order = *(CWalletTx*)event.GetItem().GetData(); | ||
| 965 | CViewOrderDialog* pdialog = new CViewOrderDialog(this, order, true); | ||
| 966 | pdialog->Show(); | ||
| 967 | } | ||
| 968 | |||
| 969 | |||
| 970 | |||
| 971 | |||
| 972 | |||
| 973 | |||
| 974 | |||
| 975 | ////////////////////////////////////////////////////////////////////////////// | ||
| 976 | // | ||
| 977 | // CTxDetailsDialog | ||
| 978 | // | ||
| 979 | |||
| 980 | CTxDetailsDialog::CTxDetailsDialog(wxWindow* parent, CWalletTx wtx) : CTxDetailsDialogBase(parent) | ||
| 981 | { | ||
| 982 | string strHTML; | ||
| 983 | strHTML.reserve(4000); | ||
| 984 | |||
| 985 | int64 nTime = wtx.GetTxTime(); | ||
| 986 | int64 nCredit = wtx.GetCredit(); | ||
| 987 | int64 nDebit = wtx.GetDebit(); | ||
| 988 | int64 nNet = nCredit - nDebit; | ||
| 989 | |||
| 990 | |||
| 991 | |||
| 992 | |||
| 993 | strHTML += "<b>Status:</b> " + FormatTxStatus(wtx) + "<br>"; | ||
| 994 | strHTML += "<b>Date:</b> " + (nTime ? DateTimeStr(nTime) : "") + "<br>"; | ||
| 995 | |||
| 996 | |||
| 997 | // | ||
| 998 | // From | ||
| 999 | // | ||
| 1000 | if (wtx.IsCoinBase()) | ||
| 1001 | { | ||
| 1002 | strHTML += "<b>Source:</b> Generated<br>"; | ||
| 1003 | } | ||
| 1004 | else if (!wtx.mapValue["from"].empty()) | ||
| 1005 | { | ||
| 1006 | // Online transaction | ||
| 1007 | if (!wtx.mapValue["from"].empty()) | ||
| 1008 | strHTML += "<b>From:</b> " + HtmlEscape(wtx.mapValue["from"]) + "<br>"; | ||
| 1009 | } | ||
| 1010 | else | ||
| 1011 | { | ||
| 1012 | // Offline transaction | ||
| 1013 | foreach(const CTxOut& txout, wtx.vout) | ||
| 1014 | { | ||
| 1015 | if (txout.IsMine()) | ||
| 1016 | { | ||
| 1017 | vector<unsigned char> vchPubKey; | ||
| 1018 | if (ExtractPubKey(txout.scriptPubKey, true, vchPubKey)) | ||
| 1019 | { | ||
| 1020 | string strAddress = PubKeyToAddress(vchPubKey); | ||
| 1021 | if (mapAddressBook.count(strAddress)) | ||
| 1022 | { | ||
| 1023 | strHTML += "<b>Received with:</b> "; | ||
| 1024 | if (!mapAddressBook[strAddress].empty()) | ||
| 1025 | strHTML += mapAddressBook[strAddress] + " "; | ||
| 1026 | strHTML += HtmlEscape(strAddress); | ||
| 1027 | strHTML += "<br>"; | ||
| 1028 | } | ||
| 1029 | } | ||
| 1030 | break; | ||
| 1031 | } | ||
| 1032 | } | ||
| 1033 | } | ||
| 1034 | |||
| 1035 | |||
| 1036 | // | ||
| 1037 | // To | ||
| 1038 | // | ||
| 1039 | string strAddress; | ||
| 1040 | if (!wtx.mapValue["to"].empty()) | ||
| 1041 | { | ||
| 1042 | // Online transaction | ||
| 1043 | strAddress = wtx.mapValue["to"]; | ||
| 1044 | strHTML += "<b>To:</b> "; | ||
| 1045 | if (mapAddressBook.count(strAddress) && !mapAddressBook[strAddress].empty()) | ||
| 1046 | strHTML += mapAddressBook[strAddress] + " "; | ||
| 1047 | strHTML += HtmlEscape(strAddress) + "<br>"; | ||
| 1048 | } | ||
| 1049 | |||
| 1050 | |||
| 1051 | // | ||
| 1052 | // Amount | ||
| 1053 | // | ||
| 1054 | if (wtx.IsCoinBase() && nCredit == 0) | ||
| 1055 | { | ||
| 1056 | // | ||
| 1057 | // Coinbase | ||
| 1058 | // | ||
| 1059 | int64 nUnmatured = 0; | ||
| 1060 | foreach(const CTxOut& txout, wtx.vout) | ||
| 1061 | nUnmatured += txout.GetCredit(); | ||
| 1062 | if (wtx.IsInMainChain()) | ||
| 1063 | strHTML += strprintf("<b>Credit:</b> (%s matures in %d blocks)<br>", FormatMoney(nUnmatured).c_str(), wtx.GetBlocksToMaturity()); | ||
| 1064 | else | ||
| 1065 | strHTML += "<b>Credit:</b> (not accepted)<br>"; | ||
| 1066 | } | ||
| 1067 | else if (nNet > 0) | ||
| 1068 | { | ||
| 1069 | // | ||
| 1070 | // Credit | ||
| 1071 | // | ||
| 1072 | strHTML += "<b>Credit:</b> " + FormatMoney(nNet) + "<br>"; | ||
| 1073 | } | ||
| 1074 | else | ||
| 1075 | { | ||
| 1076 | bool fAllFromMe = true; | ||
| 1077 | foreach(const CTxIn& txin, wtx.vin) | ||
| 1078 | fAllFromMe = fAllFromMe && txin.IsMine(); | ||
| 1079 | |||
| 1080 | bool fAllToMe = true; | ||
| 1081 | foreach(const CTxOut& txout, wtx.vout) | ||
| 1082 | fAllToMe = fAllToMe && txout.IsMine(); | ||
| 1083 | |||
| 1084 | if (fAllFromMe) | ||
| 1085 | { | ||
| 1086 | // | ||
| 1087 | // Debit | ||
| 1088 | // | ||
| 1089 | foreach(const CTxOut& txout, wtx.vout) | ||
| 1090 | { | ||
| 1091 | if (txout.IsMine()) | ||
| 1092 | continue; | ||
| 1093 | |||
| 1094 | string strAddress; | ||
| 1095 | if (!wtx.mapValue["to"].empty()) | ||
| 1096 | { | ||
| 1097 | // Online transaction | ||
| 1098 | strAddress = wtx.mapValue["to"]; | ||
| 1099 | } | ||
| 1100 | else | ||
| 1101 | { | ||
| 1102 | // Offline transaction | ||
| 1103 | uint160 hash160; | ||
| 1104 | if (ExtractHash160(txout.scriptPubKey, hash160)) | ||
| 1105 | strAddress = Hash160ToAddress(hash160); | ||
| 1106 | } | ||
| 1107 | |||
| 1108 | strHTML += "<b>Debit:</b> " + FormatMoney(-txout.nValue) + " "; | ||
| 1109 | strHTML += "(to "; | ||
| 1110 | if (mapAddressBook.count(strAddress) && !mapAddressBook[strAddress].empty()) | ||
| 1111 | strHTML += mapAddressBook[strAddress] + " "; | ||
| 1112 | strHTML += strAddress; | ||
| 1113 | strHTML += ")<br>"; | ||
| 1114 | } | ||
| 1115 | |||
| 1116 | if (fAllToMe) | ||
| 1117 | { | ||
| 1118 | // Payment to self | ||
| 1119 | int64 nValue = wtx.vout[0].nValue; | ||
| 1120 | strHTML += "<b>Debit:</b> " + FormatMoney(-nValue) + "<br>"; | ||
| 1121 | strHTML += "<b>Credit:</b> " + FormatMoney(nValue) + "<br>"; | ||
| 1122 | } | ||
| 1123 | |||
| 1124 | int64 nTxFee = nDebit - wtx.GetValueOut(); | ||
| 1125 | if (nTxFee > 0) | ||
| 1126 | strHTML += "<b>Transaction fee:</b> " + FormatMoney(-nTxFee) + "<br>"; | ||
| 1127 | } | ||
| 1128 | else | ||
| 1129 | { | ||
| 1130 | // | ||
| 1131 | // Mixed debit transaction | ||
| 1132 | // | ||
| 1133 | foreach(const CTxIn& txin, wtx.vin) | ||
| 1134 | if (txin.IsMine()) | ||
| 1135 | strHTML += "<b>Debit:</b> " + FormatMoney(-txin.GetDebit()) + "<br>"; | ||
| 1136 | foreach(const CTxOut& txout, wtx.vout) | ||
| 1137 | if (txout.IsMine()) | ||
| 1138 | strHTML += "<b>Credit:</b> " + FormatMoney(txout.GetCredit()) + "<br>"; | ||
| 1139 | } | ||
| 1140 | } | ||
| 1141 | |||
| 1142 | strHTML += "<b>Net amount:</b> " + FormatMoney(nNet, true) + "<br>"; | ||
| 1143 | |||
| 1144 | |||
| 1145 | // | ||
| 1146 | // Message | ||
| 1147 | // | ||
| 1148 | if (!wtx.mapValue["message"].empty()) | ||
| 1149 | strHTML += "<br><b>Message:</b><br>" + HtmlEscape(wtx.mapValue["message"], true) + "<br>"; | ||
| 1150 | |||
| 1151 | |||
| 1152 | // | ||
| 1153 | // Debug view | ||
| 1154 | // | ||
| 1155 | if (fDebug) | ||
| 1156 | { | ||
| 1157 | strHTML += "<hr><br>debug print<br><br>"; | ||
| 1158 | foreach(const CTxIn& txin, wtx.vin) | ||
| 1159 | if (txin.IsMine()) | ||
| 1160 | strHTML += "<b>Debit:</b> " + FormatMoney(-txin.GetDebit()) + "<br>"; | ||
| 1161 | foreach(const CTxOut& txout, wtx.vout) | ||
| 1162 | if (txout.IsMine()) | ||
| 1163 | strHTML += "<b>Credit:</b> " + FormatMoney(txout.GetCredit()) + "<br>"; | ||
| 1164 | |||
| 1165 | strHTML += "<b>Inputs:</b><br>"; | ||
| 1166 | CRITICAL_BLOCK(cs_mapWallet) | ||
| 1167 | { | ||
| 1168 | foreach(const CTxIn& txin, wtx.vin) | ||
| 1169 | { | ||
| 1170 | COutPoint prevout = txin.prevout; | ||
| 1171 | map<uint256, CWalletTx>::iterator mi = mapWallet.find(prevout.hash); | ||
| 1172 | if (mi != mapWallet.end()) | ||
| 1173 | { | ||
| 1174 | const CWalletTx& prev = (*mi).second; | ||
| 1175 | if (prevout.n < prev.vout.size()) | ||
| 1176 | { | ||
| 1177 | strHTML += HtmlEscape(prev.ToString(), true); | ||
| 1178 | strHTML += " " + FormatTxStatus(prev) + ", "; | ||
| 1179 | strHTML = strHTML + "IsMine=" + (prev.vout[prevout.n].IsMine() ? "true" : "false") + "<br>"; | ||
| 1180 | } | ||
| 1181 | } | ||
| 1182 | } | ||
| 1183 | } | ||
| 1184 | |||
| 1185 | strHTML += "<br><hr><br><b>Transaction:</b><br>"; | ||
| 1186 | strHTML += HtmlEscape(wtx.ToString(), true); | ||
| 1187 | } | ||
| 1188 | |||
| 1189 | |||
| 1190 | string(strHTML.begin(), strHTML.end()).swap(strHTML); | ||
| 1191 | m_htmlWin->SetPage(strHTML); | ||
| 1192 | m_buttonOK->SetFocus(); | ||
| 1193 | } | ||
| 1194 | |||
| 1195 | void CTxDetailsDialog::OnButtonOK(wxCommandEvent& event) | ||
| 1196 | { | ||
| 1197 | EndModal(true); // wx3: modal dialogs must EndModal, not Close() | ||
| 1198 | //Destroy(); | ||
| 1199 | } | ||
| 1200 | |||
| 1201 | |||
| 1202 | |||
| 1203 | |||
| 1204 | |||
| 1205 | ////////////////////////////////////////////////////////////////////////////// | ||
| 1206 | // | ||
| 1207 | // COptionsDialog | ||
| 1208 | // | ||
| 1209 | |||
| 1210 | COptionsDialog::COptionsDialog(wxWindow* parent) : COptionsDialogBase(parent) | ||
| 1211 | { | ||
| 1212 | m_textCtrlTransactionFee->SetValue(FormatMoney(nTransactionFee)); | ||
| 1213 | m_buttonOK->SetFocus(); | ||
| 1214 | } | ||
| 1215 | |||
| 1216 | void COptionsDialog::OnKillFocusTransactionFee(wxFocusEvent& event) | ||
| 1217 | { | ||
| 1218 | int64 nTmp = nTransactionFee; | ||
| 1219 | ParseMoney(m_textCtrlTransactionFee->GetValue(), nTmp); | ||
| 1220 | m_textCtrlTransactionFee->SetValue(FormatMoney(nTmp)); | ||
| 1221 | } | ||
| 1222 | |||
| 1223 | void COptionsDialog::OnButtonOK(wxCommandEvent& event) | ||
| 1224 | { | ||
| 1225 | // nTransactionFee | ||
| 1226 | int64 nPrevTransactionFee = nTransactionFee; | ||
| 1227 | if (ParseMoney(m_textCtrlTransactionFee->GetValue(), nTransactionFee) && nTransactionFee != nPrevTransactionFee) | ||
| 1228 | CWalletDB().WriteSetting("nTransactionFee", nTransactionFee); | ||
| 1229 | |||
| 1230 | EndModal(true); // wx3: modal dialogs must EndModal, not Close() | ||
| 1231 | } | ||
| 1232 | |||
| 1233 | void COptionsDialog::OnButtonCancel(wxCommandEvent& event) | ||
| 1234 | { | ||
| 1235 | EndModal(false); // wx3: modal dialogs must EndModal, not Close() | ||
| 1236 | } | ||
| 1237 | |||
| 1238 | |||
| 1239 | |||
| 1240 | |||
| 1241 | |||
| 1242 | |||
| 1243 | ////////////////////////////////////////////////////////////////////////////// | ||
| 1244 | // | ||
| 1245 | // CAboutDialog | ||
| 1246 | // | ||
| 1247 | |||
| 1248 | CAboutDialog::CAboutDialog(wxWindow* parent) : CAboutDialogBase(parent) | ||
| 1249 | { | ||
| 1250 | m_staticTextVersion->SetLabel(strprintf("version 0.%d.%d Alpha", VERSION/100, VERSION%100)); | ||
| 1251 | |||
| 1252 | // (wx3 is natively Unicode; the wx2.8 UTF-8 workaround is no longer needed) | ||
| 1253 | } | ||
| 1254 | |||
| 1255 | void CAboutDialog::OnButtonOK(wxCommandEvent& event) | ||
| 1256 | { | ||
| 1257 | EndModal(true); // wx3: modal dialogs must EndModal, not Close() | ||
| 1258 | } | ||
| 1259 | |||
| 1260 | |||
| 1261 | |||
| 1262 | |||
| 1263 | |||
| 1264 | |||
| 1265 | ////////////////////////////////////////////////////////////////////////////// | ||
| 1266 | // | ||
| 1267 | // CSendDialog | ||
| 1268 | // | ||
| 1269 | |||
| 1270 | CSendDialog::CSendDialog(wxWindow* parent, const wxString& strAddress) : CSendDialogBase(parent) | ||
| 1271 | { | ||
| 1272 | // Init | ||
| 1273 | m_textCtrlAddress->SetValue(strAddress); | ||
| 1274 | m_choiceTransferType->SetSelection(0); | ||
| 1275 | m_bitmapCheckMark->Show(false); | ||
| 1276 | //// todo: should add a display of your balance for convenience | ||
| 1277 | |||
| 1278 | // Set Icon | ||
| 1279 | wxBitmap bmpSend(wxT("send16"), wxBITMAP_TYPE_RESOURCE); | ||
| 1280 | bmpSend.SetMask(new wxMask(wxBitmap(wxT("send16masknoshadow"), wxBITMAP_TYPE_RESOURCE))); | ||
| 1281 | wxIcon iconSend; | ||
| 1282 | iconSend.CopyFromBitmap(bmpSend); | ||
| 1283 | SetIcon(iconSend); | ||
| 1284 | |||
| 1285 | wxCommandEvent event; | ||
| 1286 | OnTextAddress(event); | ||
| 1287 | |||
| 1288 | // Fixup the tab order | ||
| 1289 | m_buttonPaste->MoveAfterInTabOrder(m_buttonCancel); | ||
| 1290 | m_buttonAddress->MoveAfterInTabOrder(m_buttonPaste); | ||
| 1291 | this->Layout(); | ||
| 1292 | } | ||
| 1293 | |||
| 1294 | void CSendDialog::OnTextAddress(wxCommandEvent& event) | ||
| 1295 | { | ||
| 1296 | // Check mark | ||
| 1297 | bool fBitcoinAddress = IsValidBitcoinAddress(m_textCtrlAddress->GetValue()); | ||
| 1298 | m_bitmapCheckMark->Show(fBitcoinAddress); | ||
| 1299 | |||
| 1300 | // Grey out message if bitcoin address | ||
| 1301 | bool fEnable = !fBitcoinAddress; | ||
| 1302 | m_staticTextFrom->Enable(fEnable); | ||
| 1303 | m_textCtrlFrom->Enable(fEnable); | ||
| 1304 | m_staticTextMessage->Enable(fEnable); | ||
| 1305 | m_textCtrlMessage->Enable(fEnable); | ||
| 1306 | m_textCtrlMessage->SetBackgroundColour(wxSystemSettings::GetColour(fEnable ? wxSYS_COLOUR_WINDOW : wxSYS_COLOUR_BTNFACE)); | ||
| 1307 | } | ||
| 1308 | |||
| 1309 | void CSendDialog::OnKillFocusAmount(wxFocusEvent& event) | ||
| 1310 | { | ||
| 1311 | // Reformat the amount | ||
| 1312 | if (m_textCtrlAmount->GetValue().Trim().empty()) | ||
| 1313 | return; | ||
| 1314 | int64 nTmp; | ||
| 1315 | if (ParseMoney(m_textCtrlAmount->GetValue(), nTmp)) | ||
| 1316 | m_textCtrlAmount->SetValue(FormatMoney(nTmp)); | ||
| 1317 | } | ||
| 1318 | |||
| 1319 | void CSendDialog::OnButtonAddressBook(wxCommandEvent& event) | ||
| 1320 | { | ||
| 1321 | // Open address book | ||
| 1322 | CAddressBookDialog dialog(this, m_textCtrlAddress->GetValue(), true); | ||
| 1323 | if (dialog.ShowModal()) | ||
| 1324 | m_textCtrlAddress->SetValue(dialog.GetAddress()); | ||
| 1325 | } | ||
| 1326 | |||
| 1327 | void CSendDialog::OnButtonPaste(wxCommandEvent& event) | ||
| 1328 | { | ||
| 1329 | // Copy clipboard to address box | ||
| 1330 | if (wxTheClipboard->Open()) | ||
| 1331 | { | ||
| 1332 | if (wxTheClipboard->IsSupported(wxDF_TEXT)) | ||
| 1333 | { | ||
| 1334 | wxTextDataObject data; | ||
| 1335 | wxTheClipboard->GetData(data); | ||
| 1336 | m_textCtrlAddress->SetValue(data.GetText()); | ||
| 1337 | } | ||
| 1338 | wxTheClipboard->Close(); | ||
| 1339 | } | ||
| 1340 | } | ||
| 1341 | |||
| 1342 | void CSendDialog::OnButtonSend(wxCommandEvent& event) | ||
| 1343 | { | ||
| 1344 | CWalletTx wtx; | ||
| 1345 | string strAddress = (string)m_textCtrlAddress->GetValue(); | ||
| 1346 | |||
| 1347 | // Parse amount | ||
| 1348 | int64 nValue = 0; | ||
| 1349 | if (!ParseMoney(m_textCtrlAmount->GetValue(), nValue) || nValue <= 0) | ||
| 1350 | { | ||
| 1351 | wxMessageBox("Error in amount "); | ||
| 1352 | return; | ||
| 1353 | } | ||
| 1354 | if (nValue > GetBalance()) | ||
| 1355 | { | ||
| 1356 | wxMessageBox("Amount exceeds your balance "); | ||
| 1357 | return; | ||
| 1358 | } | ||
| 1359 | if (nValue + nTransactionFee > GetBalance()) | ||
| 1360 | { | ||
| 1361 | wxMessageBox(string("Total exceeds your balance when the ") + FormatMoney(nTransactionFee) + " transaction fee is included "); | ||
| 1362 | return; | ||
| 1363 | } | ||
| 1364 | |||
| 1365 | // Parse bitcoin address | ||
| 1366 | uint160 hash160; | ||
| 1367 | bool fBitcoinAddress = AddressToHash160(strAddress, hash160); | ||
| 1368 | |||
| 1369 | if (fBitcoinAddress) | ||
| 1370 | { | ||
| 1371 | // Send to bitcoin address | ||
| 1372 | CScript scriptPubKey; | ||
| 1373 | scriptPubKey << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG; | ||
| 1374 | |||
| 1375 | if (!SendMoney(scriptPubKey, nValue, wtx)) | ||
| 1376 | return; | ||
| 1377 | |||
| 1378 | wxMessageBox("Payment sent ", "Sending..."); | ||
| 1379 | } | ||
| 1380 | else | ||
| 1381 | { | ||
| 1382 | // Parse IP address | ||
| 1383 | CAddress addr(strAddress.c_str()); | ||
| 1384 | if (addr.ip == 0) | ||
| 1385 | { | ||
| 1386 | wxMessageBox("Invalid address "); | ||
| 1387 | return; | ||
| 1388 | } | ||
| 1389 | |||
| 1390 | // Message | ||
| 1391 | wtx.mapValue["to"] = strAddress; | ||
| 1392 | wtx.mapValue["from"] = m_textCtrlFrom->GetValue(); | ||
| 1393 | wtx.mapValue["message"] = m_textCtrlMessage->GetValue(); | ||
| 1394 | |||
| 1395 | // Send to IP address | ||
| 1396 | CSendingDialog* pdialog = new CSendingDialog(this, addr, nValue, wtx); | ||
| 1397 | if (!pdialog->ShowModal()) | ||
| 1398 | return; | ||
| 1399 | } | ||
| 1400 | |||
| 1401 | if (!mapAddressBook.count(strAddress)) | ||
| 1402 | SetAddressBookName(strAddress, ""); | ||
| 1403 | |||
| 1404 | EndModal(true); | ||
| 1405 | } | ||
| 1406 | |||
| 1407 | void CSendDialog::OnButtonCancel(wxCommandEvent& event) | ||
| 1408 | { | ||
| 1409 | // Cancel | ||
| 1410 | EndModal(false); | ||
| 1411 | } | ||
| 1412 | |||
| 1413 | |||
| 1414 | |||
| 1415 | |||
| 1416 | |||
| 1417 | |||
| 1418 | ////////////////////////////////////////////////////////////////////////////// | ||
| 1419 | // | ||
| 1420 | // CSendingDialog | ||
| 1421 | // | ||
| 1422 | |||
| 1423 | CSendingDialog::CSendingDialog(wxWindow* parent, const CAddress& addrIn, int64 nPriceIn, const CWalletTx& wtxIn) : CSendingDialogBase(NULL) // we have to give null so parent can't destroy us | ||
| 1424 | { | ||
| 1425 | addr = addrIn; | ||
| 1426 | nPrice = nPriceIn; | ||
| 1427 | wtx = wtxIn; | ||
| 1428 | start = wxDateTime::UNow(); | ||
| 1429 | strStatus = ""; | ||
| 1430 | fCanCancel = true; | ||
| 1431 | fAbort = false; | ||
| 1432 | fSuccess = false; | ||
| 1433 | fUIDone = false; | ||
| 1434 | fWorkDone = false; | ||
| 1435 | |||
| 1436 | SetTitle(strprintf("Sending %s to %s...", FormatMoney(nPrice).c_str(), wtx.mapValue["to"].c_str())); | ||
| 1437 | m_textCtrlStatus->SetValue(""); | ||
| 1438 | |||
| 1439 | _beginthread(SendingDialogStartTransfer, 0, this); | ||
| 1440 | } | ||
| 1441 | |||
| 1442 | CSendingDialog::~CSendingDialog() | ||
| 1443 | { | ||
| 1444 | printf("~CSendingDialog()\n"); | ||
| 1445 | } | ||
| 1446 | |||
| 1447 | void CSendingDialog::Close() | ||
| 1448 | { | ||
| 1449 | // Last one out turn out the lights. | ||
| 1450 | // fWorkDone signals that work side is done and UI thread should call destroy. | ||
| 1451 | // fUIDone signals that UI window has closed and work thread should call destroy. | ||
| 1452 | // This allows the window to disappear and end modality when cancelled | ||
| 1453 | // without making the user wait for ConnectNode to return. The dialog object | ||
| 1454 | // hangs around in the background until the work thread exits. | ||
| 1455 | if (IsModal()) | ||
| 1456 | EndModal(fSuccess); | ||
| 1457 | else | ||
| 1458 | Show(false); | ||
| 1459 | if (fWorkDone) | ||
| 1460 | Destroy(); | ||
| 1461 | else | ||
| 1462 | fUIDone = true; | ||
| 1463 | } | ||
| 1464 | |||
| 1465 | void CSendingDialog::OnClose(wxCloseEvent& event) | ||
| 1466 | { | ||
| 1467 | if (!event.CanVeto() || fWorkDone || fAbort || !fCanCancel) | ||
| 1468 | { | ||
| 1469 | Close(); | ||
| 1470 | } | ||
| 1471 | else | ||
| 1472 | { | ||
| 1473 | event.Veto(); | ||
| 1474 | wxCommandEvent cmdevent; | ||
| 1475 | OnButtonCancel(cmdevent); | ||
| 1476 | } | ||
| 1477 | } | ||
| 1478 | |||
| 1479 | void CSendingDialog::OnButtonOK(wxCommandEvent& event) | ||
| 1480 | { | ||
| 1481 | if (fWorkDone) | ||
| 1482 | Close(); | ||
| 1483 | } | ||
| 1484 | |||
| 1485 | void CSendingDialog::OnButtonCancel(wxCommandEvent& event) | ||
| 1486 | { | ||
| 1487 | if (fCanCancel) | ||
| 1488 | fAbort = true; | ||
| 1489 | } | ||
| 1490 | |||
| 1491 | void CSendingDialog::OnPaint(wxPaintEvent& event) | ||
| 1492 | { | ||
| 1493 | if (strStatus.size() > 130) | ||
| 1494 | m_textCtrlStatus->SetValue(string("\n") + strStatus); | ||
| 1495 | else | ||
| 1496 | m_textCtrlStatus->SetValue(string("\n\n") + strStatus); | ||
| 1497 | m_staticTextSending->SetFocus(); | ||
| 1498 | if (!fCanCancel) | ||
| 1499 | m_buttonCancel->Enable(false); | ||
| 1500 | if (fWorkDone) | ||
| 1501 | { | ||
| 1502 | m_buttonOK->Enable(true); | ||
| 1503 | m_buttonOK->SetFocus(); | ||
| 1504 | m_buttonCancel->Enable(false); | ||
| 1505 | } | ||
| 1506 | if (fAbort && fCanCancel && IsShown()) | ||
| 1507 | { | ||
| 1508 | strStatus = "CANCELLED"; | ||
| 1509 | m_buttonOK->Enable(true); | ||
| 1510 | m_buttonOK->SetFocus(); | ||
| 1511 | m_buttonCancel->Enable(false); | ||
| 1512 | m_buttonCancel->SetLabel("Cancelled"); | ||
| 1513 | Close(); | ||
| 1514 | wxMessageBox("Transfer cancelled ", "Sending...", wxOK, this); | ||
| 1515 | } | ||
| 1516 | event.Skip(); | ||
| 1517 | |||
| 1518 | /// debug test | ||
| 1519 | if (fRandSendTest && fWorkDone && fSuccess) | ||
| 1520 | { | ||
| 1521 | Close(); | ||
| 1522 | Sleep(1000); | ||
| 1523 | RandSend(); | ||
| 1524 | } | ||
| 1525 | } | ||
| 1526 | |||
| 1527 | |||
| 1528 | // | ||
| 1529 | // Everything from here on is not in the UI thread and must only communicate | ||
| 1530 | // with the rest of the dialog through variables and calling repaint. | ||
| 1531 | // | ||
| 1532 | |||
| 1533 | void CSendingDialog::Repaint() | ||
| 1534 | { | ||
| 1535 | // Called from worker threads: repaint only on the GUI thread | ||
| 1536 | if (wxTheApp) | ||
| 1537 | wxTheApp->CallAfter([this] { Refresh(); }); | ||
| 1538 | } | ||
| 1539 | |||
| 1540 | bool CSendingDialog::Status() | ||
| 1541 | { | ||
| 1542 | if (fUIDone) | ||
| 1543 | { | ||
| 1544 | Destroy(); | ||
| 1545 | return false; | ||
| 1546 | } | ||
| 1547 | if (fAbort && fCanCancel) | ||
| 1548 | { | ||
| 1549 | strStatus = "CANCELLED"; | ||
| 1550 | Repaint(); | ||
| 1551 | fWorkDone = true; | ||
| 1552 | return false; | ||
| 1553 | } | ||
| 1554 | return true; | ||
| 1555 | } | ||
| 1556 | |||
| 1557 | bool CSendingDialog::Status(const string& str) | ||
| 1558 | { | ||
| 1559 | if (!Status()) | ||
| 1560 | return false; | ||
| 1561 | strStatus = str; | ||
| 1562 | Repaint(); | ||
| 1563 | return true; | ||
| 1564 | } | ||
| 1565 | |||
| 1566 | bool CSendingDialog::Error(const string& str) | ||
| 1567 | { | ||
| 1568 | fCanCancel = false; | ||
| 1569 | fWorkDone = true; | ||
| 1570 | Status(string("Error: ") + str); | ||
| 1571 | return false; | ||
| 1572 | } | ||
| 1573 | |||
| 1574 | void SendingDialogStartTransfer(void* parg) | ||
| 1575 | { | ||
| 1576 | ((CSendingDialog*)parg)->StartTransfer(); | ||
| 1577 | } | ||
| 1578 | |||
| 1579 | void CSendingDialog::StartTransfer() | ||
| 1580 | { | ||
| 1581 | // Make sure we have enough money | ||
| 1582 | if (nPrice + nTransactionFee > GetBalance()) | ||
| 1583 | { | ||
| 1584 | Error("You don't have enough money"); | ||
| 1585 | return; | ||
| 1586 | } | ||
| 1587 | |||
| 1588 | // We may have connected already for product details | ||
| 1589 | if (!Status("Connecting...")) | ||
| 1590 | return; | ||
| 1591 | CNode* pnode = ConnectNode(addr, 5 * 60); | ||
| 1592 | if (!pnode) | ||
| 1593 | { | ||
| 1594 | Error("Unable to connect"); | ||
| 1595 | return; | ||
| 1596 | } | ||
| 1597 | |||
| 1598 | // Send order to seller, with response going to OnReply2 via event handler | ||
| 1599 | if (!Status("Requesting public key...")) | ||
| 1600 | return; | ||
| 1601 | pnode->PushRequest("checkorder", wtx, SendingDialogOnReply2, this); | ||
| 1602 | } | ||
| 1603 | |||
| 1604 | void SendingDialogOnReply2(void* parg, CDataStream& vRecv) | ||
| 1605 | { | ||
| 1606 | ((CSendingDialog*)parg)->OnReply2(vRecv); | ||
| 1607 | } | ||
| 1608 | |||
| 1609 | void CSendingDialog::OnReply2(CDataStream& vRecv) | ||
| 1610 | { | ||
| 1611 | if (!Status("Received public key...")) | ||
| 1612 | return; | ||
| 1613 | |||
| 1614 | CScript scriptPubKey; | ||
| 1615 | int nRet; | ||
| 1616 | try | ||
| 1617 | { | ||
| 1618 | vRecv >> nRet; | ||
| 1619 | if (nRet > 0) | ||
| 1620 | { | ||
| 1621 | string strMessage; | ||
| 1622 | vRecv >> strMessage; | ||
| 1623 | Error("Transfer was not accepted"); | ||
| 1624 | //// todo: enlarge the window and enable a hidden white box to put seller's message | ||
| 1625 | return; | ||
| 1626 | } | ||
| 1627 | vRecv >> scriptPubKey; | ||
| 1628 | } | ||
| 1629 | catch (...) | ||
| 1630 | { | ||
| 1631 | //// what do we want to do about this? | ||
| 1632 | Error("Invalid response received"); | ||
| 1633 | return; | ||
| 1634 | } | ||
| 1635 | |||
| 1636 | // Should already be connected | ||
| 1637 | CNode* pnode = ConnectNode(addr, 5 * 60); | ||
| 1638 | if (!pnode) | ||
| 1639 | { | ||
| 1640 | Error("Lost connection"); | ||
| 1641 | return; | ||
| 1642 | } | ||
| 1643 | |||
| 1644 | // Pause to give the user a chance to cancel | ||
| 1645 | while (wxDateTime::UNow() < start + wxTimeSpan(0, 0, 0, 2 * 1000)) | ||
| 1646 | { | ||
| 1647 | Sleep(200); | ||
| 1648 | if (!Status()) | ||
| 1649 | return; | ||
| 1650 | } | ||
| 1651 | |||
| 1652 | CRITICAL_BLOCK(cs_main) | ||
| 1653 | { | ||
| 1654 | // Pay | ||
| 1655 | if (!Status("Creating transaction...")) | ||
| 1656 | return; | ||
| 1657 | if (nPrice + nTransactionFee > GetBalance()) | ||
| 1658 | { | ||
| 1659 | Error("You don't have enough money"); | ||
| 1660 | return; | ||
| 1661 | } | ||
| 1662 | int64 nFeeRequired; | ||
| 1663 | if (!CreateTransaction(scriptPubKey, nPrice, wtx, nFeeRequired)) | ||
| 1664 | { | ||
| 1665 | if (nPrice + nFeeRequired > GetBalance()) | ||
| 1666 | Error(strprintf("This is an oversized transaction that requires a transaction fee of %s", FormatMoney(nFeeRequired).c_str())); | ||
| 1667 | else | ||
| 1668 | Error("Transaction creation failed"); | ||
| 1669 | return; | ||
| 1670 | } | ||
| 1671 | |||
| 1672 | // Last chance to cancel | ||
| 1673 | Sleep(50); | ||
| 1674 | if (!Status()) | ||
| 1675 | return; | ||
| 1676 | fCanCancel = false; | ||
| 1677 | if (fAbort) | ||
| 1678 | { | ||
| 1679 | fCanCancel = true; | ||
| 1680 | if (!Status()) | ||
| 1681 | return; | ||
| 1682 | fCanCancel = false; | ||
| 1683 | } | ||
| 1684 | if (!Status("Sending payment...")) | ||
| 1685 | return; | ||
| 1686 | |||
| 1687 | // Commit | ||
| 1688 | if (!CommitTransactionSpent(wtx)) | ||
| 1689 | { | ||
| 1690 | Error("Error finalizing payment"); | ||
| 1691 | return; | ||
| 1692 | } | ||
| 1693 | |||
| 1694 | // Send payment tx to seller, with response going to OnReply3 via event handler | ||
| 1695 | pnode->PushRequest("submitorder", wtx, SendingDialogOnReply3, this); | ||
| 1696 | |||
| 1697 | // Accept and broadcast transaction | ||
| 1698 | if (!wtx.AcceptTransaction()) | ||
| 1699 | printf("ERROR: CSendingDialog : wtxNew.AcceptTransaction() %s failed\n", wtx.GetHash().ToString().c_str()); | ||
| 1700 | wtx.RelayWalletTransaction(); | ||
| 1701 | |||
| 1702 | Status("Waiting for confirmation..."); | ||
| 1703 | MainFrameRepaint(); | ||
| 1704 | } | ||
| 1705 | } | ||
| 1706 | |||
| 1707 | void SendingDialogOnReply3(void* parg, CDataStream& vRecv) | ||
| 1708 | { | ||
| 1709 | ((CSendingDialog*)parg)->OnReply3(vRecv); | ||
| 1710 | } | ||
| 1711 | |||
| 1712 | void CSendingDialog::OnReply3(CDataStream& vRecv) | ||
| 1713 | { | ||
| 1714 | int nRet; | ||
| 1715 | try | ||
| 1716 | { | ||
| 1717 | vRecv >> nRet; | ||
| 1718 | if (nRet > 0) | ||
| 1719 | { | ||
| 1720 | Error("The payment was sent, but the recipient was unable to verify it.\n" | ||
| 1721 | "The transaction is recorded and will credit to the recipient if it is valid,\n" | ||
| 1722 | "but without comment information."); | ||
| 1723 | return; | ||
| 1724 | } | ||
| 1725 | } | ||
| 1726 | catch (...) | ||
| 1727 | { | ||
| 1728 | //// what do we want to do about this? | ||
| 1729 | Error("Payment was sent, but an invalid response was received"); | ||
| 1730 | return; | ||
| 1731 | } | ||
| 1732 | |||
| 1733 | fSuccess = true; | ||
| 1734 | fWorkDone = true; | ||
| 1735 | Status("Payment completed"); | ||
| 1736 | } | ||
| 1737 | |||
| 1738 | |||
| 1739 | |||
| 1740 | |||
| 1741 | |||
| 1742 | |||
| 1743 | ////////////////////////////////////////////////////////////////////////////// | ||
| 1744 | // | ||
| 1745 | // CYourAddressDialog | ||
| 1746 | // | ||
| 1747 | |||
| 1748 | CYourAddressDialog::CYourAddressDialog(wxWindow* parent, const string& strInitSelected) : CYourAddressDialogBase(parent) | ||
| 1749 | { | ||
| 1750 | // Init column headers | ||
| 1751 | m_listCtrl->InsertColumn(0, "Name", wxLIST_FORMAT_LEFT, 200); | ||
| 1752 | m_listCtrl->InsertColumn(1, "Bitflash Address", wxLIST_FORMAT_LEFT, 350); | ||
| 1753 | m_listCtrl->SetFocus(); | ||
| 1754 | |||
| 1755 | // Fill listctrl with address book data | ||
| 1756 | CRITICAL_BLOCK(cs_mapKeys) | ||
| 1757 | { | ||
| 1758 | foreach(const PAIRTYPE(string, string)& item, mapAddressBook) | ||
| 1759 | { | ||
| 1760 | string strAddress = item.first; | ||
| 1761 | string strName = item.second; | ||
| 1762 | uint160 hash160; | ||
| 1763 | bool fMine = (AddressToHash160(strAddress, hash160) && mapPubKeys.count(hash160)); | ||
| 1764 | if (fMine) | ||
| 1765 | { | ||
| 1766 | int nIndex = InsertLine(m_listCtrl, strName, strAddress); | ||
| 1767 | if (strAddress == strInitSelected) | ||
| 1768 | m_listCtrl->SetItemState(nIndex, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED); | ||
| 1769 | } | ||
| 1770 | } | ||
| 1771 | } | ||
| 1772 | } | ||
| 1773 | |||
| 1774 | wxString CYourAddressDialog::GetAddress() | ||
| 1775 | { | ||
| 1776 | int nIndex = GetSelection(m_listCtrl); | ||
| 1777 | if (nIndex == -1) | ||
| 1778 | return ""; | ||
| 1779 | return GetItemText(m_listCtrl, nIndex, 1); | ||
| 1780 | } | ||
| 1781 | |||
| 1782 | void CYourAddressDialog::OnListEndLabelEdit(wxListEvent& event) | ||
| 1783 | { | ||
| 1784 | // Update address book with edited name | ||
| 1785 | if (event.IsEditCancelled()) | ||
| 1786 | return; | ||
| 1787 | string strAddress = (string)GetItemText(m_listCtrl, event.GetIndex(), 1); | ||
| 1788 | SetAddressBookName(strAddress, string(event.GetText())); | ||
| 1789 | pframeMain->RefreshListCtrl(); | ||
| 1790 | } | ||
| 1791 | |||
| 1792 | void CYourAddressDialog::OnListItemSelected(wxListEvent& event) | ||
| 1793 | { | ||
| 1794 | } | ||
| 1795 | |||
| 1796 | void CYourAddressDialog::OnListItemActivated(wxListEvent& event) | ||
| 1797 | { | ||
| 1798 | // Doubleclick returns selection | ||
| 1799 | EndModal(true); | ||
| 1800 | } | ||
| 1801 | |||
| 1802 | void CYourAddressDialog::OnButtonRename(wxCommandEvent& event) | ||
| 1803 | { | ||
| 1804 | // Ask new name | ||
| 1805 | int nIndex = GetSelection(m_listCtrl); | ||
| 1806 | if (nIndex == -1) | ||
| 1807 | return; | ||
| 1808 | string strName = (string)m_listCtrl->GetItemText(nIndex); | ||
| 1809 | string strAddress = (string)GetItemText(m_listCtrl, nIndex, 1); | ||
| 1810 | CGetTextFromUserDialog dialog(this, "Rename Bitflash Address", "New Name", strName); | ||
| 1811 | if (!dialog.ShowModal()) | ||
| 1812 | return; | ||
| 1813 | strName = dialog.GetValue(); | ||
| 1814 | |||
| 1815 | // Change name | ||
| 1816 | SetAddressBookName(strAddress, strName); | ||
| 1817 | m_listCtrl->SetItemText(nIndex, strName); | ||
| 1818 | pframeMain->RefreshListCtrl(); | ||
| 1819 | } | ||
| 1820 | |||
| 1821 | void CYourAddressDialog::OnButtonNew(wxCommandEvent& event) | ||
| 1822 | { | ||
| 1823 | // Ask name | ||
| 1824 | CGetTextFromUserDialog dialog(this, "New Bitflash Address", "Name", ""); | ||
| 1825 | if (!dialog.ShowModal()) | ||
| 1826 | return; | ||
| 1827 | string strName = dialog.GetValue(); | ||
| 1828 | |||
| 1829 | // Generate new key | ||
| 1830 | string strAddress = PubKeyToAddress(GenerateNewKey()); | ||
| 1831 | SetAddressBookName(strAddress, strName); | ||
| 1832 | |||
| 1833 | // Add to list and select it | ||
| 1834 | int nIndex = InsertLine(m_listCtrl, strName, strAddress); | ||
| 1835 | SetSelection(m_listCtrl, nIndex); | ||
| 1836 | m_listCtrl->SetFocus(); | ||
| 1837 | } | ||
| 1838 | |||
| 1839 | void CYourAddressDialog::OnButtonCopy(wxCommandEvent& event) | ||
| 1840 | { | ||
| 1841 | // Copy address box to clipboard | ||
| 1842 | if (wxTheClipboard->Open()) | ||
| 1843 | { | ||
| 1844 | wxTheClipboard->SetData(new wxTextDataObject(GetAddress())); | ||
| 1845 | wxTheClipboard->Close(); | ||
| 1846 | } | ||
| 1847 | } | ||
| 1848 | |||
| 1849 | void CYourAddressDialog::OnButtonOK(wxCommandEvent& event) | ||
| 1850 | { | ||
| 1851 | // OK | ||
| 1852 | EndModal(true); | ||
| 1853 | } | ||
| 1854 | |||
| 1855 | void CYourAddressDialog::OnButtonCancel(wxCommandEvent& event) | ||
| 1856 | { | ||
| 1857 | // Cancel | ||
| 1858 | EndModal(false); | ||
| 1859 | } | ||
| 1860 | |||
| 1861 | void CYourAddressDialog::OnClose(wxCloseEvent& event) | ||
| 1862 | { | ||
| 1863 | // Close | ||
| 1864 | EndModal(false); | ||
| 1865 | } | ||
| 1866 | |||
| 1867 | |||
| 1868 | |||
| 1869 | |||
| 1870 | |||
| 1871 | |||
| 1872 | ////////////////////////////////////////////////////////////////////////////// | ||
| 1873 | // | ||
| 1874 | // CAddressBookDialog | ||
| 1875 | // | ||
| 1876 | |||
| 1877 | CAddressBookDialog::CAddressBookDialog(wxWindow* parent, const wxString& strInitSelected, bool fSendingIn) : CAddressBookDialogBase(parent) | ||
| 1878 | { | ||
| 1879 | fSending = fSendingIn; | ||
| 1880 | if (!fSending) | ||
| 1881 | m_buttonCancel->Show(false); | ||
| 1882 | |||
| 1883 | // Init column headers | ||
| 1884 | m_listCtrl->InsertColumn(0, "Name", wxLIST_FORMAT_LEFT, 200); | ||
| 1885 | m_listCtrl->InsertColumn(1, "Address", wxLIST_FORMAT_LEFT, 350); | ||
| 1886 | m_listCtrl->SetFocus(); | ||
| 1887 | |||
| 1888 | // Set Icon | ||
| 1889 | wxBitmap bmpAddressBook(wxT("addressbook16"), wxBITMAP_TYPE_RESOURCE); | ||
| 1890 | bmpAddressBook.SetMask(new wxMask(wxBitmap(wxT("addressbook16mask"), wxBITMAP_TYPE_RESOURCE))); | ||
| 1891 | wxIcon iconAddressBook; | ||
| 1892 | iconAddressBook.CopyFromBitmap(bmpAddressBook); | ||
| 1893 | SetIcon(iconAddressBook); | ||
| 1894 | |||
| 1895 | // Fill listctrl with address book data | ||
| 1896 | CRITICAL_BLOCK(cs_mapKeys) | ||
| 1897 | { | ||
| 1898 | foreach(const PAIRTYPE(string, string)& item, mapAddressBook) | ||
| 1899 | { | ||
| 1900 | string strAddress = item.first; | ||
| 1901 | string strName = item.second; | ||
| 1902 | uint160 hash160; | ||
| 1903 | bool fMine = (AddressToHash160(strAddress, hash160) && mapPubKeys.count(hash160)); | ||
| 1904 | if (!fMine) | ||
| 1905 | { | ||
| 1906 | int nIndex = InsertLine(m_listCtrl, strName, strAddress); | ||
| 1907 | if (strAddress == strInitSelected) | ||
| 1908 | m_listCtrl->SetItemState(nIndex, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED); | ||
| 1909 | } | ||
| 1910 | } | ||
| 1911 | } | ||
| 1912 | } | ||
| 1913 | |||
| 1914 | wxString CAddressBookDialog::GetAddress() | ||
| 1915 | { | ||
| 1916 | int nIndex = GetSelection(m_listCtrl); | ||
| 1917 | if (nIndex == -1) | ||
| 1918 | return ""; | ||
| 1919 | return GetItemText(m_listCtrl, nIndex, 1); | ||
| 1920 | } | ||
| 1921 | |||
| 1922 | void CAddressBookDialog::OnListEndLabelEdit(wxListEvent& event) | ||
| 1923 | { | ||
| 1924 | // Update address book with edited name | ||
| 1925 | if (event.IsEditCancelled()) | ||
| 1926 | return; | ||
| 1927 | string strAddress = (string)GetItemText(m_listCtrl, event.GetIndex(), 1); | ||
| 1928 | SetAddressBookName(strAddress, string(event.GetText())); | ||
| 1929 | pframeMain->RefreshListCtrl(); | ||
| 1930 | } | ||
| 1931 | |||
| 1932 | void CAddressBookDialog::OnListItemSelected(wxListEvent& event) | ||
| 1933 | { | ||
| 1934 | } | ||
| 1935 | |||
| 1936 | void CAddressBookDialog::OnListItemActivated(wxListEvent& event) | ||
| 1937 | { | ||
| 1938 | if (fSending) | ||
| 1939 | { | ||
| 1940 | // Doubleclick returns selection | ||
| 1941 | EndModal(GetAddress() != "" ? 2 : 0); | ||
| 1942 | } | ||
| 1943 | else | ||
| 1944 | { | ||
| 1945 | // Doubleclick edits item | ||
| 1946 | wxCommandEvent event; | ||
| 1947 | OnButtonEdit(event); | ||
| 1948 | } | ||
| 1949 | } | ||
| 1950 | |||
| 1951 | void CAddressBookDialog::OnButtonEdit(wxCommandEvent& event) | ||
| 1952 | { | ||
| 1953 | // Ask new name | ||
| 1954 | int nIndex = GetSelection(m_listCtrl); | ||
| 1955 | if (nIndex == -1) | ||
| 1956 | return; | ||
| 1957 | string strName = (string)m_listCtrl->GetItemText(nIndex); | ||
| 1958 | string strAddress = (string)GetItemText(m_listCtrl, nIndex, 1); | ||
| 1959 | string strAddressOrg = strAddress; | ||
| 1960 | CGetTextFromUserDialog dialog(this, "Edit Address", "Name", strName, "Address", strAddress); | ||
| 1961 | if (!dialog.ShowModal()) | ||
| 1962 | return; | ||
| 1963 | strName = dialog.GetValue1(); | ||
| 1964 | strAddress = dialog.GetValue2(); | ||
| 1965 | |||
| 1966 | // Change name | ||
| 1967 | if (strAddress != strAddressOrg) | ||
| 1968 | CWalletDB().EraseName(strAddressOrg); | ||
| 1969 | SetAddressBookName(strAddress, strName); | ||
| 1970 | m_listCtrl->SetItem(nIndex, 1, strAddress); | ||
| 1971 | m_listCtrl->SetItemText(nIndex, strName); | ||
| 1972 | pframeMain->RefreshListCtrl(); | ||
| 1973 | } | ||
| 1974 | |||
| 1975 | void CAddressBookDialog::OnButtonNew(wxCommandEvent& event) | ||
| 1976 | { | ||
| 1977 | // Ask name | ||
| 1978 | CGetTextFromUserDialog dialog(this, "New Address", "Name", "", "Address", ""); | ||
| 1979 | if (!dialog.ShowModal()) | ||
| 1980 | return; | ||
| 1981 | string strName = dialog.GetValue1(); | ||
| 1982 | string strAddress = dialog.GetValue2(); | ||
| 1983 | |||
| 1984 | // Add to list and select it | ||
| 1985 | SetAddressBookName(strAddress, strName); | ||
| 1986 | int nIndex = InsertLine(m_listCtrl, strName, strAddress); | ||
| 1987 | SetSelection(m_listCtrl, nIndex); | ||
| 1988 | m_listCtrl->SetFocus(); | ||
| 1989 | } | ||
| 1990 | |||
| 1991 | void CAddressBookDialog::OnButtonDelete(wxCommandEvent& event) | ||
| 1992 | { | ||
| 1993 | for (int nIndex = m_listCtrl->GetItemCount()-1; nIndex >= 0; nIndex--) | ||
| 1994 | { | ||
| 1995 | if (m_listCtrl->GetItemState(nIndex, wxLIST_STATE_SELECTED)) | ||
| 1996 | { | ||
| 1997 | string strAddress = (string)GetItemText(m_listCtrl, nIndex, 1); | ||
| 1998 | CWalletDB().EraseName(strAddress); | ||
| 1999 | m_listCtrl->DeleteItem(nIndex); | ||
| 2000 | } | ||
| 2001 | } | ||
| 2002 | pframeMain->RefreshListCtrl(); | ||
| 2003 | } | ||
| 2004 | |||
| 2005 | void CAddressBookDialog::OnButtonCopy(wxCommandEvent& event) | ||
| 2006 | { | ||
| 2007 | // Copy address box to clipboard | ||
| 2008 | if (wxTheClipboard->Open()) | ||
| 2009 | { | ||
| 2010 | wxTheClipboard->SetData(new wxTextDataObject(GetAddress())); | ||
| 2011 | wxTheClipboard->Close(); | ||
| 2012 | } | ||
| 2013 | } | ||
| 2014 | |||
| 2015 | void CAddressBookDialog::OnButtonOK(wxCommandEvent& event) | ||
| 2016 | { | ||
| 2017 | // OK | ||
| 2018 | EndModal(GetAddress() != "" ? 1 : 0); | ||
| 2019 | } | ||
| 2020 | |||
| 2021 | void CAddressBookDialog::OnButtonCancel(wxCommandEvent& event) | ||
| 2022 | { | ||
| 2023 | // Cancel | ||
| 2024 | EndModal(0); | ||
| 2025 | } | ||
| 2026 | |||
| 2027 | void CAddressBookDialog::OnClose(wxCloseEvent& event) | ||
| 2028 | { | ||
| 2029 | // Close | ||
| 2030 | EndModal(0); | ||
| 2031 | } | ||
| 2032 | |||
| 2033 | |||
| 2034 | |||
| 2035 | |||
| 2036 | |||
| 2037 | |||
| 2038 | ////////////////////////////////////////////////////////////////////////////// | ||
| 2039 | // | ||
| 2040 | // CProductsDialog | ||
| 2041 | // | ||
| 2042 | |||
| 2043 | bool CompareIntStringPairBestFirst(const pair<int, string>& item1, const pair<int, string>& item2) | ||
| 2044 | { | ||
| 2045 | return (item1.first > item2.first); | ||
| 2046 | } | ||
| 2047 | |||
| 2048 | CProductsDialog::CProductsDialog(wxWindow* parent) : CProductsDialogBase(parent) | ||
| 2049 | { | ||
| 2050 | // Init column headers | ||
| 2051 | m_listCtrl->InsertColumn(0, "Title", wxLIST_FORMAT_LEFT, 200); | ||
| 2052 | m_listCtrl->InsertColumn(1, "Price", wxLIST_FORMAT_LEFT, 80); | ||
| 2053 | m_listCtrl->InsertColumn(2, "Seller", wxLIST_FORMAT_LEFT, 80); | ||
| 2054 | m_listCtrl->InsertColumn(3, "Stars", wxLIST_FORMAT_LEFT, 50); | ||
| 2055 | m_listCtrl->InsertColumn(4, "Power", wxLIST_FORMAT_LEFT, 50); | ||
| 2056 | |||
| 2057 | // Tally top categories | ||
| 2058 | map<string, int> mapTopCategories; | ||
| 2059 | CRITICAL_BLOCK(cs_mapProducts) | ||
| 2060 | for (map<uint256, CProduct>::iterator mi = mapProducts.begin(); mi != mapProducts.end(); ++mi) | ||
| 2061 | mapTopCategories[(*mi).second.mapValue["category"]]++; | ||
| 2062 | |||
| 2063 | // Sort top categories | ||
| 2064 | vector<pair<int, string> > vTopCategories; | ||
| 2065 | for (map<string, int>::iterator mi = mapTopCategories.begin(); mi != mapTopCategories.end(); ++mi) | ||
| 2066 | vTopCategories.push_back(make_pair((*mi).second, (*mi).first)); | ||
| 2067 | sort(vTopCategories.begin(), vTopCategories.end(), CompareIntStringPairBestFirst); | ||
| 2068 | |||
| 2069 | // Fill categories combo box | ||
| 2070 | int nLimit = 250; | ||
| 2071 | for (vector<pair<int, string> >::iterator it = vTopCategories.begin(); it != vTopCategories.end() && nLimit-- > 0; ++it) | ||
| 2072 | m_comboBoxCategory->Append((*it).second); | ||
| 2073 | |||
| 2074 | // Fill window with initial search | ||
| 2075 | //wxCommandEvent event; | ||
| 2076 | //OnButtonSearch(event); | ||
| 2077 | } | ||
| 2078 | |||
| 2079 | void CProductsDialog::OnCombobox(wxCommandEvent& event) | ||
| 2080 | { | ||
| 2081 | OnButtonSearch(event); | ||
| 2082 | } | ||
| 2083 | |||
| 2084 | bool CompareProductsBestFirst(const CProduct* p1, const CProduct* p2) | ||
| 2085 | { | ||
| 2086 | return (p1->nAtoms > p2->nAtoms); | ||
| 2087 | } | ||
| 2088 | |||
| 2089 | void CProductsDialog::OnButtonSearch(wxCommandEvent& event) | ||
| 2090 | { | ||
| 2091 | string strCategory = (string)m_comboBoxCategory->GetValue(); | ||
| 2092 | string strSearch = (string)m_textCtrlSearch->GetValue(); | ||
| 2093 | |||
| 2094 | // Search products | ||
| 2095 | vector<CProduct*> vProductsFound; | ||
| 2096 | CRITICAL_BLOCK(cs_mapProducts) | ||
| 2097 | { | ||
| 2098 | for (map<uint256, CProduct>::iterator mi = mapProducts.begin(); mi != mapProducts.end(); ++mi) | ||
| 2099 | { | ||
| 2100 | CProduct& product = (*mi).second; | ||
| 2101 | if (product.mapValue["category"].find(strCategory) != -1) | ||
| 2102 | { | ||
| 2103 | if (product.mapValue["title"].find(strSearch) != -1 || | ||
| 2104 | product.mapValue["description"].find(strSearch) != -1 || | ||
| 2105 | product.mapValue["seller"].find(strSearch) != -1) | ||
| 2106 | { | ||
| 2107 | vProductsFound.push_back(&product); | ||
| 2108 | } | ||
| 2109 | } | ||
| 2110 | } | ||
| 2111 | } | ||
| 2112 | |||
| 2113 | // Sort | ||
| 2114 | sort(vProductsFound.begin(), vProductsFound.end(), CompareProductsBestFirst); | ||
| 2115 | |||
| 2116 | // Display | ||
| 2117 | foreach(CProduct* pproduct, vProductsFound) | ||
| 2118 | { | ||
| 2119 | InsertLine(m_listCtrl, | ||
| 2120 | pproduct->mapValue["title"], | ||
| 2121 | pproduct->mapValue["price"], | ||
| 2122 | pproduct->mapValue["seller"], | ||
| 2123 | pproduct->mapValue["stars"], | ||
| 2124 | itostr(pproduct->nAtoms)); | ||
| 2125 | } | ||
| 2126 | } | ||
| 2127 | |||
| 2128 | void CProductsDialog::OnListItemActivated(wxListEvent& event) | ||
| 2129 | { | ||
| 2130 | // Doubleclick opens product | ||
| 2131 | CViewProductDialog* pdialog = new CViewProductDialog(this, m_vProduct[event.GetIndex()]); | ||
| 2132 | pdialog->Show(); | ||
| 2133 | } | ||
| 2134 | |||
| 2135 | |||
| 2136 | |||
| 2137 | |||
| 2138 | |||
| 2139 | |||
| 2140 | |||
| 2141 | ////////////////////////////////////////////////////////////////////////////// | ||
| 2142 | // | ||
| 2143 | // CEditProductDialog | ||
| 2144 | // | ||
| 2145 | |||
| 2146 | CEditProductDialog::CEditProductDialog(wxWindow* parent) : CEditProductDialogBase(parent) | ||
| 2147 | { | ||
| 2148 | m_textCtrlLabel[0 ] = m_textCtrlLabel0; | ||
| 2149 | m_textCtrlLabel[1 ] = m_textCtrlLabel1; | ||
| 2150 | m_textCtrlLabel[2 ] = m_textCtrlLabel2; | ||
| 2151 | m_textCtrlLabel[3 ] = m_textCtrlLabel3; | ||
| 2152 | m_textCtrlLabel[4 ] = m_textCtrlLabel4; | ||
| 2153 | m_textCtrlLabel[5 ] = m_textCtrlLabel5; | ||
| 2154 | m_textCtrlLabel[6 ] = m_textCtrlLabel6; | ||
| 2155 | m_textCtrlLabel[7 ] = m_textCtrlLabel7; | ||
| 2156 | m_textCtrlLabel[8 ] = m_textCtrlLabel8; | ||
| 2157 | m_textCtrlLabel[9 ] = m_textCtrlLabel9; | ||
| 2158 | m_textCtrlLabel[10] = m_textCtrlLabel10; | ||
| 2159 | m_textCtrlLabel[11] = m_textCtrlLabel11; | ||
| 2160 | m_textCtrlLabel[12] = m_textCtrlLabel12; | ||
| 2161 | m_textCtrlLabel[13] = m_textCtrlLabel13; | ||
| 2162 | m_textCtrlLabel[14] = m_textCtrlLabel14; | ||
| 2163 | m_textCtrlLabel[15] = m_textCtrlLabel15; | ||
| 2164 | m_textCtrlLabel[16] = m_textCtrlLabel16; | ||
| 2165 | m_textCtrlLabel[17] = m_textCtrlLabel17; | ||
| 2166 | m_textCtrlLabel[18] = m_textCtrlLabel18; | ||
| 2167 | m_textCtrlLabel[19] = m_textCtrlLabel19; | ||
| 2168 | |||
| 2169 | m_textCtrlField[0 ] = m_textCtrlField0; | ||
| 2170 | m_textCtrlField[1 ] = m_textCtrlField1; | ||
| 2171 | m_textCtrlField[2 ] = m_textCtrlField2; | ||
| 2172 | m_textCtrlField[3 ] = m_textCtrlField3; | ||
| 2173 | m_textCtrlField[4 ] = m_textCtrlField4; | ||
| 2174 | m_textCtrlField[5 ] = m_textCtrlField5; | ||
| 2175 | m_textCtrlField[6 ] = m_textCtrlField6; | ||
| 2176 | m_textCtrlField[7 ] = m_textCtrlField7; | ||
| 2177 | m_textCtrlField[8 ] = m_textCtrlField8; | ||
| 2178 | m_textCtrlField[9 ] = m_textCtrlField9; | ||
| 2179 | m_textCtrlField[10] = m_textCtrlField10; | ||
| 2180 | m_textCtrlField[11] = m_textCtrlField11; | ||
| 2181 | m_textCtrlField[12] = m_textCtrlField12; | ||
| 2182 | m_textCtrlField[13] = m_textCtrlField13; | ||
| 2183 | m_textCtrlField[14] = m_textCtrlField14; | ||
| 2184 | m_textCtrlField[15] = m_textCtrlField15; | ||
| 2185 | m_textCtrlField[16] = m_textCtrlField16; | ||
| 2186 | m_textCtrlField[17] = m_textCtrlField17; | ||
| 2187 | m_textCtrlField[18] = m_textCtrlField18; | ||
| 2188 | m_textCtrlField[19] = m_textCtrlField19; | ||
| 2189 | |||
| 2190 | m_buttonDel[0 ] = m_buttonDel0; | ||
| 2191 | m_buttonDel[1 ] = m_buttonDel1; | ||
| 2192 | m_buttonDel[2 ] = m_buttonDel2; | ||
| 2193 | m_buttonDel[3 ] = m_buttonDel3; | ||
| 2194 | m_buttonDel[4 ] = m_buttonDel4; | ||
| 2195 | m_buttonDel[5 ] = m_buttonDel5; | ||
| 2196 | m_buttonDel[6 ] = m_buttonDel6; | ||
| 2197 | m_buttonDel[7 ] = m_buttonDel7; | ||
| 2198 | m_buttonDel[8 ] = m_buttonDel8; | ||
| 2199 | m_buttonDel[9 ] = m_buttonDel9; | ||
| 2200 | m_buttonDel[10] = m_buttonDel10; | ||
| 2201 | m_buttonDel[11] = m_buttonDel11; | ||
| 2202 | m_buttonDel[12] = m_buttonDel12; | ||
| 2203 | m_buttonDel[13] = m_buttonDel13; | ||
| 2204 | m_buttonDel[14] = m_buttonDel14; | ||
| 2205 | m_buttonDel[15] = m_buttonDel15; | ||
| 2206 | m_buttonDel[16] = m_buttonDel16; | ||
| 2207 | m_buttonDel[17] = m_buttonDel17; | ||
| 2208 | m_buttonDel[18] = m_buttonDel18; | ||
| 2209 | m_buttonDel[19] = m_buttonDel19; | ||
| 2210 | |||
| 2211 | for (int i = 1; i < FIELDS_MAX; i++) | ||
| 2212 | ShowLine(i, false); | ||
| 2213 | |||
| 2214 | LayoutAll(); | ||
| 2215 | } | ||
| 2216 | |||
| 2217 | void CEditProductDialog::LayoutAll() | ||
| 2218 | { | ||
| 2219 | m_scrolledWindow->Layout(); | ||
| 2220 | m_scrolledWindow->GetSizer()->Fit(m_scrolledWindow); | ||
| 2221 | this->Layout(); | ||
| 2222 | } | ||
| 2223 | |||
| 2224 | void CEditProductDialog::ShowLine(int i, bool fShow) | ||
| 2225 | { | ||
| 2226 | m_textCtrlLabel[i]->Show(fShow); | ||
| 2227 | m_textCtrlField[i]->Show(fShow); | ||
| 2228 | m_buttonDel[i]->Show(fShow); | ||
| 2229 | } | ||
| 2230 | |||
| 2231 | void CEditProductDialog::OnButtonDel0(wxCommandEvent& event) { OnButtonDel(event, 0); } | ||
| 2232 | void CEditProductDialog::OnButtonDel1(wxCommandEvent& event) { OnButtonDel(event, 1); } | ||
| 2233 | void CEditProductDialog::OnButtonDel2(wxCommandEvent& event) { OnButtonDel(event, 2); } | ||
| 2234 | void CEditProductDialog::OnButtonDel3(wxCommandEvent& event) { OnButtonDel(event, 3); } | ||
| 2235 | void CEditProductDialog::OnButtonDel4(wxCommandEvent& event) { OnButtonDel(event, 4); } | ||
| 2236 | void CEditProductDialog::OnButtonDel5(wxCommandEvent& event) { OnButtonDel(event, 5); } | ||
| 2237 | void CEditProductDialog::OnButtonDel6(wxCommandEvent& event) { OnButtonDel(event, 6); } | ||
| 2238 | void CEditProductDialog::OnButtonDel7(wxCommandEvent& event) { OnButtonDel(event, 7); } | ||
| 2239 | void CEditProductDialog::OnButtonDel8(wxCommandEvent& event) { OnButtonDel(event, 8); } | ||
| 2240 | void CEditProductDialog::OnButtonDel9(wxCommandEvent& event) { OnButtonDel(event, 9); } | ||
| 2241 | void CEditProductDialog::OnButtonDel10(wxCommandEvent& event) { OnButtonDel(event, 10); } | ||
| 2242 | void CEditProductDialog::OnButtonDel11(wxCommandEvent& event) { OnButtonDel(event, 11); } | ||
| 2243 | void CEditProductDialog::OnButtonDel12(wxCommandEvent& event) { OnButtonDel(event, 12); } | ||
| 2244 | void CEditProductDialog::OnButtonDel13(wxCommandEvent& event) { OnButtonDel(event, 13); } | ||
| 2245 | void CEditProductDialog::OnButtonDel14(wxCommandEvent& event) { OnButtonDel(event, 14); } | ||
| 2246 | void CEditProductDialog::OnButtonDel15(wxCommandEvent& event) { OnButtonDel(event, 15); } | ||
| 2247 | void CEditProductDialog::OnButtonDel16(wxCommandEvent& event) { OnButtonDel(event, 16); } | ||
| 2248 | void CEditProductDialog::OnButtonDel17(wxCommandEvent& event) { OnButtonDel(event, 17); } | ||
| 2249 | void CEditProductDialog::OnButtonDel18(wxCommandEvent& event) { OnButtonDel(event, 18); } | ||
| 2250 | void CEditProductDialog::OnButtonDel19(wxCommandEvent& event) { OnButtonDel(event, 19); } | ||
| 2251 | |||
| 2252 | void CEditProductDialog::OnButtonDel(wxCommandEvent& event, int n) | ||
| 2253 | { | ||
| 2254 | Freeze(); | ||
| 2255 | int x, y; | ||
| 2256 | m_scrolledWindow->GetViewStart(&x, &y); | ||
| 2257 | int i; | ||
| 2258 | for (i = n; i < FIELDS_MAX-1; i++) | ||
| 2259 | { | ||
| 2260 | m_textCtrlLabel[i]->SetValue(m_textCtrlLabel[i+1]->GetValue()); | ||
| 2261 | m_textCtrlField[i]->SetValue(m_textCtrlField[i+1]->GetValue()); | ||
| 2262 | if (!m_buttonDel[i+1]->IsShown()) | ||
| 2263 | break; | ||
| 2264 | } | ||
| 2265 | m_textCtrlLabel[i]->SetValue(""); | ||
| 2266 | m_textCtrlField[i]->SetValue(""); | ||
| 2267 | ShowLine(i, false); | ||
| 2268 | m_buttonAddField->Enable(true); | ||
| 2269 | LayoutAll(); | ||
| 2270 | m_scrolledWindow->Scroll(0, y); | ||
| 2271 | Thaw(); | ||
| 2272 | } | ||
| 2273 | |||
| 2274 | void CEditProductDialog::OnButtonAddField(wxCommandEvent& event) | ||
| 2275 | { | ||
| 2276 | for (int i = 0; i < FIELDS_MAX; i++) | ||
| 2277 | { | ||
| 2278 | if (!m_buttonDel[i]->IsShown()) | ||
| 2279 | { | ||
| 2280 | Freeze(); | ||
| 2281 | ShowLine(i, true); | ||
| 2282 | if (i == FIELDS_MAX-1) | ||
| 2283 | m_buttonAddField->Enable(false); | ||
| 2284 | LayoutAll(); | ||
| 2285 | m_scrolledWindow->Scroll(0, 99999); | ||
| 2286 | Thaw(); | ||
| 2287 | break; | ||
| 2288 | } | ||
| 2289 | } | ||
| 2290 | } | ||
| 2291 | |||
| 2292 | void CEditProductDialog::OnButtonSend(wxCommandEvent& event) | ||
| 2293 | { | ||
| 2294 | CProduct product; | ||
| 2295 | GetProduct(product); | ||
| 2296 | |||
| 2297 | // Sign the detailed product | ||
| 2298 | product.vchPubKeyFrom = keyUser.GetPubKey(); | ||
| 2299 | if (!keyUser.Sign(product.GetSigHash(), product.vchSig)) | ||
| 2300 | { | ||
| 2301 | wxMessageBox("Error digitally signing the product "); | ||
| 2302 | return; | ||
| 2303 | } | ||
| 2304 | |||
| 2305 | // Save detailed product | ||
| 2306 | AddToMyProducts(product); | ||
| 2307 | |||
| 2308 | // Strip down to summary product | ||
| 2309 | product.mapDetails.clear(); | ||
| 2310 | product.vOrderForm.clear(); | ||
| 2311 | |||
| 2312 | // Sign the summary product | ||
| 2313 | if (!keyUser.Sign(product.GetSigHash(), product.vchSig)) | ||
| 2314 | { | ||
| 2315 | wxMessageBox("Error digitally signing the product "); | ||
| 2316 | return; | ||
| 2317 | } | ||
| 2318 | |||
| 2319 | // Verify | ||
| 2320 | if (!product.CheckProduct()) | ||
| 2321 | { | ||
| 2322 | wxMessageBox("Errors found in product "); | ||
| 2323 | return; | ||
| 2324 | } | ||
| 2325 | |||
| 2326 | // Broadcast | ||
| 2327 | AdvertStartPublish(pnodeLocalHost, MSG_PRODUCT, 0, product); | ||
| 2328 | |||
| 2329 | Destroy(); | ||
| 2330 | } | ||
| 2331 | |||
| 2332 | void CEditProductDialog::OnButtonPreview(wxCommandEvent& event) | ||
| 2333 | { | ||
| 2334 | CProduct product; | ||
| 2335 | GetProduct(product); | ||
| 2336 | CViewProductDialog* pdialog = new CViewProductDialog(this, product); | ||
| 2337 | pdialog->Show(); | ||
| 2338 | } | ||
| 2339 | |||
| 2340 | void CEditProductDialog::OnButtonCancel(wxCommandEvent& event) | ||
| 2341 | { | ||
| 2342 | Destroy(); | ||
| 2343 | } | ||
| 2344 | |||
| 2345 | void CEditProductDialog::SetProduct(const CProduct& productIn) | ||
| 2346 | { | ||
| 2347 | CProduct product = productIn; | ||
| 2348 | |||
| 2349 | m_comboBoxCategory->SetValue(product.mapValue["category"]); | ||
| 2350 | m_textCtrlTitle->SetValue(product.mapValue["title"]); | ||
| 2351 | m_textCtrlPrice->SetValue(product.mapValue["price"]); | ||
| 2352 | m_textCtrlDescription->SetValue(product.mapValue["description"]); | ||
| 2353 | m_textCtrlInstructions->SetValue(product.mapValue["instructions"]); | ||
| 2354 | |||
| 2355 | for (int i = 0; i < FIELDS_MAX; i++) | ||
| 2356 | { | ||
| 2357 | bool fUsed = i < product.vOrderForm.size(); | ||
| 2358 | m_buttonDel[i]->Show(fUsed); | ||
| 2359 | m_textCtrlLabel[i]->Show(fUsed); | ||
| 2360 | m_textCtrlField[i]->Show(fUsed); | ||
| 2361 | if (!fUsed) | ||
| 2362 | continue; | ||
| 2363 | |||
| 2364 | m_textCtrlLabel[i]->SetValue(product.vOrderForm[i].first); | ||
| 2365 | string strControl = product.vOrderForm[i].second; | ||
| 2366 | if (strControl.substr(0, 5) == "text=") | ||
| 2367 | m_textCtrlField[i]->SetValue(""); | ||
| 2368 | else if (strControl.substr(0, 7) == "choice=") | ||
| 2369 | m_textCtrlField[i]->SetValue(strControl.substr(7)); | ||
| 2370 | else | ||
| 2371 | m_textCtrlField[i]->SetValue(strControl); | ||
| 2372 | } | ||
| 2373 | } | ||
| 2374 | |||
| 2375 | void CEditProductDialog::GetProduct(CProduct& product) | ||
| 2376 | { | ||
| 2377 | // map<string, string> mapValue; | ||
| 2378 | // vector<pair<string, string> > vOrderForm; | ||
| 2379 | |||
| 2380 | product.mapValue["category"] = m_comboBoxCategory->GetValue().Trim(); | ||
| 2381 | product.mapValue["title"] = m_textCtrlTitle->GetValue().Trim(); | ||
| 2382 | product.mapValue["price"] = m_textCtrlPrice->GetValue().Trim(); | ||
| 2383 | product.mapValue["description"] = m_textCtrlDescription->GetValue().Trim(); | ||
| 2384 | product.mapValue["instructions"] = m_textCtrlInstructions->GetValue().Trim(); | ||
| 2385 | |||
| 2386 | for (int i = 0; i < FIELDS_MAX; i++) | ||
| 2387 | { | ||
| 2388 | if (m_buttonDel[i]->IsShown()) | ||
| 2389 | { | ||
| 2390 | string strLabel = (string)m_textCtrlLabel[i]->GetValue().Trim(); | ||
| 2391 | string strControl = (string)m_textCtrlField[i]->GetValue(); | ||
| 2392 | if (strControl.empty()) | ||
| 2393 | strControl = "text="; | ||
| 2394 | else | ||
| 2395 | strControl = "choice=" + strControl; | ||
| 2396 | product.vOrderForm.push_back(make_pair(strLabel, strControl)); | ||
| 2397 | } | ||
| 2398 | } | ||
| 2399 | } | ||
| 2400 | |||
| 2401 | |||
| 2402 | |||
| 2403 | |||
| 2404 | |||
| 2405 | |||
| 2406 | |||
| 2407 | ////////////////////////////////////////////////////////////////////////////// | ||
| 2408 | // | ||
| 2409 | // CViewProductDialog | ||
| 2410 | // | ||
| 2411 | |||
| 2412 | CViewProductDialog::CViewProductDialog(wxWindow* parent, const CProduct& productIn) : CViewProductDialogBase(parent) | ||
| 2413 | { | ||
| 2414 | Connect(wxEVT_REPLY1, wxCommandEventHandler(CViewProductDialog::OnReply1), NULL, this); | ||
| 2415 | AddCallbackAvailable(GetEventHandler()); | ||
| 2416 | |||
| 2417 | // Fill display with product summary while waiting for details | ||
| 2418 | product = productIn; | ||
| 2419 | UpdateProductDisplay(false); | ||
| 2420 | |||
| 2421 | m_buttonBack->Enable(false); | ||
| 2422 | m_buttonNext->Enable(!product.vOrderForm.empty()); | ||
| 2423 | m_htmlWinReviews->Show(true); | ||
| 2424 | m_scrolledWindow->Show(false); | ||
| 2425 | this->Layout(); | ||
| 2426 | |||
| 2427 | // Request details from seller | ||
| 2428 | _beginthread(ThreadRequestProductDetails, 0, new pair<CProduct, wxEvtHandler*>(product, GetEventHandler())); | ||
| 2429 | } | ||
| 2430 | |||
| 2431 | CViewProductDialog::~CViewProductDialog() | ||
| 2432 | { | ||
| 2433 | RemoveCallbackAvailable(GetEventHandler()); | ||
| 2434 | } | ||
| 2435 | |||
| 2436 | void ThreadRequestProductDetails(void* parg) | ||
| 2437 | { | ||
| 2438 | // Extract parameters | ||
| 2439 | pair<CProduct, wxEvtHandler*>* pitem = (pair<CProduct, wxEvtHandler*>*)parg; | ||
| 2440 | CProduct product = pitem->first; | ||
| 2441 | wxEvtHandler* pevthandler = pitem->second; | ||
| 2442 | delete pitem; | ||
| 2443 | |||
| 2444 | // Connect to seller | ||
| 2445 | CNode* pnode = ConnectNode(product.addr, 5 * 60); | ||
| 2446 | if (!pnode) | ||
| 2447 | { | ||
| 2448 | CDataStream ssEmpty; | ||
| 2449 | AddPendingReplyEvent1(pevthandler, ssEmpty); | ||
| 2450 | return; | ||
| 2451 | } | ||
| 2452 | |||
| 2453 | // Request detailed product, with response going to OnReply1 via dialog's event handler | ||
| 2454 | pnode->PushRequest("getdetails", product.GetHash(), AddPendingReplyEvent1, (void*)pevthandler); | ||
| 2455 | } | ||
| 2456 | |||
| 2457 | void CViewProductDialog::OnReply1(wxCommandEvent& event) | ||
| 2458 | { | ||
| 2459 | CDataStream ss = GetStreamFromEvent(event); | ||
| 2460 | if (ss.empty()) | ||
| 2461 | { | ||
| 2462 | product.mapValue["description"] = "-- CAN'T CONNECT TO SELLER --\n"; | ||
| 2463 | UpdateProductDisplay(true); | ||
| 2464 | return; | ||
| 2465 | } | ||
| 2466 | |||
| 2467 | int nRet; | ||
| 2468 | CProduct product2; | ||
| 2469 | try | ||
| 2470 | { | ||
| 2471 | ss >> nRet; | ||
| 2472 | if (nRet > 0) | ||
| 2473 | throw false; | ||
| 2474 | ss >> product2; | ||
| 2475 | if (product2.GetHash() != product.GetHash()) | ||
| 2476 | throw false; | ||
| 2477 | if (!product2.CheckSignature()) | ||
| 2478 | throw false; | ||
| 2479 | } | ||
| 2480 | catch (...) | ||
| 2481 | { | ||
| 2482 | product.mapValue["description"] = "-- INVALID RESPONSE --\n"; | ||
| 2483 | UpdateProductDisplay(true); | ||
| 2484 | return; | ||
| 2485 | } | ||
| 2486 | |||
| 2487 | product = product2; | ||
| 2488 | UpdateProductDisplay(true); | ||
| 2489 | } | ||
| 2490 | |||
| 2491 | bool CompareReviewsBestFirst(const CReview* p1, const CReview* p2) | ||
| 2492 | { | ||
| 2493 | return (p1->nAtoms > p2->nAtoms); | ||
| 2494 | } | ||
| 2495 | |||
| 2496 | void CViewProductDialog::UpdateProductDisplay(bool fDetails) | ||
| 2497 | { | ||
| 2498 | // Product and reviews | ||
| 2499 | string strHTML; | ||
| 2500 | strHTML.reserve(4000); | ||
| 2501 | strHTML += "<html>\n" | ||
| 2502 | "<head>\n" | ||
| 2503 | "<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">\n" | ||
| 2504 | "</head>\n" | ||
| 2505 | "<body>\n"; | ||
| 2506 | strHTML += "<b>Category:</b> " + HtmlEscape(product.mapValue["category"]) + "<br>\n"; | ||
| 2507 | strHTML += "<b>Title:</b> " + HtmlEscape(product.mapValue["title"]) + "<br>\n"; | ||
| 2508 | strHTML += "<b>Price:</b> " + HtmlEscape(product.mapValue["price"]) + "<br>\n"; | ||
| 2509 | |||
| 2510 | if (!fDetails) | ||
| 2511 | strHTML += "<b>Loading details...</b><br>\n<br>\n"; | ||
| 2512 | else | ||
| 2513 | strHTML += HtmlEscape(product.mapValue["description"], true) + "<br>\n<br>\n"; | ||
| 2514 | |||
| 2515 | strHTML += "<b>Reviews:</b><br>\n<br>\n"; | ||
| 2516 | |||
| 2517 | if (!product.vchPubKeyFrom.empty()) | ||
| 2518 | { | ||
| 2519 | CReviewDB reviewdb("r"); | ||
| 2520 | |||
| 2521 | // Get reviews | ||
| 2522 | vector<CReview> vReviews; | ||
| 2523 | reviewdb.ReadReviews(product.GetUserHash(), vReviews); | ||
| 2524 | |||
| 2525 | // Get reviewer's number of atoms | ||
| 2526 | vector<CReview*> vSortedReviews; | ||
| 2527 | vSortedReviews.reserve(vReviews.size()); | ||
| 2528 | for (vector<CReview>::reverse_iterator it = vReviews.rbegin(); it != vReviews.rend(); ++it) | ||
| 2529 | { | ||
| 2530 | CReview& review = *it; | ||
| 2531 | CUser user; | ||
| 2532 | reviewdb.ReadUser(review.GetUserHash(), user); | ||
| 2533 | review.nAtoms = user.GetAtomCount(); | ||
| 2534 | vSortedReviews.push_back(&review); | ||
| 2535 | } | ||
| 2536 | |||
| 2537 | reviewdb.Close(); | ||
| 2538 | |||
| 2539 | // Sort | ||
| 2540 | stable_sort(vSortedReviews.begin(), vSortedReviews.end(), CompareReviewsBestFirst); | ||
| 2541 | |||
| 2542 | // Format reviews | ||
| 2543 | foreach(CReview* preview, vSortedReviews) | ||
| 2544 | { | ||
| 2545 | CReview& review = *preview; | ||
| 2546 | int nStars = atoi(review.mapValue["stars"].c_str()); | ||
| 2547 | if (nStars < 1 || nStars > 5) | ||
| 2548 | continue; | ||
| 2549 | |||
| 2550 | strHTML += "<b>" + itostr(nStars) + (nStars == 1 ? " star" : " stars") + "</b>"; | ||
| 2551 | strHTML += " "; | ||
| 2552 | strHTML += DateStr(atoi64(review.mapValue["date"])) + "<br>\n"; | ||
| 2553 | strHTML += HtmlEscape(review.mapValue["review"], true); | ||
| 2554 | strHTML += "<br>\n<br>\n"; | ||
| 2555 | } | ||
| 2556 | } | ||
| 2557 | |||
| 2558 | strHTML += "</body>\n</html>\n"; | ||
| 2559 | |||
| 2560 | // Shrink capacity to fit | ||
| 2561 | string(strHTML.begin(), strHTML.end()).swap(strHTML); | ||
| 2562 | |||
| 2563 | m_htmlWinReviews->SetPage(strHTML); | ||
| 2564 | |||
| 2565 | ///// need to find some other indicator to use so can allow empty order form | ||
| 2566 | if (product.vOrderForm.empty()) | ||
| 2567 | return; | ||
| 2568 | |||
| 2569 | // Order form | ||
| 2570 | m_staticTextInstructions->SetLabel(product.mapValue["instructions"]); | ||
| 2571 | for (int i = 0; i < FIELDS_MAX; i++) | ||
| 2572 | { | ||
| 2573 | m_staticTextLabel[i] = NULL; | ||
| 2574 | m_textCtrlField[i] = NULL; | ||
| 2575 | m_choiceField[i] = NULL; | ||
| 2576 | } | ||
| 2577 | |||
| 2578 | // Construct flexgridsizer | ||
| 2579 | wxBoxSizer* bSizer21 = (wxBoxSizer*)m_scrolledWindow->GetSizer(); | ||
| 2580 | wxFlexGridSizer* fgSizer; | ||
| 2581 | fgSizer = new wxFlexGridSizer(0, 2, 0, 0); | ||
| 2582 | fgSizer->AddGrowableCol(1); | ||
| 2583 | fgSizer->SetFlexibleDirection(wxBOTH); | ||
| 2584 | fgSizer->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); | ||
| 2585 | |||
| 2586 | // Construct order form fields | ||
| 2587 | wxWindow* windowLast = NULL; | ||
| 2588 | for (int i = 0; i < product.vOrderForm.size(); i++) | ||
| 2589 | { | ||
| 2590 | string strLabel = product.vOrderForm[i].first; | ||
| 2591 | string strControl = product.vOrderForm[i].second; | ||
| 2592 | |||
| 2593 | if (strLabel.size() < 20) | ||
| 2594 | strLabel.insert(strLabel.begin(), 20 - strLabel.size(), ' '); | ||
| 2595 | |||
| 2596 | m_staticTextLabel[i] = new wxStaticText(m_scrolledWindow, wxID_ANY, strLabel, wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); | ||
| 2597 | m_staticTextLabel[i]->Wrap(-1); | ||
| 2598 | fgSizer->Add(m_staticTextLabel[i], 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5); | ||
| 2599 | |||
| 2600 | if (strControl.substr(0, 5) == "text=") | ||
| 2601 | { | ||
| 2602 | m_textCtrlField[i] = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); | ||
| 2603 | fgSizer->Add(m_textCtrlField[i], 1, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5); | ||
| 2604 | windowLast = m_textCtrlField[i]; | ||
| 2605 | } | ||
| 2606 | else if (strControl.substr(0, 7) == "choice=") | ||
| 2607 | { | ||
| 2608 | vector<string> vChoices; | ||
| 2609 | ParseString(strControl.substr(7), ',', vChoices); | ||
| 2610 | |||
| 2611 | wxArrayString arraystring; | ||
| 2612 | foreach(const string& str, vChoices) | ||
| 2613 | arraystring.Add(str); | ||
| 2614 | |||
| 2615 | m_choiceField[i] = new wxChoice(m_scrolledWindow, wxID_ANY, wxDefaultPosition, wxDefaultSize, arraystring, 0); | ||
| 2616 | fgSizer->Add(m_choiceField[i], 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); | ||
| 2617 | windowLast = m_choiceField[i]; | ||
| 2618 | } | ||
| 2619 | else | ||
| 2620 | { | ||
| 2621 | m_textCtrlField[i] = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); | ||
| 2622 | fgSizer->Add(m_textCtrlField[i], 1, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5); | ||
| 2623 | m_staticTextLabel[i]->Show(false); | ||
| 2624 | m_textCtrlField[i]->Show(false); | ||
| 2625 | } | ||
| 2626 | } | ||
| 2627 | |||
| 2628 | // Insert after instructions and before submit/cancel buttons | ||
| 2629 | bSizer21->Insert(2, fgSizer, 0, wxEXPAND|wxRIGHT|wxLEFT, 5); | ||
| 2630 | m_scrolledWindow->Layout(); | ||
| 2631 | bSizer21->Fit(m_scrolledWindow); | ||
| 2632 | this->Layout(); | ||
| 2633 | |||
| 2634 | // Fixup the tab order | ||
| 2635 | m_buttonSubmitForm->MoveAfterInTabOrder(windowLast); | ||
| 2636 | m_buttonCancelForm->MoveAfterInTabOrder(m_buttonSubmitForm); | ||
| 2637 | //m_buttonBack->MoveAfterInTabOrder(m_buttonCancelForm); | ||
| 2638 | //m_buttonNext->MoveAfterInTabOrder(m_buttonBack); | ||
| 2639 | //m_buttonCancel->MoveAfterInTabOrder(m_buttonNext); | ||
| 2640 | this->Layout(); | ||
| 2641 | } | ||
| 2642 | |||
| 2643 | void CViewProductDialog::GetOrder(CWalletTx& wtx) | ||
| 2644 | { | ||
| 2645 | wtx.SetNull(); | ||
| 2646 | for (int i = 0; i < product.vOrderForm.size(); i++) | ||
| 2647 | { | ||
| 2648 | string strValue; | ||
| 2649 | if (m_textCtrlField[i]) | ||
| 2650 | strValue = m_textCtrlField[i]->GetValue().Trim(); | ||
| 2651 | else | ||
| 2652 | strValue = m_choiceField[i]->GetStringSelection(); | ||
| 2653 | wtx.vOrderForm.push_back(make_pair(m_staticTextLabel[i]->GetLabel(), strValue)); | ||
| 2654 | } | ||
| 2655 | } | ||
| 2656 | |||
| 2657 | void CViewProductDialog::OnButtonSubmitForm(wxCommandEvent& event) | ||
| 2658 | { | ||
| 2659 | m_buttonSubmitForm->Enable(false); | ||
| 2660 | m_buttonCancelForm->Enable(false); | ||
| 2661 | |||
| 2662 | CWalletTx wtx; | ||
| 2663 | GetOrder(wtx); | ||
| 2664 | |||
| 2665 | CSendingDialog* pdialog = new CSendingDialog(this, product.addr, atoi64(product.mapValue["price"]), wtx); | ||
| 2666 | if (!pdialog->ShowModal()) | ||
| 2667 | { | ||
| 2668 | m_buttonSubmitForm->Enable(true); | ||
| 2669 | m_buttonCancelForm->Enable(true); | ||
| 2670 | return; | ||
| 2671 | } | ||
| 2672 | } | ||
| 2673 | |||
| 2674 | void CViewProductDialog::OnButtonCancelForm(wxCommandEvent& event) | ||
| 2675 | { | ||
| 2676 | Destroy(); | ||
| 2677 | } | ||
| 2678 | |||
| 2679 | void CViewProductDialog::OnButtonBack(wxCommandEvent& event) | ||
| 2680 | { | ||
| 2681 | Freeze(); | ||
| 2682 | m_htmlWinReviews->Show(true); | ||
| 2683 | m_scrolledWindow->Show(false); | ||
| 2684 | m_buttonBack->Enable(false); | ||
| 2685 | m_buttonNext->Enable(!product.vOrderForm.empty()); | ||
| 2686 | this->Layout(); | ||
| 2687 | Thaw(); | ||
| 2688 | } | ||
| 2689 | |||
| 2690 | void CViewProductDialog::OnButtonNext(wxCommandEvent& event) | ||
| 2691 | { | ||
| 2692 | if (!product.vOrderForm.empty()) | ||
| 2693 | { | ||
| 2694 | Freeze(); | ||
| 2695 | m_htmlWinReviews->Show(false); | ||
| 2696 | m_scrolledWindow->Show(true); | ||
| 2697 | m_buttonBack->Enable(true); | ||
| 2698 | m_buttonNext->Enable(false); | ||
| 2699 | this->Layout(); | ||
| 2700 | Thaw(); | ||
| 2701 | } | ||
| 2702 | } | ||
| 2703 | |||
| 2704 | void CViewProductDialog::OnButtonCancel(wxCommandEvent& event) | ||
| 2705 | { | ||
| 2706 | Destroy(); | ||
| 2707 | } | ||
| 2708 | |||
| 2709 | |||
| 2710 | |||
| 2711 | |||
| 2712 | |||
| 2713 | |||
| 2714 | |||
| 2715 | ////////////////////////////////////////////////////////////////////////////// | ||
| 2716 | // | ||
| 2717 | // CViewOrderDialog | ||
| 2718 | // | ||
| 2719 | |||
| 2720 | CViewOrderDialog::CViewOrderDialog(wxWindow* parent, CWalletTx order, bool fReceived) : CViewOrderDialogBase(parent) | ||
| 2721 | { | ||
| 2722 | int64 nPrice = (fReceived ? order.GetCredit() : order.GetDebit()); | ||
| 2723 | |||
| 2724 | string strHTML; | ||
| 2725 | strHTML.reserve(4000); | ||
| 2726 | strHTML += "<html>\n" | ||
| 2727 | "<head>\n" | ||
| 2728 | "<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">\n" | ||
| 2729 | "</head>\n" | ||
| 2730 | "<body>\n"; | ||
| 2731 | strHTML += "<b>Time:</b> " + HtmlEscape(DateTimeStr(order.nTimeReceived)) + "<br>\n"; | ||
| 2732 | strHTML += "<b>Price:</b> " + HtmlEscape(FormatMoney(nPrice)) + "<br>\n"; | ||
| 2733 | strHTML += "<b>Status:</b> " + HtmlEscape(FormatTxStatus(order)) + "<br>\n"; | ||
| 2734 | |||
| 2735 | strHTML += "<table>\n"; | ||
| 2736 | for (int i = 0; i < order.vOrderForm.size(); i++) | ||
| 2737 | { | ||
| 2738 | strHTML += " <tr><td><b>" + HtmlEscape(order.vOrderForm[i].first) + ":</b></td>"; | ||
| 2739 | strHTML += "<td>" + HtmlEscape(order.vOrderForm[i].second) + "</td></tr>\n"; | ||
| 2740 | } | ||
| 2741 | strHTML += "</table>\n"; | ||
| 2742 | |||
| 2743 | strHTML += "</body>\n</html>\n"; | ||
| 2744 | |||
| 2745 | // Shrink capacity to fit | ||
| 2746 | // (strings are ref counted, so it may live on in SetPage) | ||
| 2747 | string(strHTML.begin(), strHTML.end()).swap(strHTML); | ||
| 2748 | |||
| 2749 | m_htmlWin->SetPage(strHTML); | ||
| 2750 | } | ||
| 2751 | |||
| 2752 | void CViewOrderDialog::OnButtonOK(wxCommandEvent& event) | ||
| 2753 | { | ||
| 2754 | Destroy(); | ||
| 2755 | } | ||
| 2756 | |||
| 2757 | |||
| 2758 | |||
| 2759 | |||
| 2760 | |||
| 2761 | |||
| 2762 | |||
| 2763 | ////////////////////////////////////////////////////////////////////////////// | ||
| 2764 | // | ||
| 2765 | // CEditReviewDialog | ||
| 2766 | // | ||
| 2767 | |||
| 2768 | CEditReviewDialog::CEditReviewDialog(wxWindow* parent) : CEditReviewDialogBase(parent) | ||
| 2769 | { | ||
| 2770 | } | ||
| 2771 | |||
| 2772 | void CEditReviewDialog::OnButtonSubmit(wxCommandEvent& event) | ||
| 2773 | { | ||
| 2774 | if (m_choiceStars->GetSelection() == -1) | ||
| 2775 | { | ||
| 2776 | wxMessageBox("Please select a rating "); | ||
| 2777 | return; | ||
| 2778 | } | ||
| 2779 | |||
| 2780 | CReview review; | ||
| 2781 | GetReview(review); | ||
| 2782 | |||
| 2783 | // Sign the review | ||
| 2784 | review.vchPubKeyFrom = keyUser.GetPubKey(); | ||
| 2785 | if (!keyUser.Sign(review.GetSigHash(), review.vchSig)) | ||
| 2786 | { | ||
| 2787 | wxMessageBox("Unable to digitally sign the review "); | ||
| 2788 | return; | ||
| 2789 | } | ||
| 2790 | |||
| 2791 | // Broadcast | ||
| 2792 | if (!review.AcceptReview()) | ||
| 2793 | { | ||
| 2794 | wxMessageBox("Save failed "); | ||
| 2795 | return; | ||
| 2796 | } | ||
| 2797 | RelayMessage(CInv(MSG_REVIEW, review.GetHash()), review); | ||
| 2798 | |||
| 2799 | Destroy(); | ||
| 2800 | } | ||
| 2801 | |||
| 2802 | void CEditReviewDialog::OnButtonCancel(wxCommandEvent& event) | ||
| 2803 | { | ||
| 2804 | Destroy(); | ||
| 2805 | } | ||
| 2806 | |||
| 2807 | void CEditReviewDialog::GetReview(CReview& review) | ||
| 2808 | { | ||
| 2809 | review.mapValue["time"] = i64tostr(GetAdjustedTime()); | ||
| 2810 | review.mapValue["stars"] = itostr(m_choiceStars->GetSelection()+1); | ||
| 2811 | review.mapValue["review"] = m_textCtrlReview->GetValue(); | ||
| 2812 | } | ||
| 2813 | |||
| 2814 | |||
| 2815 | |||
| 2816 | |||
| 2817 | |||
| 2818 | |||
| 2819 | |||
| 2820 | |||
| 2821 | |||
| 2822 | |||
| 2823 | |||
| 2824 | |||
| 2825 | ////////////////////////////////////////////////////////////////////////////// | ||
| 2826 | // | ||
| 2827 | // CMyApp | ||
| 2828 | // | ||
| 2829 | |||
| 2830 | // Define a new application | ||
| 2831 | class CMyApp: public wxApp | ||
| 2832 | { | ||
| 2833 | public: | ||
| 2834 | CMyApp(){}; | ||
| 2835 | ~CMyApp(){}; | ||
| 2836 | bool OnInit(); | ||
| 2837 | bool OnInit2(); | ||
| 2838 | int OnExit(); | ||
| 2839 | |||
| 2840 | // The MSYS2 release wxWidgets DLLs ship with asserts enabled. Log any | ||
| 2841 | // assertion to debug.log instead of showing a modal "Debug Alert" popup, | ||
| 2842 | // so the packaged build runs cleanly by double-click. | ||
| 2843 | virtual void OnAssertFailure(const wxChar* file, int line, const wxChar* func, | ||
| 2844 | const wxChar* cond, const wxChar* msg) | ||
| 2845 | { | ||
| 2846 | printf("wxAssert: %s(%d) %s: %s %s\n", | ||
| 2847 | (const char*)wxString(file).mb_str(), line, | ||
| 2848 | (const char*)wxString(func).mb_str(), | ||
| 2849 | (const char*)wxString(cond).mb_str(), | ||
| 2850 | (const char*)wxString(msg).mb_str()); | ||
| 2851 | } | ||
| 2852 | |||
| 2853 | // 2nd-level exception handling: we get all the exceptions occurring in any | ||
| 2854 | // event handler here | ||
| 2855 | virtual bool OnExceptionInMainLoop(); | ||
| 2856 | |||
| 2857 | // 3rd, and final, level exception handling: whenever an unhandled | ||
| 2858 | // exception is caught, this function is called | ||
| 2859 | virtual void OnUnhandledException(); | ||
| 2860 | |||
| 2861 | // and now for something different: this function is called in case of a | ||
| 2862 | // crash (e.g. dereferencing null pointer, division by 0, ...) | ||
| 2863 | virtual void OnFatalException(); | ||
| 2864 | }; | ||
| 2865 | |||
| 2866 | IMPLEMENT_APP(CMyApp) | ||
| 2867 | |||
| 2868 | bool CMyApp::OnInit() | ||
| 2869 | { | ||
| 2870 | // The 2009 wxFormBuilder layout mixes wxEXPAND with alignment flags, which | ||
| 2871 | // modern wxWidgets flags as an assertion. Disable those sizer consistency | ||
| 2872 | // checks globally so no "Debug Alert" popup ever blocks the UI. | ||
| 2873 | wxSizerFlags::DisableConsistencyChecks(); | ||
| 2874 | try | ||
| 2875 | { | ||
| 2876 | return OnInit2(); | ||
| 2877 | } | ||
| 2878 | catch (std::exception& e) { | ||
| 2879 | PrintException(&e, "OnInit()"); | ||
| 2880 | } catch (...) { | ||
| 2881 | PrintException(NULL, "OnInit()"); | ||
| 2882 | } | ||
| 2883 | return false; | ||
| 2884 | } | ||
| 2885 | |||
| 2886 | map<string, string> ParseParameters(int argc, char* argv[]) | ||
| 2887 | { | ||
| 2888 | map<string, string> mapArgs; | ||
| 2889 | for (int i = 0; i < argc; i++) | ||
| 2890 | { | ||
| 2891 | char psz[10000]; | ||
| 2892 | strcpy(psz, argv[i]); | ||
| 2893 | char* pszValue = ""; | ||
| 2894 | if (strchr(psz, '=')) | ||
| 2895 | { | ||
| 2896 | pszValue = strchr(psz, '='); | ||
| 2897 | *pszValue++ = '\0'; | ||
| 2898 | } | ||
| 2899 | strlwr(psz); | ||
| 2900 | if (psz[0] == '-') | ||
| 2901 | psz[0] = '/'; | ||
| 2902 | mapArgs[psz] = pszValue; | ||
| 2903 | } | ||
| 2904 | return mapArgs; | ||
| 2905 | } | ||
| 2906 | |||
| 2907 | bool CMyApp::OnInit2() | ||
| 2908 | { | ||
| 2909 | #ifdef _MSC_VER | ||
| 2910 | // Turn off microsoft heap dump noise for now | ||
| 2911 | _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); | ||
| 2912 | _CrtSetReportFile(_CRT_WARN, CreateFile("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0)); | ||
| 2913 | #endif | ||
| 2914 | |||
| 2915 | //// debug print | ||
| 2916 | printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); | ||
| 2917 | printf("Bitcoin CMyApp::OnInit()\n"); | ||
| 2918 | |||
| 2919 | // | ||
| 2920 | // Parameters (parsed before the lock so /datadir and /port feed the mutex) | ||
| 2921 | // | ||
| 2922 | wxImage::AddHandler(new wxPNGHandler); | ||
| 2923 | map<string, string> mapArgs = ParseParameters(argc, argv); | ||
| 2924 | |||
| 2925 | if (mapArgs.count("/datadir")) | ||
| 2926 | strSetDataDir = mapArgs["/datadir"]; | ||
| 2927 | |||
| 2928 | if (mapArgs.count("/port")) | ||
| 2929 | nListenPort = htons(atoi(mapArgs["/port"].c_str())); | ||
| 2930 | |||
| 2931 | // | ||
| 2932 | // Limit to single instance per user/datadir | ||
| 2933 | // The mutex includes the datadir to allow multiple nodes on one machine. | ||
| 2934 | // | ||
| 2935 | const char* pszHomePath = getenv("HOMEPATH"); | ||
| 2936 | wxString strMutexName = wxString("Bitflash.") + (pszHomePath ? pszHomePath : "default") + "." + strSetDataDir.c_str(); | ||
| 2937 | for (int i = 0; i < strMutexName.size(); i++) | ||
| 2938 | if (!isalnum(strMutexName[i])) | ||
| 2939 | strMutexName[i] = '.'; | ||
| 2940 | wxSingleInstanceChecker* psingleinstancechecker = new wxSingleInstanceChecker(strMutexName); | ||
| 2941 | if (psingleinstancechecker->IsAnotherRunning()) | ||
| 2942 | { | ||
| 2943 | printf("Existing instance found\n"); | ||
| 2944 | unsigned int nStart = GetTime(); | ||
| 2945 | loop | ||
| 2946 | { | ||
| 2947 | // Show the previous instance and exit | ||
| 2948 | HWND hwndPrev = FindWindow("wxWindowClassNR", "Bitflash"); | ||
| 2949 | if (hwndPrev) | ||
| 2950 | { | ||
| 2951 | if (IsIconic(hwndPrev)) | ||
| 2952 | ShowWindow(hwndPrev, SW_RESTORE); | ||
| 2953 | SetForegroundWindow(hwndPrev); | ||
| 2954 | return false; | ||
| 2955 | } | ||
| 2956 | |||
| 2957 | if (GetTime() > nStart + 60) | ||
| 2958 | return false; | ||
| 2959 | |||
| 2960 | // Resume this instance if the other exits | ||
| 2961 | delete psingleinstancechecker; | ||
| 2962 | Sleep(1000); | ||
| 2963 | psingleinstancechecker = new wxSingleInstanceChecker(strMutexName); | ||
| 2964 | if (!psingleinstancechecker->IsAnotherRunning()) | ||
| 2965 | break; | ||
| 2966 | } | ||
| 2967 | } | ||
| 2968 | |||
| 2969 | if (mapArgs.count("/proxy")) | ||
| 2970 | addrProxy = CAddress(mapArgs["/proxy"].c_str()); | ||
| 2971 | |||
| 2972 | // Rendezvous meeting relay this node registers its .btf service at and | ||
| 2973 | // advertises in its descriptor (default is the seed relay; empty disables). | ||
| 2974 | if (mapArgs.count("/rvrelay")) | ||
| 2975 | strBtfMeetingRelay = mapArgs["/rvrelay"]; | ||
| 2976 | |||
| 2977 | // Keep an anonymous outbound connection to a specific .btf peer. | ||
| 2978 | if (mapArgs.count("/connectbtf")) | ||
| 2979 | strBtfConnect = mapArgs["/connectbtf"]; | ||
| 2980 | |||
| 2981 | if (mapArgs.count("/debug")) | ||
| 2982 | fDebug = true; | ||
| 2983 | |||
| 2984 | if (mapArgs.count("/dropmessages")) | ||
| 2985 | { | ||
| 2986 | nDropMessagesTest = atoi(mapArgs["/dropmessages"]); | ||
| 2987 | if (nDropMessagesTest == 0) | ||
| 2988 | nDropMessagesTest = 20; | ||
| 2989 | } | ||
| 2990 | |||
| 2991 | if (mapArgs.count("/loadblockindextest")) | ||
| 2992 | { | ||
| 2993 | CTxDB txdb("r"); | ||
| 2994 | txdb.LoadBlockIndex(); | ||
| 2995 | PrintBlockTree(); | ||
| 2996 | ExitProcess(0); | ||
| 2997 | } | ||
| 2998 | |||
| 2999 | // | ||
| 3000 | // Load data files | ||
| 3001 | // | ||
| 3002 | string strErrors; | ||
| 3003 | int64 nStart, nEnd; | ||
| 3004 | |||
| 3005 | printf("Loading addresses...\n"); | ||
| 3006 | QueryPerformanceCounter((LARGE_INTEGER*)&nStart); | ||
| 3007 | if (!LoadAddresses()) | ||
| 3008 | strErrors += "Error loading addr.dat \n"; | ||
| 3009 | QueryPerformanceCounter((LARGE_INTEGER*)&nEnd); | ||
| 3010 | printf(" addresses %20I64d\n", nEnd - nStart); | ||
| 3011 | |||
| 3012 | printf("Loading block index...\n"); | ||
| 3013 | QueryPerformanceCounter((LARGE_INTEGER*)&nStart); | ||
| 3014 | if (!LoadBlockIndex()) | ||
| 3015 | strErrors += "Error loading blkindex.dat \n"; | ||
| 3016 | QueryPerformanceCounter((LARGE_INTEGER*)&nEnd); | ||
| 3017 | printf(" block index %20I64d\n", nEnd - nStart); | ||
| 3018 | |||
| 3019 | printf("Loading wallet...\n"); | ||
| 3020 | QueryPerformanceCounter((LARGE_INTEGER*)&nStart); | ||
| 3021 | if (!LoadWallet()) | ||
| 3022 | strErrors += "Error loading wallet.dat \n"; | ||
| 3023 | QueryPerformanceCounter((LARGE_INTEGER*)&nEnd); | ||
| 3024 | printf(" wallet %20I64d\n", nEnd - nStart); | ||
| 3025 | |||
| 3026 | printf("Done loading\n"); | ||
| 3027 | |||
| 3028 | //// debug print | ||
| 3029 | printf("mapBlockIndex.size() = %d\n", mapBlockIndex.size()); | ||
| 3030 | printf("nBestHeight = %d\n", nBestHeight); | ||
| 3031 | printf("mapKeys.size() = %d\n", mapKeys.size()); | ||
| 3032 | printf("mapPubKeys.size() = %d\n", mapPubKeys.size()); | ||
| 3033 | printf("mapWallet.size() = %d\n", mapWallet.size()); | ||
| 3034 | printf("mapAddressBook.size() = %d\n", mapAddressBook.size()); | ||
| 3035 | |||
| 3036 | if (!strErrors.empty()) | ||
| 3037 | { | ||
| 3038 | wxMessageBox(strErrors); | ||
| 3039 | OnExit(); | ||
| 3040 | return false; | ||
| 3041 | } | ||
| 3042 | |||
| 3043 | // Add wallet transactions that aren't already in a block to mapTransactions | ||
| 3044 | ReacceptWalletTransactions(); | ||
| 3045 | |||
| 3046 | // | ||
| 3047 | // Parameters | ||
| 3048 | // | ||
| 3049 | if (mapArgs.count("/printblockindex") || mapArgs.count("/printblocktree")) | ||
| 3050 | { | ||
| 3051 | PrintBlockTree(); | ||
| 3052 | OnExit(); | ||
| 3053 | return false; | ||
| 3054 | } | ||
| 3055 | |||
| 3056 | if (mapArgs.count("/solomine")) | ||
| 3057 | fSoloMineTest = true; | ||
| 3058 | |||
| 3059 | if (mapArgs.count("/gen")) | ||
| 3060 | { | ||
| 3061 | if (mapArgs["/gen"].empty()) | ||
| 3062 | fGenerateBitcoins = true; | ||
| 3063 | else | ||
| 3064 | fGenerateBitcoins = atoi(mapArgs["/gen"].c_str()); | ||
| 3065 | } | ||
| 3066 | |||
| 3067 | // | ||
| 3068 | // Create the main frame window | ||
| 3069 | // | ||
| 3070 | { | ||
| 3071 | pframeMain = new CMainFrame(NULL); | ||
| 3072 | pframeMain->Show(); | ||
| 3073 | |||
| 3074 | if (!StartNode(strErrors)) | ||
| 3075 | wxMessageBox(strErrors); | ||
| 3076 | |||
| 3077 | if (fGenerateBitcoins) | ||
| 3078 | if (_beginthread(ThreadBitcoinMiner, 0, NULL) == -1) | ||
| 3079 | printf("Error: _beginthread(ThreadBitcoinMiner) failed\n"); | ||
| 3080 | |||
| 3081 | // | ||
| 3082 | // Tests | ||
| 3083 | // | ||
| 3084 | if (argc >= 2 && wxString(argv[1]).CmpNoCase("/send") == 0) | ||
| 3085 | { | ||
| 3086 | int64 nValue = 1; | ||
| 3087 | if (argc >= 3) | ||
| 3088 | ParseMoney(argv[2], nValue); | ||
| 3089 | |||
| 3090 | string strAddress; | ||
| 3091 | if (argc >= 4) | ||
| 3092 | strAddress = argv[3]; | ||
| 3093 | CAddress addr(strAddress.c_str()); | ||
| 3094 | |||
| 3095 | CWalletTx wtx; | ||
| 3096 | wtx.mapValue["to"] = strAddress; | ||
| 3097 | wtx.mapValue["from"] = addrLocalHost.ToString(); | ||
| 3098 | wtx.mapValue["message"] = "command line send"; | ||
| 3099 | |||
| 3100 | // Send to IP address | ||
| 3101 | CSendingDialog* pdialog = new CSendingDialog(pframeMain, addr, nValue, wtx); | ||
| 3102 | if (!pdialog->ShowModal()) | ||
| 3103 | return false; | ||
| 3104 | } | ||
| 3105 | |||
| 3106 | if (mapArgs.count("/randsendtest")) | ||
| 3107 | { | ||
| 3108 | if (!mapArgs["/randsendtest"].empty()) | ||
| 3109 | _beginthread(ThreadRandSendTest, 0, new string(mapArgs["/randsendtest"])); | ||
| 3110 | else | ||
| 3111 | fRandSendTest = true; | ||
| 3112 | fDebug = true; | ||
| 3113 | } | ||
| 3114 | } | ||
| 3115 | |||
| 3116 | return true; | ||
| 3117 | } | ||
| 3118 | |||
| 3119 | int CMyApp::OnExit() | ||
| 3120 | { | ||
| 3121 | Shutdown(NULL); | ||
| 3122 | return wxApp::OnExit(); | ||
| 3123 | } | ||
| 3124 | |||
| 3125 | bool CMyApp::OnExceptionInMainLoop() | ||
| 3126 | { | ||
| 3127 | try | ||
| 3128 | { | ||
| 3129 | throw; | ||
| 3130 | } | ||
| 3131 | catch (std::exception& e) | ||
| 3132 | { | ||
| 3133 | PrintException(&e, "CMyApp::OnExceptionInMainLoop()"); | ||
| 3134 | wxLogWarning(_T("Exception %s %s"), typeid(e).name(), e.what()); | ||
| 3135 | Sleep(1000); | ||
| 3136 | throw; | ||
| 3137 | } | ||
| 3138 | catch (...) | ||
| 3139 | { | ||
| 3140 | PrintException(NULL, "CMyApp::OnExceptionInMainLoop()"); | ||
| 3141 | wxLogWarning(_T("Unknown exception")); | ||
| 3142 | Sleep(1000); | ||
| 3143 | throw; | ||
| 3144 | } | ||
| 3145 | |||
| 3146 | return true; | ||
| 3147 | } | ||
| 3148 | |||
| 3149 | void CMyApp::OnUnhandledException() | ||
| 3150 | { | ||
| 3151 | // this shows how we may let some exception propagate uncaught | ||
| 3152 | try | ||
| 3153 | { | ||
| 3154 | throw; | ||
| 3155 | } | ||
| 3156 | catch (std::exception& e) | ||
| 3157 | { | ||
| 3158 | PrintException(&e, "CMyApp::OnUnhandledException()"); | ||
| 3159 | wxLogWarning(_T("Exception %s %s"), typeid(e).name(), e.what()); | ||
| 3160 | Sleep(1000); | ||
| 3161 | throw; | ||
| 3162 | } | ||
| 3163 | catch (...) | ||
| 3164 | { | ||
| 3165 | PrintException(NULL, "CMyApp::OnUnhandledException()"); | ||
| 3166 | wxLogWarning(_T("Unknown exception")); | ||
| 3167 | Sleep(1000); | ||
| 3168 | throw; | ||
| 3169 | } | ||
| 3170 | } | ||
| 3171 | |||
| 3172 | void CMyApp::OnFatalException() | ||
| 3173 | { | ||
| 3174 | wxMessageBox("Program has crashed and will terminate. ", "", wxOK | wxICON_ERROR); | ||
| 3175 | } | ||
| 3176 | |||
| 3177 | |||
| 3178 | |||
| 3179 | void MainFrameRepaint() | ||
| 3180 | { | ||
| 3181 | if (pframeMain) | ||
| 3182 | { | ||
| 3183 | printf("MainFrameRepaint()\n"); | ||
| 3184 | // Called from worker threads: repaint only on the GUI thread | ||
| 3185 | wxTheApp->CallAfter([] { if (pframeMain) pframeMain->Refresh(); }); | ||
| 3186 | } | ||
| 3187 | } | ||
| 3188 | |||
| 3189 | |||
| 3190 | |||
| 3191 | |||
| 3192 | |||
| 3193 | |||
| 3194 | |||
| 3195 | // randsendtest to bitcoin address | ||
| 3196 | void ThreadRandSendTest(void* parg) | ||
| 3197 | { | ||
| 3198 | string strAddress = *(string*)parg; | ||
| 3199 | uint160 hash160; | ||
| 3200 | if (!AddressToHash160(strAddress, hash160)) | ||
| 3201 | { | ||
| 3202 | wxMessageBox(strprintf("ThreadRandSendTest: Bitcoin address '%s' not valid ", strAddress.c_str())); | ||
| 3203 | return; | ||
| 3204 | } | ||
| 3205 | |||
| 3206 | loop | ||
| 3207 | { | ||
| 3208 | Sleep(GetRand(30) * 1000 + 100); | ||
| 3209 | |||
| 3210 | // Message | ||
| 3211 | CWalletTx wtx; | ||
| 3212 | wtx.mapValue["to"] = strAddress; | ||
| 3213 | wtx.mapValue["from"] = addrLocalHost.ToString(); | ||
| 3214 | static int nRep; | ||
| 3215 | wtx.mapValue["message"] = strprintf("randsendtest %d\n", ++nRep); | ||
| 3216 | |||
| 3217 | // Value | ||
| 3218 | int64 nValue = (GetRand(9) + 1) * 100 * CENT; | ||
| 3219 | if (GetBalance() < nValue) | ||
| 3220 | { | ||
| 3221 | wxMessageBox("Out of money "); | ||
| 3222 | return; | ||
| 3223 | } | ||
| 3224 | nValue += (nRep % 100) * CENT; | ||
| 3225 | |||
| 3226 | // Send to bitcoin address | ||
| 3227 | CScript scriptPubKey; | ||
| 3228 | scriptPubKey << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG; | ||
| 3229 | |||
| 3230 | if (!SendMoney(scriptPubKey, nValue, wtx)) | ||
| 3231 | return; | ||
| 3232 | } | ||
| 3233 | } | ||
| 3234 | |||
| 3235 | |||
| 3236 | // randsendtest to any connected node | ||
| 3237 | void RandSend() | ||
| 3238 | { | ||
| 3239 | CWalletTx wtx; | ||
| 3240 | |||
| 3241 | while (vNodes.empty()) | ||
| 3242 | Sleep(1000); | ||
| 3243 | CAddress addr; | ||
| 3244 | CRITICAL_BLOCK(cs_vNodes) | ||
| 3245 | addr = vNodes[GetRand(vNodes.size())]->addr; | ||
| 3246 | |||
| 3247 | // Message | ||
| 3248 | wtx.mapValue["to"] = addr.ToString(); | ||
| 3249 | wtx.mapValue["from"] = addrLocalHost.ToString(); | ||
| 3250 | static int nRep; | ||
| 3251 | wtx.mapValue["message"] = strprintf("randsendtest %d\n", ++nRep); | ||
| 3252 | |||
| 3253 | // Value | ||
| 3254 | int64 nValue = (GetRand(999) + 1) * CENT; | ||
| 3255 | if (GetBalance() < nValue) | ||
| 3256 | { | ||
| 3257 | wxMessageBox("Out of money "); | ||
| 3258 | return; | ||
| 3259 | } | ||
| 3260 | |||
| 3261 | // Send to IP address | ||
| 3262 | CSendingDialog* pdialog = new CSendingDialog(pframeMain, addr, nValue, wtx); | ||
| 3263 | if (!pdialog->Show()) | ||
| 3264 | wxMessageBox("ShowModal Failed "); | ||
| 3265 | } | ||
diff --git a/src/ui.h b/src/ui.h new file mode 100644 index 0000000..2efeace --- /dev/null +++ b/src/ui.h | |||
| @@ -0,0 +1,417 @@ | |||
| 1 | // Copyright (c) 2009 Satoshi Nakamoto | ||
| 2 | // Distributed under the MIT/X11 software license, see the accompanying | ||
| 3 | // file license.txt or http://www.opensource.org/licenses/mit-license.php. | ||
| 4 | |||
| 5 | |||
| 6 | |||
| 7 | |||
| 8 | DECLARE_EVENT_TYPE(wxEVT_CROSSTHREADCALL, -1) | ||
| 9 | DECLARE_EVENT_TYPE(wxEVT_REPLY1, -1) | ||
| 10 | DECLARE_EVENT_TYPE(wxEVT_REPLY2, -1) | ||
| 11 | DECLARE_EVENT_TYPE(wxEVT_REPLY3, -1) | ||
| 12 | DECLARE_EVENT_TYPE(wxEVT_TABLEADDED, -1) | ||
| 13 | DECLARE_EVENT_TYPE(wxEVT_TABLEUPDATED, -1) | ||
| 14 | DECLARE_EVENT_TYPE(wxEVT_TABLEDELETED, -1) | ||
| 15 | |||
| 16 | enum | ||
| 17 | { | ||
| 18 | UICALL_ADDORDER = 1, | ||
| 19 | UICALL_UPDATEORDER, | ||
| 20 | }; | ||
| 21 | |||
| 22 | |||
| 23 | |||
| 24 | extern void HandleCtrlA(wxKeyEvent& event); | ||
| 25 | extern string DateTimeStr(int64 nTime); | ||
| 26 | extern string FormatTxStatus(const CWalletTx& wtx); | ||
| 27 | extern void CrossThreadCall(int nID, void* pdata); | ||
| 28 | extern void MainFrameRepaint(); | ||
| 29 | |||
| 30 | |||
| 31 | |||
| 32 | |||
| 33 | |||
| 34 | |||
| 35 | class CMainFrame : public CMainFrameBase | ||
| 36 | { | ||
| 37 | protected: | ||
| 38 | // Event handlers | ||
| 39 | void OnClose(wxCloseEvent& event); | ||
| 40 | void OnMouseEvents(wxMouseEvent& event); | ||
| 41 | void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); } | ||
| 42 | void OnIdle(wxIdleEvent& event); | ||
| 43 | void OnPaint(wxPaintEvent& event); | ||
| 44 | void OnPaintListCtrl(wxPaintEvent& event); | ||
| 45 | void OnMenuFileExit(wxCommandEvent& event); | ||
| 46 | void OnMenuOptionsGenerate(wxCommandEvent& event); | ||
| 47 | void OnMenuOptionsOptions(wxCommandEvent& event); | ||
| 48 | void OnMenuHelpAbout(wxCommandEvent& event); | ||
| 49 | void OnButtonSend(wxCommandEvent& event); | ||
| 50 | void OnButtonAddressBook(wxCommandEvent& event); | ||
| 51 | void OnSetFocusAddress(wxFocusEvent& event); | ||
| 52 | void OnMouseEventsAddress(wxMouseEvent& event); | ||
| 53 | void OnButtonCopy(wxCommandEvent& event); | ||
| 54 | void OnButtonChange(wxCommandEvent& event); | ||
| 55 | void OnListColBeginDrag(wxListEvent& event); | ||
| 56 | void OnListItemActivatedAllTransactions(wxListEvent& event); | ||
| 57 | void OnListItemActivatedProductsSent(wxListEvent& event); | ||
| 58 | void OnListItemActivatedOrdersSent(wxListEvent& event); | ||
| 59 | void OnListItemActivatedOrdersReceived(wxListEvent& event); | ||
| 60 | |||
| 61 | public: | ||
| 62 | /** Constructor */ | ||
| 63 | CMainFrame(wxWindow* parent); | ||
| 64 | ~CMainFrame(); | ||
| 65 | |||
| 66 | // Custom | ||
| 67 | bool fRefreshListCtrl; | ||
| 68 | bool fRefreshListCtrlRunning; | ||
| 69 | bool fOnSetFocusAddress; | ||
| 70 | CBlockIndex* pindexBestLast; | ||
| 71 | set<uint256> setUnmaturedDisplayed; | ||
| 72 | |||
| 73 | void OnCrossThreadCall(wxCommandEvent& event); | ||
| 74 | void InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSort, const wxString& str1, const wxString& str2, const wxString& str3, const wxString& str4, const wxString& str5); | ||
| 75 | void InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex=-1); | ||
| 76 | void RefreshListCtrl(); | ||
| 77 | void RefreshStatus(); | ||
| 78 | }; | ||
| 79 | |||
| 80 | |||
| 81 | |||
| 82 | |||
| 83 | class CTxDetailsDialog : public CTxDetailsDialogBase | ||
| 84 | { | ||
| 85 | protected: | ||
| 86 | // Event handlers | ||
| 87 | void OnButtonOK(wxCommandEvent& event); | ||
| 88 | |||
| 89 | public: | ||
| 90 | /** Constructor */ | ||
| 91 | CTxDetailsDialog(wxWindow* parent, CWalletTx wtx); | ||
| 92 | |||
| 93 | // State | ||
| 94 | CWalletTx wtx; | ||
| 95 | }; | ||
| 96 | |||
| 97 | |||
| 98 | |||
| 99 | class COptionsDialog : public COptionsDialogBase | ||
| 100 | { | ||
| 101 | protected: | ||
| 102 | // Event handlers | ||
| 103 | void OnKillFocusTransactionFee(wxFocusEvent& event); | ||
| 104 | void OnButtonOK(wxCommandEvent& event); | ||
| 105 | void OnButtonCancel(wxCommandEvent& event); | ||
| 106 | |||
| 107 | public: | ||
| 108 | /** Constructor */ | ||
| 109 | COptionsDialog(wxWindow* parent); | ||
| 110 | }; | ||
| 111 | |||
| 112 | |||
| 113 | |||
| 114 | class CAboutDialog : public CAboutDialogBase | ||
| 115 | { | ||
| 116 | protected: | ||
| 117 | // Event handlers | ||
| 118 | void OnButtonOK(wxCommandEvent& event); | ||
| 119 | |||
| 120 | public: | ||
| 121 | /** Constructor */ | ||
| 122 | CAboutDialog(wxWindow* parent); | ||
| 123 | }; | ||
| 124 | |||
| 125 | |||
| 126 | |||
| 127 | class CSendDialog : public CSendDialogBase | ||
| 128 | { | ||
| 129 | protected: | ||
| 130 | // Event handlers | ||
| 131 | void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); } | ||
| 132 | void OnTextAddress(wxCommandEvent& event); | ||
| 133 | void OnKillFocusAmount(wxFocusEvent& event); | ||
| 134 | void OnButtonAddressBook(wxCommandEvent& event); | ||
| 135 | void OnButtonPaste(wxCommandEvent& event); | ||
| 136 | void OnButtonSend(wxCommandEvent& event); | ||
| 137 | void OnButtonCancel(wxCommandEvent& event); | ||
| 138 | |||
| 139 | public: | ||
| 140 | /** Constructor */ | ||
| 141 | CSendDialog(wxWindow* parent, const wxString& strAddress=""); | ||
| 142 | }; | ||
| 143 | |||
| 144 | |||
| 145 | |||
| 146 | class CSendingDialog : public CSendingDialogBase | ||
| 147 | { | ||
| 148 | public: | ||
| 149 | // Event handlers | ||
| 150 | void OnClose(wxCloseEvent& event); | ||
| 151 | void OnButtonOK(wxCommandEvent& event); | ||
| 152 | void OnButtonCancel(wxCommandEvent& event); | ||
| 153 | void OnPaint(wxPaintEvent& event); | ||
| 154 | |||
| 155 | public: | ||
| 156 | /** Constructor */ | ||
| 157 | CSendingDialog(wxWindow* parent, const CAddress& addrIn, int64 nPriceIn, const CWalletTx& wtxIn); | ||
| 158 | ~CSendingDialog(); | ||
| 159 | |||
| 160 | // State | ||
| 161 | CAddress addr; | ||
| 162 | int64 nPrice; | ||
| 163 | CWalletTx wtx; | ||
| 164 | wxDateTime start; | ||
| 165 | string strStatus; | ||
| 166 | bool fCanCancel; | ||
| 167 | bool fAbort; | ||
| 168 | bool fSuccess; | ||
| 169 | bool fUIDone; | ||
| 170 | bool fWorkDone; | ||
| 171 | |||
| 172 | void Close(); | ||
| 173 | void Repaint(); | ||
| 174 | bool Status(); | ||
| 175 | bool Status(const string& str); | ||
| 176 | bool Error(const string& str); | ||
| 177 | void StartTransfer(); | ||
| 178 | void OnReply2(CDataStream& vRecv); | ||
| 179 | void OnReply3(CDataStream& vRecv); | ||
| 180 | }; | ||
| 181 | |||
| 182 | void SendingDialogStartTransfer(void* parg); | ||
| 183 | void SendingDialogOnReply2(void* parg, CDataStream& vRecv); | ||
| 184 | void SendingDialogOnReply3(void* parg, CDataStream& vRecv); | ||
| 185 | |||
| 186 | |||
| 187 | |||
| 188 | class CYourAddressDialog : public CYourAddressDialogBase | ||
| 189 | { | ||
| 190 | protected: | ||
| 191 | // Event handlers | ||
| 192 | void OnListEndLabelEdit(wxListEvent& event); | ||
| 193 | void OnListItemSelected(wxListEvent& event); | ||
| 194 | void OnListItemActivated(wxListEvent& event); | ||
| 195 | void OnButtonRename(wxCommandEvent& event); | ||
| 196 | void OnButtonNew(wxCommandEvent& event); | ||
| 197 | void OnButtonCopy(wxCommandEvent& event); | ||
| 198 | void OnButtonOK(wxCommandEvent& event); | ||
| 199 | void OnButtonCancel(wxCommandEvent& event); | ||
| 200 | void OnClose(wxCloseEvent& event); | ||
| 201 | |||
| 202 | public: | ||
| 203 | /** Constructor */ | ||
| 204 | CYourAddressDialog(wxWindow* parent); | ||
| 205 | CYourAddressDialog(wxWindow* parent, const string& strInitSelected); | ||
| 206 | |||
| 207 | // Custom | ||
| 208 | wxString GetAddress(); | ||
| 209 | }; | ||
| 210 | |||
| 211 | |||
| 212 | |||
| 213 | class CAddressBookDialog : public CAddressBookDialogBase | ||
| 214 | { | ||
| 215 | protected: | ||
| 216 | // Event handlers | ||
| 217 | void OnListEndLabelEdit(wxListEvent& event); | ||
| 218 | void OnListItemSelected(wxListEvent& event); | ||
| 219 | void OnListItemActivated(wxListEvent& event); | ||
| 220 | void OnButtonEdit(wxCommandEvent& event); | ||
| 221 | void OnButtonDelete(wxCommandEvent& event); | ||
| 222 | void OnButtonNew(wxCommandEvent& event); | ||
| 223 | void OnButtonCopy(wxCommandEvent& event); | ||
| 224 | void OnButtonOK(wxCommandEvent& event); | ||
| 225 | void OnButtonCancel(wxCommandEvent& event); | ||
| 226 | void OnClose(wxCloseEvent& event); | ||
| 227 | |||
| 228 | public: | ||
| 229 | /** Constructor */ | ||
| 230 | CAddressBookDialog(wxWindow* parent, const wxString& strInitSelected, bool fSendingIn); | ||
| 231 | |||
| 232 | // Custom | ||
| 233 | bool fSending; | ||
| 234 | wxString GetAddress(); | ||
| 235 | }; | ||
| 236 | |||
| 237 | |||
| 238 | |||
| 239 | class CProductsDialog : public CProductsDialogBase | ||
| 240 | { | ||
| 241 | protected: | ||
| 242 | // Event handlers | ||
| 243 | void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); } | ||
| 244 | void OnCombobox(wxCommandEvent& event); | ||
| 245 | void OnButtonSearch(wxCommandEvent& event); | ||
| 246 | void OnListItemActivated(wxListEvent& event); | ||
| 247 | |||
| 248 | public: | ||
| 249 | /** Constructor */ | ||
| 250 | CProductsDialog(wxWindow* parent); | ||
| 251 | |||
| 252 | // Custom | ||
| 253 | vector<CProduct> m_vProduct; | ||
| 254 | }; | ||
| 255 | |||
| 256 | |||
| 257 | |||
| 258 | class CEditProductDialog : public CEditProductDialogBase | ||
| 259 | { | ||
| 260 | protected: | ||
| 261 | // Event handlers | ||
| 262 | void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); } | ||
| 263 | void OnButtonDel0(wxCommandEvent& event); | ||
| 264 | void OnButtonDel1(wxCommandEvent& event); | ||
| 265 | void OnButtonDel2(wxCommandEvent& event); | ||
| 266 | void OnButtonDel3(wxCommandEvent& event); | ||
| 267 | void OnButtonDel4(wxCommandEvent& event); | ||
| 268 | void OnButtonDel5(wxCommandEvent& event); | ||
| 269 | void OnButtonDel6(wxCommandEvent& event); | ||
| 270 | void OnButtonDel7(wxCommandEvent& event); | ||
| 271 | void OnButtonDel8(wxCommandEvent& event); | ||
| 272 | void OnButtonDel9(wxCommandEvent& event); | ||
| 273 | void OnButtonDel10(wxCommandEvent& event); | ||
| 274 | void OnButtonDel11(wxCommandEvent& event); | ||
| 275 | void OnButtonDel12(wxCommandEvent& event); | ||
| 276 | void OnButtonDel13(wxCommandEvent& event); | ||
| 277 | void OnButtonDel14(wxCommandEvent& event); | ||
| 278 | void OnButtonDel15(wxCommandEvent& event); | ||
| 279 | void OnButtonDel16(wxCommandEvent& event); | ||
| 280 | void OnButtonDel17(wxCommandEvent& event); | ||
| 281 | void OnButtonDel18(wxCommandEvent& event); | ||
| 282 | void OnButtonDel19(wxCommandEvent& event); | ||
| 283 | void OnButtonAddField(wxCommandEvent& event); | ||
| 284 | void OnButtonSend(wxCommandEvent& event); | ||
| 285 | void OnButtonPreview(wxCommandEvent& event); | ||
| 286 | void OnButtonCancel(wxCommandEvent& event); | ||
| 287 | |||
| 288 | public: | ||
| 289 | /** Constructor */ | ||
| 290 | CEditProductDialog(wxWindow* parent); | ||
| 291 | |||
| 292 | // Custom | ||
| 293 | enum { FIELDS_MAX = 20 }; | ||
| 294 | wxTextCtrl* m_textCtrlLabel[FIELDS_MAX]; | ||
| 295 | wxTextCtrl* m_textCtrlField[FIELDS_MAX]; | ||
| 296 | wxButton* m_buttonDel[FIELDS_MAX]; | ||
| 297 | |||
| 298 | void LayoutAll(); | ||
| 299 | void ShowLine(int i, bool fShow=true); | ||
| 300 | void OnButtonDel(wxCommandEvent& event, int n); | ||
| 301 | void SetProduct(const CProduct& productIn); | ||
| 302 | void GetProduct(CProduct& product); | ||
| 303 | |||
| 304 | }; | ||
| 305 | |||
| 306 | |||
| 307 | |||
| 308 | class CViewProductDialog : public CViewProductDialogBase | ||
| 309 | { | ||
| 310 | protected: | ||
| 311 | // Event handlers | ||
| 312 | void OnButtonSubmitForm(wxCommandEvent& event); | ||
| 313 | void OnButtonCancelForm(wxCommandEvent& event); | ||
| 314 | void OnButtonBack(wxCommandEvent& event); | ||
| 315 | void OnButtonNext(wxCommandEvent& event); | ||
| 316 | void OnButtonCancel(wxCommandEvent& event); | ||
| 317 | |||
| 318 | public: | ||
| 319 | /** Constructor */ | ||
| 320 | CViewProductDialog(wxWindow* parent, const CProduct& productIn); | ||
| 321 | ~CViewProductDialog(); | ||
| 322 | |||
| 323 | // Custom | ||
| 324 | CProduct product; | ||
| 325 | enum { FIELDS_MAX = 20 }; | ||
| 326 | wxStaticText* m_staticTextLabel[FIELDS_MAX]; | ||
| 327 | wxTextCtrl* m_textCtrlField[FIELDS_MAX]; | ||
| 328 | wxChoice* m_choiceField[FIELDS_MAX]; | ||
| 329 | |||
| 330 | void GetOrder(CWalletTx& order); | ||
| 331 | void UpdateProductDisplay(bool fDetails); | ||
| 332 | void OnReply1(wxCommandEvent& event); | ||
| 333 | }; | ||
| 334 | |||
| 335 | |||
| 336 | |||
| 337 | class CViewOrderDialog : public CViewOrderDialogBase | ||
| 338 | { | ||
| 339 | protected: | ||
| 340 | // Event handlers | ||
| 341 | void OnButtonOK(wxCommandEvent& event); | ||
| 342 | |||
| 343 | public: | ||
| 344 | /** Constructor */ | ||
| 345 | CViewOrderDialog(wxWindow* parent, CWalletTx order, bool fReceived); | ||
| 346 | |||
| 347 | // Custom | ||
| 348 | bool fReceived; | ||
| 349 | }; | ||
| 350 | |||
| 351 | |||
| 352 | |||
| 353 | class CEditReviewDialog : public CEditReviewDialogBase | ||
| 354 | { | ||
| 355 | protected: | ||
| 356 | // Event handlers | ||
| 357 | void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); } | ||
| 358 | void OnButtonSubmit(wxCommandEvent& event); | ||
| 359 | void OnButtonCancel(wxCommandEvent& event); | ||
| 360 | |||
| 361 | public: | ||
| 362 | /** Constructor */ | ||
| 363 | CEditReviewDialog(wxWindow* parent); | ||
| 364 | |||
| 365 | // Custom | ||
| 366 | void GetReview(CReview& review); | ||
| 367 | }; | ||
| 368 | |||
| 369 | |||
| 370 | |||
| 371 | class CGetTextFromUserDialog : public CGetTextFromUserDialogBase | ||
| 372 | { | ||
| 373 | protected: | ||
| 374 | // Event handlers | ||
| 375 | void OnButtonOK(wxCommandEvent& event) { EndModal(true); } | ||
| 376 | void OnButtonCancel(wxCommandEvent& event) { EndModal(false); } | ||
| 377 | void OnClose(wxCloseEvent& event) { EndModal(false); } | ||
| 378 | |||
| 379 | void OnKeyDown(wxKeyEvent& event) | ||
| 380 | { | ||
| 381 | if (event.GetKeyCode() == '\r' || event.GetKeyCode() == WXK_NUMPAD_ENTER) | ||
| 382 | EndModal(true); | ||
| 383 | else | ||
| 384 | HandleCtrlA(event); | ||
| 385 | } | ||
| 386 | |||
| 387 | public: | ||
| 388 | /** Constructor */ | ||
| 389 | CGetTextFromUserDialog(wxWindow* parent, | ||
| 390 | const string& strCaption, | ||
| 391 | const string& strMessage1, | ||
| 392 | const string& strValue1="", | ||
| 393 | const string& strMessage2="", | ||
| 394 | const string& strValue2="") : CGetTextFromUserDialogBase(parent, wxID_ANY, strCaption) | ||
| 395 | { | ||
| 396 | m_staticTextMessage1->SetLabel(strMessage1); | ||
| 397 | m_textCtrl1->SetValue(strValue1); | ||
| 398 | if (!strMessage2.empty()) | ||
| 399 | { | ||
| 400 | m_staticTextMessage2->Show(true); | ||
| 401 | m_staticTextMessage2->SetLabel(strMessage2); | ||
| 402 | m_textCtrl2->Show(true); | ||
| 403 | m_textCtrl2->SetValue(strValue2); | ||
| 404 | SetSize(wxDefaultCoord, 180); | ||
| 405 | } | ||
| 406 | } | ||
| 407 | |||
| 408 | // Custom | ||
| 409 | string GetValue() { return (string)m_textCtrl1->GetValue(); } | ||
| 410 | string GetValue1() { return (string)m_textCtrl1->GetValue(); } | ||
| 411 | string GetValue2() { return (string)m_textCtrl2->GetValue(); } | ||
| 412 | }; | ||
| 413 | |||
| 414 | |||
| 415 | |||
| 416 | |||
| 417 | |||
diff --git a/src/ui.rc b/src/ui.rc new file mode 100644 index 0000000..ec8b142 --- /dev/null +++ b/src/ui.rc | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | bitcoin ICON "rc/bitcoin.ico" | ||
| 2 | |||
| 3 | #include "wx/msw/wx.rc" | ||
| 4 | |||
| 5 | check ICON "rc/check.ico" | ||
| 6 | send16 BITMAP "rc/send16.bmp" | ||
| 7 | send16mask BITMAP "rc/send16mask.bmp" | ||
| 8 | send16masknoshadow BITMAP "rc/send16masknoshadow.bmp" | ||
| 9 | send20 BITMAP "rc/send20.bmp" | ||
| 10 | send20mask BITMAP "rc/send20mask.bmp" | ||
| 11 | addressbook16 BITMAP "rc/addressbook16.bmp" | ||
| 12 | addressbook16mask BITMAP "rc/addressbook16mask.bmp" | ||
| 13 | addressbook20 BITMAP "rc/addressbook20.bmp" | ||
| 14 | addressbook20mask BITMAP "rc/addressbook20mask.bmp" | ||
diff --git a/src/uibase.cpp b/src/uibase.cpp new file mode 100644 index 0000000..95ff887 --- /dev/null +++ b/src/uibase.cpp | |||
| @@ -0,0 +1,1808 @@ | |||
| 1 | // Copyright (c) 2009 Satoshi Nakamoto | ||
| 2 | // Distributed under the MIT/X11 software license, see the accompanying | ||
| 3 | // file license.txt or http://www.opensource.org/licenses/mit-license.php. | ||
| 4 | |||
| 5 | /////////////////////////////////////////////////////////////////////////// | ||
| 6 | // C++ code generated with wxFormBuilder (version Apr 16 2008) | ||
| 7 | // http://www.wxformbuilder.org/ | ||
| 8 | // | ||
| 9 | // PLEASE DO "NOT" EDIT THIS FILE! | ||
| 10 | /////////////////////////////////////////////////////////////////////////// | ||
| 11 | |||
| 12 | #include "uibase.h" | ||
| 13 | |||
| 14 | /////////////////////////////////////////////////////////////////////////// | ||
| 15 | |||
| 16 | CMainFrameBase::CMainFrameBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxFrame(parent, id, title, pos, size, style) | ||
| 17 | { | ||
| 18 | this->SetSizeHints(wxDefaultSize, wxDefaultSize); | ||
| 19 | this->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)); | ||
| 20 | |||
| 21 | m_menubar = new wxMenuBar(0); | ||
| 22 | m_menubar->SetBackgroundColour(wxColour(240, 240, 240)); | ||
| 23 | |||
| 24 | m_menuFile = new wxMenu(); | ||
| 25 | wxMenuItem* m_menuFileExit; | ||
| 26 | m_menuFileExit = new wxMenuItem(m_menuFile, wxID_ANY, wxString(wxT("E&xit")) , wxEmptyString, wxITEM_NORMAL); | ||
| 27 | m_menuFile->Append(m_menuFileExit); | ||
| 28 | |||
| 29 | m_menubar->Append(m_menuFile, wxT("&File")); | ||
| 30 | |||
| 31 | m_menuOptions = new wxMenu(); | ||
| 32 | wxMenuItem* m_menuOptionsGenerateBitcoins; | ||
| 33 | m_menuOptionsGenerateBitcoins = new wxMenuItem(m_menuOptions, wxID_OPTIONSGENERATEBITCOINS, wxString(wxT("&Generate Coins (CPU)")), wxEmptyString, wxITEM_CHECK); | ||
| 34 | m_menuOptions->Append(m_menuOptionsGenerateBitcoins); | ||
| 35 | |||
| 36 | wxMenuItem* m_menuOptionsOptions; | ||
| 37 | m_menuOptionsOptions = new wxMenuItem(m_menuOptions, wxID_ANY, wxString(wxT("&Options...")) , wxEmptyString, wxITEM_NORMAL); | ||
| 38 | m_menuOptions->Append(m_menuOptionsOptions); | ||
| 39 | |||
| 40 | m_menubar->Append(m_menuOptions, wxT("&Options")); | ||
| 41 | |||
| 42 | m_menuHelp = new wxMenu(); | ||
| 43 | wxMenuItem* m_menuHelpAbout; | ||
| 44 | m_menuHelpAbout = new wxMenuItem(m_menuHelp, wxID_ANY, wxString(wxT("&About...")) , wxEmptyString, wxITEM_NORMAL); | ||
| 45 | m_menuHelp->Append(m_menuHelpAbout); | ||
| 46 | |||
| 47 | m_menubar->Append(m_menuHelp, wxT("&Help")); | ||
| 48 | |||
| 49 | this->SetMenuBar(m_menubar); | ||
| 50 | |||
| 51 | m_toolBar = this->CreateToolBar(wxTB_FLAT|wxTB_HORZ_TEXT, wxID_ANY); | ||
| 52 | m_toolBar->SetToolBitmapSize(wxSize(20,20)); | ||
| 53 | m_toolBar->SetToolSeparation(1); | ||
| 54 | m_toolBar->SetFont(wxFont(wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxEmptyString)); | ||
| 55 | |||
| 56 | m_toolBar->AddTool(wxID_BUTTONSEND, wxT("&Send Coins"), wxBitmap(wxT("send20"), wxBITMAP_TYPE_RESOURCE), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString); | ||
| 57 | m_toolBar->AddTool(wxID_BUTTONRECEIVE, wxT("&Address Book"), wxBitmap(wxT("addressbook20"), wxBITMAP_TYPE_RESOURCE), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString); | ||
| 58 | m_toolBar->Realize(); | ||
| 59 | |||
| 60 | m_statusBar = this->CreateStatusBar(1, wxST_SIZEGRIP, wxID_ANY); | ||
| 61 | m_statusBar->SetBackgroundColour(wxColour(240, 240, 240)); | ||
| 62 | |||
| 63 | wxBoxSizer* bSizer2; | ||
| 64 | bSizer2 = new wxBoxSizer(wxVERTICAL); | ||
| 65 | |||
| 66 | |||
| 67 | bSizer2->Add(0, 2, 0, wxEXPAND, 5); | ||
| 68 | |||
| 69 | wxBoxSizer* bSizer85; | ||
| 70 | bSizer85 = new wxBoxSizer(wxHORIZONTAL); | ||
| 71 | |||
| 72 | m_staticText32 = new wxStaticText(this, wxID_ANY, wxT("Your Bitflash Address:"), wxDefaultPosition, wxDefaultSize, 0); | ||
| 73 | m_staticText32->Wrap(-1); | ||
| 74 | bSizer85->Add(m_staticText32, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5); | ||
| 75 | |||
| 76 | m_textCtrlAddress = new wxTextCtrl(this, wxID_TEXTCTRLADDRESS, wxEmptyString, wxDefaultPosition, wxSize(250,-1), wxTE_READONLY); | ||
| 77 | m_textCtrlAddress->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_MENU)); | ||
| 78 | |||
| 79 | bSizer85->Add(m_textCtrlAddress, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); | ||
| 80 | |||
| 81 | m_buttonCopy = new wxButton(this, wxID_BUTTONCOPY, wxT("&Copy to Clipboard"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT); | ||
| 82 | bSizer85->Add(m_buttonCopy, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5); | ||
| 83 | |||
| 84 | m_button91 = new wxButton(this, wxID_BUTTONCHANGE, wxT("C&hange..."), wxDefaultPosition, wxDefaultSize, 0); | ||
| 85 | bSizer85->Add(m_button91, 0, wxRIGHT, 5); | ||
| 86 | |||
| 87 | |||
| 88 | bSizer85->Add(0, 0, 0, wxEXPAND, 5); | ||
| 89 | |||
| 90 | bSizer2->Add(bSizer85, 0, wxEXPAND|wxRIGHT|wxLEFT, 5); | ||
| 91 | |||
| 92 | wxBoxSizer* bSizer3; | ||
| 93 | bSizer3 = new wxBoxSizer(wxHORIZONTAL); | ||
| 94 | |||
| 95 | m_panel14 = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); | ||
| 96 | wxBoxSizer* bSizer66; | ||
| 97 | bSizer66 = new wxBoxSizer(wxHORIZONTAL); | ||
| 98 | |||
| 99 | m_staticText41 = new wxStaticText(m_panel14, wxID_ANY, wxT("Balance:"), wxDefaultPosition, wxSize(-1,15), 0); | ||
| 100 | m_staticText41->Wrap(-1); | ||
| 101 | bSizer66->Add(m_staticText41, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5); | ||
| 102 | |||
| 103 | m_staticTextBalance = new wxStaticText(m_panel14, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(120,15), wxALIGN_RIGHT|wxST_NO_AUTORESIZE); | ||
| 104 | m_staticTextBalance->Wrap(-1); | ||
| 105 | m_staticTextBalance->SetFont(wxFont(8, 70, 90, 90, false, wxEmptyString)); | ||
| 106 | m_staticTextBalance->SetBackgroundColour(wxColour(240, 240, 240)); | ||
| 107 | |||
| 108 | bSizer66->Add(m_staticTextBalance, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); | ||
| 109 | |||
| 110 | m_panel14->SetSizer(bSizer66); | ||
| 111 | m_panel14->Layout(); | ||
| 112 | bSizer66->Fit(m_panel14); | ||
| 113 | bSizer3->Add(m_panel14, 1, wxEXPAND|wxALIGN_BOTTOM|wxALL, 5); | ||
| 114 | |||
| 115 | |||
| 116 | bSizer3->Add(0, 0, 0, wxEXPAND, 5); | ||
| 117 | |||
| 118 | wxString m_choiceFilterChoices[] = { wxT(" All"), wxT(" Sent"), wxT(" Received"), wxT(" In Progress") }; | ||
| 119 | int m_choiceFilterNChoices = sizeof(m_choiceFilterChoices) / sizeof(wxString); | ||
| 120 | m_choiceFilter = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxSize(110,-1), m_choiceFilterNChoices, m_choiceFilterChoices, 0); | ||
| 121 | m_choiceFilter->SetSelection(0); | ||
| 122 | m_choiceFilter->Hide(); | ||
| 123 | |||
| 124 | bSizer3->Add(m_choiceFilter, 0, wxALIGN_BOTTOM|wxTOP|wxRIGHT|wxLEFT, 5); | ||
| 125 | |||
| 126 | bSizer2->Add(bSizer3, 0, wxEXPAND, 5); | ||
| 127 | |||
| 128 | m_notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0); | ||
| 129 | m_panel7 = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); | ||
| 130 | wxBoxSizer* bSizer157; | ||
| 131 | bSizer157 = new wxBoxSizer(wxVERTICAL); | ||
| 132 | |||
| 133 | m_listCtrl = new wxListCtrl(m_panel7, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING|wxALWAYS_SHOW_SB); | ||
| 134 | bSizer157->Add(m_listCtrl, 1, wxEXPAND|wxALL, 5); | ||
| 135 | |||
| 136 | m_panel7->SetSizer(bSizer157); | ||
| 137 | m_panel7->Layout(); | ||
| 138 | bSizer157->Fit(m_panel7); | ||
| 139 | m_notebook->AddPage(m_panel7, wxT("All Transactions"), false); | ||
| 140 | |||
| 141 | bSizer2->Add(m_notebook, 1, wxEXPAND, 5); | ||
| 142 | |||
| 143 | wxBoxSizer* bSizer_TabsForFutureUse; | ||
| 144 | bSizer_TabsForFutureUse = new wxBoxSizer(wxVERTICAL); | ||
| 145 | |||
| 146 | m_panel9 = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); | ||
| 147 | m_panel9->Hide(); | ||
| 148 | |||
| 149 | wxBoxSizer* bSizer159; | ||
| 150 | bSizer159 = new wxBoxSizer(wxVERTICAL); | ||
| 151 | |||
| 152 | m_listCtrlEscrows = new wxListCtrl(m_panel9, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT); | ||
| 153 | bSizer159->Add(m_listCtrlEscrows, 1, wxALL|wxEXPAND, 5); | ||
| 154 | |||
| 155 | m_panel9->SetSizer(bSizer159); | ||
| 156 | m_panel9->Layout(); | ||
| 157 | bSizer159->Fit(m_panel9); | ||
| 158 | bSizer_TabsForFutureUse->Add(m_panel9, 1, wxEXPAND | wxALL, 5); | ||
| 159 | |||
| 160 | m_panel8 = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); | ||
| 161 | m_panel8->Hide(); | ||
| 162 | |||
| 163 | wxBoxSizer* bSizer158; | ||
| 164 | bSizer158 = new wxBoxSizer(wxVERTICAL); | ||
| 165 | |||
| 166 | m_listCtrlOrdersSent = new wxListCtrl(m_panel8, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT); | ||
| 167 | bSizer158->Add(m_listCtrlOrdersSent, 1, wxALL|wxEXPAND, 5); | ||
| 168 | |||
| 169 | m_panel8->SetSizer(bSizer158); | ||
| 170 | m_panel8->Layout(); | ||
| 171 | bSizer158->Fit(m_panel8); | ||
| 172 | bSizer_TabsForFutureUse->Add(m_panel8, 1, wxEXPAND | wxALL, 5); | ||
| 173 | |||
| 174 | m_panel10 = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); | ||
| 175 | m_panel10->Hide(); | ||
| 176 | |||
| 177 | wxBoxSizer* bSizer160; | ||
| 178 | bSizer160 = new wxBoxSizer(wxVERTICAL); | ||
| 179 | |||
| 180 | m_listCtrlProductsSent = new wxListCtrl(m_panel10, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT); | ||
| 181 | bSizer160->Add(m_listCtrlProductsSent, 1, wxALL|wxEXPAND, 5); | ||
| 182 | |||
| 183 | m_panel10->SetSizer(bSizer160); | ||
| 184 | m_panel10->Layout(); | ||
| 185 | bSizer160->Fit(m_panel10); | ||
| 186 | bSizer_TabsForFutureUse->Add(m_panel10, 1, wxEXPAND | wxALL, 5); | ||
| 187 | |||
| 188 | m_panel11 = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); | ||
| 189 | m_panel11->Hide(); | ||
| 190 | |||
| 191 | wxBoxSizer* bSizer161; | ||
| 192 | bSizer161 = new wxBoxSizer(wxVERTICAL); | ||
| 193 | |||
| 194 | m_listCtrlOrdersReceived = new wxListCtrl(m_panel11, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT); | ||
| 195 | bSizer161->Add(m_listCtrlOrdersReceived, 1, wxALL|wxEXPAND, 5); | ||
| 196 | |||
| 197 | m_panel11->SetSizer(bSizer161); | ||
| 198 | m_panel11->Layout(); | ||
| 199 | bSizer161->Fit(m_panel11); | ||
| 200 | bSizer_TabsForFutureUse->Add(m_panel11, 1, wxEXPAND | wxALL, 5); | ||
| 201 | |||
| 202 | bSizer2->Add(bSizer_TabsForFutureUse, 1, wxEXPAND, 5); | ||
| 203 | |||
| 204 | this->SetSizer(bSizer2); | ||
| 205 | this->Layout(); | ||
| 206 | |||
| 207 | // Connect Events | ||
| 208 | this->Connect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(CMainFrameBase::OnClose)); | ||
| 209 | this->Connect(wxEVT_IDLE, wxIdleEventHandler(CMainFrameBase::OnIdle)); | ||
| 210 | this->Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(CMainFrameBase::OnMouseEvents)); | ||
| 211 | this->Connect(wxEVT_LEFT_UP, wxMouseEventHandler(CMainFrameBase::OnMouseEvents)); | ||
| 212 | this->Connect(wxEVT_MIDDLE_DOWN, wxMouseEventHandler(CMainFrameBase::OnMouseEvents)); | ||
| 213 | this->Connect(wxEVT_MIDDLE_UP, wxMouseEventHandler(CMainFrameBase::OnMouseEvents)); | ||
| 214 | this->Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(CMainFrameBase::OnMouseEvents)); | ||
| 215 | this->Connect(wxEVT_RIGHT_UP, wxMouseEventHandler(CMainFrameBase::OnMouseEvents)); | ||
| 216 | this->Connect(wxEVT_MOTION, wxMouseEventHandler(CMainFrameBase::OnMouseEvents)); | ||
| 217 | this->Connect(wxEVT_LEFT_DCLICK, wxMouseEventHandler(CMainFrameBase::OnMouseEvents)); | ||
| 218 | this->Connect(wxEVT_MIDDLE_DCLICK, wxMouseEventHandler(CMainFrameBase::OnMouseEvents)); | ||
| 219 | this->Connect(wxEVT_RIGHT_DCLICK, wxMouseEventHandler(CMainFrameBase::OnMouseEvents)); | ||
| 220 | this->Connect(wxEVT_LEAVE_WINDOW, wxMouseEventHandler(CMainFrameBase::OnMouseEvents)); | ||
| 221 | this->Connect(wxEVT_ENTER_WINDOW, wxMouseEventHandler(CMainFrameBase::OnMouseEvents)); | ||
| 222 | this->Connect(wxEVT_MOUSEWHEEL, wxMouseEventHandler(CMainFrameBase::OnMouseEvents)); | ||
| 223 | this->Connect(wxEVT_PAINT, wxPaintEventHandler(CMainFrameBase::OnPaint)); | ||
| 224 | this->Connect(m_menuFileExit->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(CMainFrameBase::OnMenuFileExit)); | ||
| 225 | this->Connect(m_menuOptionsGenerateBitcoins->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(CMainFrameBase::OnMenuOptionsGenerate)); | ||
| 226 | this->Connect(m_menuOptionsOptions->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(CMainFrameBase::OnMenuOptionsOptions)); | ||
| 227 | this->Connect(m_menuHelpAbout->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(CMainFrameBase::OnMenuHelpAbout)); | ||
| 228 | this->Connect(wxID_BUTTONSEND, wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler(CMainFrameBase::OnButtonSend)); | ||
| 229 | this->Connect(wxID_BUTTONRECEIVE, wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler(CMainFrameBase::OnButtonAddressBook)); | ||
| 230 | m_textCtrlAddress->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CMainFrameBase::OnKeyDown), NULL, this); | ||
| 231 | m_textCtrlAddress->Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(CMainFrameBase::OnMouseEventsAddress), NULL, this); | ||
| 232 | m_textCtrlAddress->Connect(wxEVT_LEFT_UP, wxMouseEventHandler(CMainFrameBase::OnMouseEventsAddress), NULL, this); | ||
| 233 | m_textCtrlAddress->Connect(wxEVT_MIDDLE_DOWN, wxMouseEventHandler(CMainFrameBase::OnMouseEventsAddress), NULL, this); | ||
| 234 | m_textCtrlAddress->Connect(wxEVT_MIDDLE_UP, wxMouseEventHandler(CMainFrameBase::OnMouseEventsAddress), NULL, this); | ||
| 235 | m_textCtrlAddress->Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(CMainFrameBase::OnMouseEventsAddress), NULL, this); | ||
| 236 | m_textCtrlAddress->Connect(wxEVT_RIGHT_UP, wxMouseEventHandler(CMainFrameBase::OnMouseEventsAddress), NULL, this); | ||
| 237 | m_textCtrlAddress->Connect(wxEVT_MOTION, wxMouseEventHandler(CMainFrameBase::OnMouseEventsAddress), NULL, this); | ||
| 238 | m_textCtrlAddress->Connect(wxEVT_LEFT_DCLICK, wxMouseEventHandler(CMainFrameBase::OnMouseEventsAddress), NULL, this); | ||
| 239 | m_textCtrlAddress->Connect(wxEVT_MIDDLE_DCLICK, wxMouseEventHandler(CMainFrameBase::OnMouseEventsAddress), NULL, this); | ||
| 240 | m_textCtrlAddress->Connect(wxEVT_RIGHT_DCLICK, wxMouseEventHandler(CMainFrameBase::OnMouseEventsAddress), NULL, this); | ||
| 241 | m_textCtrlAddress->Connect(wxEVT_LEAVE_WINDOW, wxMouseEventHandler(CMainFrameBase::OnMouseEventsAddress), NULL, this); | ||
| 242 | m_textCtrlAddress->Connect(wxEVT_ENTER_WINDOW, wxMouseEventHandler(CMainFrameBase::OnMouseEventsAddress), NULL, this); | ||
| 243 | m_textCtrlAddress->Connect(wxEVT_MOUSEWHEEL, wxMouseEventHandler(CMainFrameBase::OnMouseEventsAddress), NULL, this); | ||
| 244 | m_textCtrlAddress->Connect(wxEVT_SET_FOCUS, wxFocusEventHandler(CMainFrameBase::OnSetFocusAddress), NULL, this); | ||
| 245 | m_buttonCopy->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CMainFrameBase::OnButtonCopy), NULL, this); | ||
| 246 | m_button91->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CMainFrameBase::OnButtonChange), NULL, this); | ||
| 247 | m_listCtrl->Connect(wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler(CMainFrameBase::OnListColBeginDrag), NULL, this); | ||
| 248 | m_listCtrl->Connect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CMainFrameBase::OnListItemActivatedAllTransactions), NULL, this); | ||
| 249 | m_listCtrl->Connect(wxEVT_PAINT, wxPaintEventHandler(CMainFrameBase::OnPaintListCtrl), NULL, this); | ||
| 250 | m_listCtrlOrdersSent->Connect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CMainFrameBase::OnListItemActivatedOrdersSent), NULL, this); | ||
| 251 | m_listCtrlProductsSent->Connect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CMainFrameBase::OnListItemActivatedProductsSent), NULL, this); | ||
| 252 | m_listCtrlOrdersReceived->Connect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CMainFrameBase::OnListItemActivatedOrdersReceived), NULL, this); | ||
| 253 | } | ||
| 254 | |||
| 255 | CMainFrameBase::~CMainFrameBase() | ||
| 256 | { | ||
| 257 | // Disconnect Events | ||
| 258 | this->Disconnect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(CMainFrameBase::OnClose)); | ||
| 259 | this->Disconnect(wxEVT_IDLE, wxIdleEventHandler(CMainFrameBase::OnIdle)); | ||
| 260 | this->Disconnect(wxEVT_LEFT_DOWN, wxMouseEventHandler(CMainFrameBase::OnMouseEvents)); | ||
| 261 | this->Disconnect(wxEVT_LEFT_UP, wxMouseEventHandler(CMainFrameBase::OnMouseEvents)); | ||
| 262 | this->Disconnect(wxEVT_MIDDLE_DOWN, wxMouseEventHandler(CMainFrameBase::OnMouseEvents)); | ||
| 263 | this->Disconnect(wxEVT_MIDDLE_UP, wxMouseEventHandler(CMainFrameBase::OnMouseEvents)); | ||
| 264 | this->Disconnect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(CMainFrameBase::OnMouseEvents)); | ||
| 265 | this->Disconnect(wxEVT_RIGHT_UP, wxMouseEventHandler(CMainFrameBase::OnMouseEvents)); | ||
| 266 | this->Disconnect(wxEVT_MOTION, wxMouseEventHandler(CMainFrameBase::OnMouseEvents)); | ||
| 267 | this->Disconnect(wxEVT_LEFT_DCLICK, wxMouseEventHandler(CMainFrameBase::OnMouseEvents)); | ||
| 268 | this->Disconnect(wxEVT_MIDDLE_DCLICK, wxMouseEventHandler(CMainFrameBase::OnMouseEvents)); | ||
| 269 | this->Disconnect(wxEVT_RIGHT_DCLICK, wxMouseEventHandler(CMainFrameBase::OnMouseEvents)); | ||
| 270 | this->Disconnect(wxEVT_LEAVE_WINDOW, wxMouseEventHandler(CMainFrameBase::OnMouseEvents)); | ||
| 271 | this->Disconnect(wxEVT_ENTER_WINDOW, wxMouseEventHandler(CMainFrameBase::OnMouseEvents)); | ||
| 272 | this->Disconnect(wxEVT_MOUSEWHEEL, wxMouseEventHandler(CMainFrameBase::OnMouseEvents)); | ||
| 273 | this->Disconnect(wxEVT_PAINT, wxPaintEventHandler(CMainFrameBase::OnPaint)); | ||
| 274 | this->Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(CMainFrameBase::OnMenuFileExit)); | ||
| 275 | this->Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(CMainFrameBase::OnMenuOptionsGenerate)); | ||
| 276 | this->Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(CMainFrameBase::OnMenuOptionsOptions)); | ||
| 277 | this->Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(CMainFrameBase::OnMenuHelpAbout)); | ||
| 278 | this->Disconnect(wxID_BUTTONSEND, wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler(CMainFrameBase::OnButtonSend)); | ||
| 279 | this->Disconnect(wxID_BUTTONRECEIVE, wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler(CMainFrameBase::OnButtonAddressBook)); | ||
| 280 | m_textCtrlAddress->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CMainFrameBase::OnKeyDown), NULL, this); | ||
| 281 | m_textCtrlAddress->Disconnect(wxEVT_LEFT_DOWN, wxMouseEventHandler(CMainFrameBase::OnMouseEventsAddress), NULL, this); | ||
| 282 | m_textCtrlAddress->Disconnect(wxEVT_LEFT_UP, wxMouseEventHandler(CMainFrameBase::OnMouseEventsAddress), NULL, this); | ||
| 283 | m_textCtrlAddress->Disconnect(wxEVT_MIDDLE_DOWN, wxMouseEventHandler(CMainFrameBase::OnMouseEventsAddress), NULL, this); | ||
| 284 | m_textCtrlAddress->Disconnect(wxEVT_MIDDLE_UP, wxMouseEventHandler(CMainFrameBase::OnMouseEventsAddress), NULL, this); | ||
| 285 | m_textCtrlAddress->Disconnect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(CMainFrameBase::OnMouseEventsAddress), NULL, this); | ||
| 286 | m_textCtrlAddress->Disconnect(wxEVT_RIGHT_UP, wxMouseEventHandler(CMainFrameBase::OnMouseEventsAddress), NULL, this); | ||
| 287 | m_textCtrlAddress->Disconnect(wxEVT_MOTION, wxMouseEventHandler(CMainFrameBase::OnMouseEventsAddress), NULL, this); | ||
| 288 | m_textCtrlAddress->Disconnect(wxEVT_LEFT_DCLICK, wxMouseEventHandler(CMainFrameBase::OnMouseEventsAddress), NULL, this); | ||
| 289 | m_textCtrlAddress->Disconnect(wxEVT_MIDDLE_DCLICK, wxMouseEventHandler(CMainFrameBase::OnMouseEventsAddress), NULL, this); | ||
| 290 | m_textCtrlAddress->Disconnect(wxEVT_RIGHT_DCLICK, wxMouseEventHandler(CMainFrameBase::OnMouseEventsAddress), NULL, this); | ||
| 291 | m_textCtrlAddress->Disconnect(wxEVT_LEAVE_WINDOW, wxMouseEventHandler(CMainFrameBase::OnMouseEventsAddress), NULL, this); | ||
| 292 | m_textCtrlAddress->Disconnect(wxEVT_ENTER_WINDOW, wxMouseEventHandler(CMainFrameBase::OnMouseEventsAddress), NULL, this); | ||
| 293 | m_textCtrlAddress->Disconnect(wxEVT_MOUSEWHEEL, wxMouseEventHandler(CMainFrameBase::OnMouseEventsAddress), NULL, this); | ||
| 294 | m_textCtrlAddress->Disconnect(wxEVT_SET_FOCUS, wxFocusEventHandler(CMainFrameBase::OnSetFocusAddress), NULL, this); | ||
| 295 | m_buttonCopy->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CMainFrameBase::OnButtonCopy), NULL, this); | ||
| 296 | m_button91->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CMainFrameBase::OnButtonChange), NULL, this); | ||
| 297 | m_listCtrl->Disconnect(wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler(CMainFrameBase::OnListColBeginDrag), NULL, this); | ||
| 298 | m_listCtrl->Disconnect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CMainFrameBase::OnListItemActivatedAllTransactions), NULL, this); | ||
| 299 | m_listCtrl->Disconnect(wxEVT_PAINT, wxPaintEventHandler(CMainFrameBase::OnPaintListCtrl), NULL, this); | ||
| 300 | m_listCtrlOrdersSent->Disconnect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CMainFrameBase::OnListItemActivatedOrdersSent), NULL, this); | ||
| 301 | m_listCtrlProductsSent->Disconnect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CMainFrameBase::OnListItemActivatedProductsSent), NULL, this); | ||
| 302 | m_listCtrlOrdersReceived->Disconnect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CMainFrameBase::OnListItemActivatedOrdersReceived), NULL, this); | ||
| 303 | } | ||
| 304 | |||
| 305 | CTxDetailsDialogBase::CTxDetailsDialogBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxDialog(parent, id, title, pos, size, style) | ||
| 306 | { | ||
| 307 | this->SetSizeHints(wxDefaultSize, wxDefaultSize); | ||
| 308 | |||
| 309 | wxBoxSizer* bSizer64; | ||
| 310 | bSizer64 = new wxBoxSizer(wxVERTICAL); | ||
| 311 | |||
| 312 | wxBoxSizer* bSizer66; | ||
| 313 | bSizer66 = new wxBoxSizer(wxVERTICAL); | ||
| 314 | |||
| 315 | m_htmlWin = new wxHtmlWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO); | ||
| 316 | bSizer66->Add(m_htmlWin, 1, wxALL|wxEXPAND, 5); | ||
| 317 | |||
| 318 | bSizer64->Add(bSizer66, 1, wxEXPAND, 5); | ||
| 319 | |||
| 320 | wxBoxSizer* bSizer65; | ||
| 321 | bSizer65 = new wxBoxSizer(wxVERTICAL); | ||
| 322 | |||
| 323 | m_buttonOK = new wxButton(this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize(85,25), 0); | ||
| 324 | bSizer65->Add(m_buttonOK, 0, wxALL, 5); | ||
| 325 | |||
| 326 | bSizer64->Add(bSizer65, 0, wxALIGN_RIGHT, 5); | ||
| 327 | |||
| 328 | this->SetSizer(bSizer64); | ||
| 329 | this->Layout(); | ||
| 330 | |||
| 331 | // Connect Events | ||
| 332 | m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CTxDetailsDialogBase::OnButtonOK), NULL, this); | ||
| 333 | } | ||
| 334 | |||
| 335 | CTxDetailsDialogBase::~CTxDetailsDialogBase() | ||
| 336 | { | ||
| 337 | // Disconnect Events | ||
| 338 | m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CTxDetailsDialogBase::OnButtonOK), NULL, this); | ||
| 339 | } | ||
| 340 | |||
| 341 | COptionsDialogBase::COptionsDialogBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxDialog(parent, id, title, pos, size, style) | ||
| 342 | { | ||
| 343 | this->SetSizeHints(wxDefaultSize, wxDefaultSize); | ||
| 344 | |||
| 345 | wxBoxSizer* bSizer55; | ||
| 346 | bSizer55 = new wxBoxSizer(wxVERTICAL); | ||
| 347 | |||
| 348 | wxBoxSizer* bSizer57; | ||
| 349 | bSizer57 = new wxBoxSizer(wxVERTICAL); | ||
| 350 | |||
| 351 | |||
| 352 | bSizer57->Add(0, 20, 0, wxEXPAND, 5); | ||
| 353 | |||
| 354 | m_staticText32 = new wxStaticText(this, wxID_ANY, wxT("Optional transaction fee you give to the nodes that process your transactions."), wxDefaultPosition, wxDefaultSize, 0); | ||
| 355 | m_staticText32->Wrap(-1); | ||
| 356 | bSizer57->Add(m_staticText32, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); | ||
| 357 | |||
| 358 | wxBoxSizer* bSizer56; | ||
| 359 | bSizer56 = new wxBoxSizer(wxHORIZONTAL); | ||
| 360 | |||
| 361 | m_staticText31 = new wxStaticText(this, wxID_ANY, wxT("Transaction fee:"), wxDefaultPosition, wxDefaultSize, 0); | ||
| 362 | m_staticText31->Wrap(-1); | ||
| 363 | bSizer56->Add(m_staticText31, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5); | ||
| 364 | |||
| 365 | m_textCtrlTransactionFee = new wxTextCtrl(this, wxID_TRANSACTIONFEE, wxEmptyString, wxDefaultPosition, wxSize(70,-1), 0); | ||
| 366 | bSizer56->Add(m_textCtrlTransactionFee, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); | ||
| 367 | |||
| 368 | bSizer57->Add(bSizer56, 0, wxEXPAND, 5); | ||
| 369 | |||
| 370 | bSizer55->Add(bSizer57, 1, wxEXPAND|wxLEFT, 5); | ||
| 371 | |||
| 372 | wxBoxSizer* bSizer58; | ||
| 373 | bSizer58 = new wxBoxSizer(wxHORIZONTAL); | ||
| 374 | |||
| 375 | m_buttonOK = new wxButton(this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize(85,25), 0); | ||
| 376 | bSizer58->Add(m_buttonOK, 0, wxALL, 5); | ||
| 377 | |||
| 378 | m_buttonCancel = new wxButton(this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize(-1,-1), 0); | ||
| 379 | m_buttonCancel->SetMinSize(wxSize(85,25)); | ||
| 380 | |||
| 381 | bSizer58->Add(m_buttonCancel, 0, wxALL, 5); | ||
| 382 | |||
| 383 | bSizer55->Add(bSizer58, 0, wxALIGN_RIGHT, 5); | ||
| 384 | |||
| 385 | this->SetSizer(bSizer55); | ||
| 386 | this->Layout(); | ||
| 387 | |||
| 388 | // Connect Events | ||
| 389 | m_textCtrlTransactionFee->Connect(wxEVT_KILL_FOCUS, wxFocusEventHandler(COptionsDialogBase::OnKillFocusTransactionFee), NULL, this); | ||
| 390 | m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(COptionsDialogBase::OnButtonOK), NULL, this); | ||
| 391 | m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(COptionsDialogBase::OnButtonCancel), NULL, this); | ||
| 392 | } | ||
| 393 | |||
| 394 | COptionsDialogBase::~COptionsDialogBase() | ||
| 395 | { | ||
| 396 | // Disconnect Events | ||
| 397 | m_textCtrlTransactionFee->Disconnect(wxEVT_KILL_FOCUS, wxFocusEventHandler(COptionsDialogBase::OnKillFocusTransactionFee), NULL, this); | ||
| 398 | m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(COptionsDialogBase::OnButtonOK), NULL, this); | ||
| 399 | m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(COptionsDialogBase::OnButtonCancel), NULL, this); | ||
| 400 | } | ||
| 401 | |||
| 402 | CAboutDialogBase::CAboutDialogBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxDialog(parent, id, title, pos, size, style) | ||
| 403 | { | ||
| 404 | this->SetSizeHints(wxDefaultSize, wxDefaultSize); | ||
| 405 | |||
| 406 | wxBoxSizer* bSizer60; | ||
| 407 | bSizer60 = new wxBoxSizer(wxVERTICAL); | ||
| 408 | |||
| 409 | wxBoxSizer* bSizer62; | ||
| 410 | bSizer62 = new wxBoxSizer(wxHORIZONTAL); | ||
| 411 | |||
| 412 | |||
| 413 | bSizer62->Add(60, 0, 0, wxEXPAND, 5); | ||
| 414 | |||
| 415 | wxBoxSizer* bSizer63; | ||
| 416 | bSizer63 = new wxBoxSizer(wxVERTICAL); | ||
| 417 | |||
| 418 | |||
| 419 | bSizer63->Add(0, 50, 0, wxEXPAND, 5); | ||
| 420 | |||
| 421 | wxBoxSizer* bSizer64; | ||
| 422 | bSizer64 = new wxBoxSizer(wxHORIZONTAL); | ||
| 423 | |||
| 424 | m_staticText40 = new wxStaticText(this, wxID_ANY, wxT("Bitflash "), wxDefaultPosition, wxDefaultSize, 0); | ||
| 425 | m_staticText40->Wrap(-1); | ||
| 426 | m_staticText40->SetFont(wxFont(10, 74, 90, 92, false, wxT("Tahoma"))); | ||
| 427 | |||
| 428 | bSizer64->Add(m_staticText40, 0, wxALIGN_BOTTOM|wxTOP|wxBOTTOM|wxLEFT, 5); | ||
| 429 | |||
| 430 | m_staticTextVersion = new wxStaticText(this, wxID_ANY, wxT("version"), wxDefaultPosition, wxDefaultSize, 0); | ||
| 431 | m_staticTextVersion->Wrap(-1); | ||
| 432 | m_staticTextVersion->SetFont(wxFont(10, 74, 90, 90, false, wxT("Tahoma"))); | ||
| 433 | |||
| 434 | bSizer64->Add(m_staticTextVersion, 0, wxALIGN_BOTTOM|wxTOP|wxBOTTOM|wxRIGHT, 5); | ||
| 435 | |||
| 436 | bSizer63->Add(bSizer64, 0, wxEXPAND, 5); | ||
| 437 | |||
| 438 | |||
| 439 | bSizer63->Add(0, 4, 0, wxEXPAND, 5); | ||
| 440 | |||
| 441 | m_staticTextMain = new wxStaticText(this, wxID_ANY, wxT("Bitflash (BTF) - a revival of the original Bitcoin v0.1 client.\nNo pre-mine. No ICO. One CPU, one vote.\n\nCopyright © 2009 Satoshi Nakamoto (original Bitcoin).\nCopyright © 2026 The Bitflash developers.\n\nThis is experimental software. Do not rely on it for actual financial transactions.\n\nDistributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php.\n\nThis product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by Eric Young (eay@cryptsoft.com)."), wxDefaultPosition, wxDefaultSize, 0); | ||
| 442 | m_staticTextMain->Wrap(400); | ||
| 443 | bSizer63->Add(m_staticTextMain, 0, wxALL, 5); | ||
| 444 | |||
| 445 | |||
| 446 | bSizer63->Add(0, 0, 1, wxEXPAND, 5); | ||
| 447 | |||
| 448 | bSizer62->Add(bSizer63, 1, wxEXPAND, 5); | ||
| 449 | |||
| 450 | bSizer60->Add(bSizer62, 1, wxEXPAND, 5); | ||
| 451 | |||
| 452 | wxBoxSizer* bSizer61; | ||
| 453 | bSizer61 = new wxBoxSizer(wxHORIZONTAL); | ||
| 454 | |||
| 455 | |||
| 456 | bSizer61->Add(0, 0, 1, wxEXPAND, 5); | ||
| 457 | |||
| 458 | m_buttonOK = new wxButton(this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize(85,25), 0); | ||
| 459 | bSizer61->Add(m_buttonOK, 0, wxALL, 5); | ||
| 460 | |||
| 461 | bSizer60->Add(bSizer61, 0, wxALIGN_RIGHT|wxEXPAND, 5); | ||
| 462 | |||
| 463 | this->SetSizer(bSizer60); | ||
| 464 | this->Layout(); | ||
| 465 | // Resize the dialog to fit all the About text (avoids the bottom being cut off) | ||
| 466 | bSizer60->Fit(this); | ||
| 467 | |||
| 468 | // Connect Events | ||
| 469 | m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CAboutDialogBase::OnButtonOK), NULL, this); | ||
| 470 | } | ||
| 471 | |||
| 472 | CAboutDialogBase::~CAboutDialogBase() | ||
| 473 | { | ||
| 474 | // Disconnect Events | ||
| 475 | m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CAboutDialogBase::OnButtonOK), NULL, this); | ||
| 476 | } | ||
| 477 | |||
| 478 | CSendDialogBase::CSendDialogBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxDialog(parent, id, title, pos, size, style) | ||
| 479 | { | ||
| 480 | this->SetSizeHints(wxDefaultSize, wxDefaultSize); | ||
| 481 | |||
| 482 | wxBoxSizer* bSizer21; | ||
| 483 | bSizer21 = new wxBoxSizer(wxVERTICAL); | ||
| 484 | |||
| 485 | |||
| 486 | bSizer21->Add(0, 5, 0, wxEXPAND, 5); | ||
| 487 | |||
| 488 | wxFlexGridSizer* fgSizer1; | ||
| 489 | fgSizer1 = new wxFlexGridSizer(3, 2, 0, 0); | ||
| 490 | fgSizer1->AddGrowableCol(1); | ||
| 491 | fgSizer1->SetFlexibleDirection(wxBOTH); | ||
| 492 | fgSizer1->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); | ||
| 493 | |||
| 494 | |||
| 495 | fgSizer1->Add(0, 0, 0, wxEXPAND, 5); | ||
| 496 | |||
| 497 | m_staticText14 = new wxStaticText(this, wxID_ANY, wxT("Enter the recipient's IP address (e.g. 123.45.6.7) for online transfer with comments and confirmation, \nor Bitflash address if recipient is not online."), wxDefaultPosition, wxDefaultSize, 0); | ||
| 498 | m_staticText14->Wrap(-1); | ||
| 499 | fgSizer1->Add(m_staticText14, 0, wxTOP|wxRIGHT|wxLEFT, 5); | ||
| 500 | |||
| 501 | wxBoxSizer* bSizer47; | ||
| 502 | bSizer47 = new wxBoxSizer(wxHORIZONTAL); | ||
| 503 | |||
| 504 | bSizer47->SetMinSize(wxSize(70,-1)); | ||
| 505 | |||
| 506 | bSizer47->Add(0, 0, 1, wxEXPAND, 5); | ||
| 507 | |||
| 508 | m_bitmapCheckMark = new wxStaticBitmap(this, wxID_ANY, wxICON(check), wxDefaultPosition, wxSize(16,16), 0); | ||
| 509 | bSizer47->Add(m_bitmapCheckMark, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); | ||
| 510 | |||
| 511 | m_staticText36 = new wxStaticText(this, wxID_ANY, wxT("Pay &To:"), wxDefaultPosition, wxSize(-1,-1), wxALIGN_RIGHT); | ||
| 512 | m_staticText36->Wrap(-1); | ||
| 513 | bSizer47->Add(m_staticText36, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5); | ||
| 514 | |||
| 515 | fgSizer1->Add(bSizer47, 1, wxEXPAND|wxLEFT, 5); | ||
| 516 | |||
| 517 | wxBoxSizer* bSizer19; | ||
| 518 | bSizer19 = new wxBoxSizer(wxHORIZONTAL); | ||
| 519 | |||
| 520 | m_textCtrlAddress = new wxTextCtrl(this, wxID_TEXTCTRLPAYTO, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); | ||
| 521 | bSizer19->Add(m_textCtrlAddress, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5); | ||
| 522 | |||
| 523 | m_buttonPaste = new wxButton(this, wxID_BUTTONPASTE, wxT("&Paste"), wxDefaultPosition, wxSize(-1,-1), wxBU_EXACTFIT); | ||
| 524 | bSizer19->Add(m_buttonPaste, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5); | ||
| 525 | |||
| 526 | m_buttonAddress = new wxButton(this, wxID_BUTTONADDRESSBOOK, wxT(" Address &Book..."), wxDefaultPosition, wxDefaultSize, 0); | ||
| 527 | bSizer19->Add(m_buttonAddress, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5); | ||
| 528 | |||
| 529 | fgSizer1->Add(bSizer19, 1, wxEXPAND|wxRIGHT, 5); | ||
| 530 | |||
| 531 | m_staticText19 = new wxStaticText(this, wxID_ANY, wxT("&Amount:"), wxDefaultPosition, wxSize(-1,-1), wxALIGN_RIGHT); | ||
| 532 | m_staticText19->Wrap(-1); | ||
| 533 | fgSizer1->Add(m_staticText19, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT|wxALIGN_RIGHT, 5); | ||
| 534 | |||
| 535 | m_textCtrlAmount = new wxTextCtrl(this, wxID_TEXTCTRLAMOUNT, wxEmptyString, wxDefaultPosition, wxSize(145,-1), 0); | ||
| 536 | m_textCtrlAmount->SetMaxLength(20); | ||
| 537 | m_textCtrlAmount->SetFont(wxFont(wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxEmptyString)); | ||
| 538 | |||
| 539 | fgSizer1->Add(m_textCtrlAmount, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); | ||
| 540 | |||
| 541 | m_staticText20 = new wxStaticText(this, wxID_ANY, wxT("T&ransfer:"), wxDefaultPosition, wxSize(-1,-1), wxALIGN_RIGHT); | ||
| 542 | m_staticText20->Wrap(-1); | ||
| 543 | fgSizer1->Add(m_staticText20, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT, 5); | ||
| 544 | |||
| 545 | wxString m_choiceTransferTypeChoices[] = { wxT(" Standard") }; | ||
| 546 | int m_choiceTransferTypeNChoices = sizeof(m_choiceTransferTypeChoices) / sizeof(wxString); | ||
| 547 | m_choiceTransferType = new wxChoice(this, wxID_CHOICETRANSFERTYPE, wxDefaultPosition, wxDefaultSize, m_choiceTransferTypeNChoices, m_choiceTransferTypeChoices, 0); | ||
| 548 | m_choiceTransferType->SetSelection(0); | ||
| 549 | fgSizer1->Add(m_choiceTransferType, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); | ||
| 550 | |||
| 551 | bSizer21->Add(fgSizer1, 0, wxEXPAND|wxLEFT, 5); | ||
| 552 | |||
| 553 | wxBoxSizer* bSizer672; | ||
| 554 | bSizer672 = new wxBoxSizer(wxHORIZONTAL); | ||
| 555 | |||
| 556 | wxBoxSizer* bSizer681; | ||
| 557 | bSizer681 = new wxBoxSizer(wxVERTICAL); | ||
| 558 | |||
| 559 | m_staticTextFrom = new wxStaticText(this, wxID_ANY, wxT("&From:"), wxDefaultPosition, wxDefaultSize, 0); | ||
| 560 | m_staticTextFrom->Wrap(-1); | ||
| 561 | bSizer681->Add(m_staticTextFrom, 0, wxBOTTOM|wxLEFT, 5); | ||
| 562 | |||
| 563 | m_textCtrlFrom = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); | ||
| 564 | bSizer681->Add(m_textCtrlFrom, 0, wxLEFT|wxEXPAND, 5); | ||
| 565 | |||
| 566 | bSizer672->Add(bSizer681, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5); | ||
| 567 | |||
| 568 | bSizer21->Add(bSizer672, 0, wxEXPAND, 5); | ||
| 569 | |||
| 570 | wxBoxSizer* bSizer67; | ||
| 571 | bSizer67 = new wxBoxSizer(wxHORIZONTAL); | ||
| 572 | |||
| 573 | wxBoxSizer* bSizer68; | ||
| 574 | bSizer68 = new wxBoxSizer(wxVERTICAL); | ||
| 575 | |||
| 576 | m_staticTextMessage = new wxStaticText(this, wxID_ANY, wxT("&Message:"), wxDefaultPosition, wxDefaultSize, 0); | ||
| 577 | m_staticTextMessage->Wrap(-1); | ||
| 578 | bSizer68->Add(m_staticTextMessage, 0, wxTOP|wxBOTTOM|wxLEFT, 5); | ||
| 579 | |||
| 580 | m_textCtrlMessage = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE); | ||
| 581 | bSizer68->Add(m_textCtrlMessage, 1, wxEXPAND|wxLEFT, 5); | ||
| 582 | |||
| 583 | bSizer67->Add(bSizer68, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5); | ||
| 584 | |||
| 585 | bSizer21->Add(bSizer67, 1, wxEXPAND, 5); | ||
| 586 | |||
| 587 | wxBoxSizer* bSizer23; | ||
| 588 | bSizer23 = new wxBoxSizer(wxHORIZONTAL); | ||
| 589 | |||
| 590 | |||
| 591 | bSizer23->Add(0, 0, 1, wxEXPAND, 5); | ||
| 592 | |||
| 593 | m_buttonSend = new wxButton(this, wxID_BUTTONSEND, wxT("&Send"), wxDefaultPosition, wxSize(-1,-1), 0); | ||
| 594 | m_buttonSend->SetFont(wxFont(wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxEmptyString)); | ||
| 595 | m_buttonSend->SetMinSize(wxSize(85,25)); | ||
| 596 | |||
| 597 | bSizer23->Add(m_buttonSend, 0, wxALL, 5); | ||
| 598 | |||
| 599 | m_buttonCancel = new wxButton(this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize(-1,-1), 0); | ||
| 600 | m_buttonCancel->SetMinSize(wxSize(85,25)); | ||
| 601 | |||
| 602 | bSizer23->Add(m_buttonCancel, 0, wxALL, 5); | ||
| 603 | |||
| 604 | bSizer21->Add(bSizer23, 0, wxEXPAND, 5); | ||
| 605 | |||
| 606 | this->SetSizer(bSizer21); | ||
| 607 | this->Layout(); | ||
| 608 | |||
| 609 | // Connect Events | ||
| 610 | m_textCtrlAddress->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CSendDialogBase::OnKeyDown), NULL, this); | ||
| 611 | m_textCtrlAddress->Connect(wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler(CSendDialogBase::OnTextAddress), NULL, this); | ||
| 612 | m_buttonPaste->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CSendDialogBase::OnButtonPaste), NULL, this); | ||
| 613 | m_buttonAddress->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CSendDialogBase::OnButtonAddressBook), NULL, this); | ||
| 614 | m_textCtrlAmount->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CSendDialogBase::OnKeyDown), NULL, this); | ||
| 615 | m_textCtrlAmount->Connect(wxEVT_KILL_FOCUS, wxFocusEventHandler(CSendDialogBase::OnKillFocusAmount), NULL, this); | ||
| 616 | m_textCtrlFrom->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CSendDialogBase::OnKeyDown), NULL, this); | ||
| 617 | m_textCtrlMessage->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CSendDialogBase::OnKeyDown), NULL, this); | ||
| 618 | m_buttonSend->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CSendDialogBase::OnButtonSend), NULL, this); | ||
| 619 | m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CSendDialogBase::OnButtonCancel), NULL, this); | ||
| 620 | } | ||
| 621 | |||
| 622 | CSendDialogBase::~CSendDialogBase() | ||
| 623 | { | ||
| 624 | // Disconnect Events | ||
| 625 | m_textCtrlAddress->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CSendDialogBase::OnKeyDown), NULL, this); | ||
| 626 | m_textCtrlAddress->Disconnect(wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler(CSendDialogBase::OnTextAddress), NULL, this); | ||
| 627 | m_buttonPaste->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CSendDialogBase::OnButtonPaste), NULL, this); | ||
| 628 | m_buttonAddress->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CSendDialogBase::OnButtonAddressBook), NULL, this); | ||
| 629 | m_textCtrlAmount->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CSendDialogBase::OnKeyDown), NULL, this); | ||
| 630 | m_textCtrlAmount->Disconnect(wxEVT_KILL_FOCUS, wxFocusEventHandler(CSendDialogBase::OnKillFocusAmount), NULL, this); | ||
| 631 | m_textCtrlFrom->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CSendDialogBase::OnKeyDown), NULL, this); | ||
| 632 | m_textCtrlMessage->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CSendDialogBase::OnKeyDown), NULL, this); | ||
| 633 | m_buttonSend->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CSendDialogBase::OnButtonSend), NULL, this); | ||
| 634 | m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CSendDialogBase::OnButtonCancel), NULL, this); | ||
| 635 | } | ||
| 636 | |||
| 637 | CSendingDialogBase::CSendingDialogBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxDialog(parent, id, title, pos, size, style) | ||
| 638 | { | ||
| 639 | this->SetSizeHints(wxDefaultSize, wxDefaultSize); | ||
| 640 | |||
| 641 | wxBoxSizer* bSizer68; | ||
| 642 | bSizer68 = new wxBoxSizer(wxVERTICAL); | ||
| 643 | |||
| 644 | m_staticTextSending = new wxStaticText(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,14), 0); | ||
| 645 | m_staticTextSending->Wrap(-1); | ||
| 646 | bSizer68->Add(m_staticTextSending, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 8); | ||
| 647 | |||
| 648 | m_textCtrlStatus = new wxTextCtrl(this, wxID_ANY, wxT("\n\nConnecting..."), wxDefaultPosition, wxDefaultSize, wxTE_CENTRE|wxTE_MULTILINE|wxTE_NO_VSCROLL|wxTE_READONLY|wxNO_BORDER); | ||
| 649 | m_textCtrlStatus->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)); | ||
| 650 | |||
| 651 | bSizer68->Add(m_textCtrlStatus, 1, wxEXPAND|wxRIGHT|wxLEFT, 10); | ||
| 652 | |||
| 653 | wxBoxSizer* bSizer69; | ||
| 654 | bSizer69 = new wxBoxSizer(wxHORIZONTAL); | ||
| 655 | |||
| 656 | |||
| 657 | bSizer69->Add(0, 0, 1, wxEXPAND, 5); | ||
| 658 | |||
| 659 | m_buttonOK = new wxButton(this, wxID_ANY, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0); | ||
| 660 | m_buttonOK->Enable(false); | ||
| 661 | m_buttonOK->SetMinSize(wxSize(85,25)); | ||
| 662 | |||
| 663 | bSizer69->Add(m_buttonOK, 0, wxALL, 5); | ||
| 664 | |||
| 665 | m_buttonCancel = new wxButton(this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize(-1,-1), 0); | ||
| 666 | m_buttonCancel->SetMinSize(wxSize(85,25)); | ||
| 667 | |||
| 668 | bSizer69->Add(m_buttonCancel, 0, wxALL, 5); | ||
| 669 | |||
| 670 | bSizer68->Add(bSizer69, 0, wxEXPAND, 5); | ||
| 671 | |||
| 672 | this->SetSizer(bSizer68); | ||
| 673 | this->Layout(); | ||
| 674 | |||
| 675 | // Connect Events | ||
| 676 | this->Connect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(CSendingDialogBase::OnClose)); | ||
| 677 | this->Connect(wxEVT_PAINT, wxPaintEventHandler(CSendingDialogBase::OnPaint)); | ||
| 678 | m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CSendingDialogBase::OnButtonOK), NULL, this); | ||
| 679 | m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CSendingDialogBase::OnButtonCancel), NULL, this); | ||
| 680 | } | ||
| 681 | |||
| 682 | CSendingDialogBase::~CSendingDialogBase() | ||
| 683 | { | ||
| 684 | // Disconnect Events | ||
| 685 | this->Disconnect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(CSendingDialogBase::OnClose)); | ||
| 686 | this->Disconnect(wxEVT_PAINT, wxPaintEventHandler(CSendingDialogBase::OnPaint)); | ||
| 687 | m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CSendingDialogBase::OnButtonOK), NULL, this); | ||
| 688 | m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CSendingDialogBase::OnButtonCancel), NULL, this); | ||
| 689 | } | ||
| 690 | |||
| 691 | CYourAddressDialogBase::CYourAddressDialogBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxDialog(parent, id, title, pos, size, style) | ||
| 692 | { | ||
| 693 | this->SetSizeHints(wxDefaultSize, wxDefaultSize); | ||
| 694 | |||
| 695 | wxBoxSizer* bSizer68; | ||
| 696 | bSizer68 = new wxBoxSizer(wxVERTICAL); | ||
| 697 | |||
| 698 | |||
| 699 | bSizer68->Add(0, 5, 0, wxEXPAND, 5); | ||
| 700 | |||
| 701 | m_staticText45 = new wxStaticText(this, wxID_ANY, wxT("These are your Bitflash addresses for receiving payments.\nYou may want to give a different one to each sender so you can keep track of who is paying you."), wxDefaultPosition, wxDefaultSize, 0); | ||
| 702 | m_staticText45->Wrap(600); | ||
| 703 | bSizer68->Add(m_staticText45, 0, wxALL, 5); | ||
| 704 | |||
| 705 | m_listCtrl = new wxListCtrl(this, wxID_LISTCTRL, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_ASCENDING); | ||
| 706 | bSizer68->Add(m_listCtrl, 1, wxALL|wxEXPAND, 5); | ||
| 707 | |||
| 708 | wxBoxSizer* bSizer69; | ||
| 709 | bSizer69 = new wxBoxSizer(wxHORIZONTAL); | ||
| 710 | |||
| 711 | |||
| 712 | bSizer69->Add(0, 0, 1, wxEXPAND, 5); | ||
| 713 | |||
| 714 | m_buttonRename = new wxButton(this, wxID_BUTTONRENAME, wxT("&Rename..."), wxDefaultPosition, wxDefaultSize, 0); | ||
| 715 | m_buttonRename->SetMinSize(wxSize(85,25)); | ||
| 716 | |||
| 717 | bSizer69->Add(m_buttonRename, 0, wxALL, 5); | ||
| 718 | |||
| 719 | m_buttonNew = new wxButton(this, wxID_BUTTONNEW, wxT("&New Address..."), wxDefaultPosition, wxSize(-1,-1), 0); | ||
| 720 | m_buttonNew->SetMinSize(wxSize(110,25)); | ||
| 721 | |||
| 722 | bSizer69->Add(m_buttonNew, 0, wxALL, 5); | ||
| 723 | |||
| 724 | m_buttonCopy = new wxButton(this, wxID_BUTTONCOPY, wxT("&Copy to Clipboard"), wxDefaultPosition, wxSize(-1,-1), 0); | ||
| 725 | m_buttonCopy->SetMinSize(wxSize(120,25)); | ||
| 726 | |||
| 727 | bSizer69->Add(m_buttonCopy, 0, wxALL, 5); | ||
| 728 | |||
| 729 | m_buttonOK = new wxButton(this, wxID_OK, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0); | ||
| 730 | m_buttonOK->SetMinSize(wxSize(85,25)); | ||
| 731 | |||
| 732 | bSizer69->Add(m_buttonOK, 0, wxALL, 5); | ||
| 733 | |||
| 734 | m_buttonCancel = new wxButton(this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize(-1,-1), 0); | ||
| 735 | m_buttonCancel->SetMinSize(wxSize(85,25)); | ||
| 736 | |||
| 737 | bSizer69->Add(m_buttonCancel, 0, wxALL, 5); | ||
| 738 | |||
| 739 | bSizer68->Add(bSizer69, 0, wxEXPAND, 5); | ||
| 740 | |||
| 741 | this->SetSizer(bSizer68); | ||
| 742 | this->Layout(); | ||
| 743 | |||
| 744 | // Connect Events | ||
| 745 | this->Connect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(CYourAddressDialogBase::OnClose)); | ||
| 746 | m_listCtrl->Connect(wxEVT_COMMAND_LIST_END_LABEL_EDIT, wxListEventHandler(CYourAddressDialogBase::OnListEndLabelEdit), NULL, this); | ||
| 747 | m_listCtrl->Connect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CYourAddressDialogBase::OnListItemActivated), NULL, this); | ||
| 748 | m_listCtrl->Connect(wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(CYourAddressDialogBase::OnListItemSelected), NULL, this); | ||
| 749 | m_buttonRename->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CYourAddressDialogBase::OnButtonRename), NULL, this); | ||
| 750 | m_buttonNew->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CYourAddressDialogBase::OnButtonNew), NULL, this); | ||
| 751 | m_buttonCopy->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CYourAddressDialogBase::OnButtonCopy), NULL, this); | ||
| 752 | m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CYourAddressDialogBase::OnButtonOK), NULL, this); | ||
| 753 | m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CYourAddressDialogBase::OnButtonCancel), NULL, this); | ||
| 754 | } | ||
| 755 | |||
| 756 | CYourAddressDialogBase::~CYourAddressDialogBase() | ||
| 757 | { | ||
| 758 | // Disconnect Events | ||
| 759 | this->Disconnect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(CYourAddressDialogBase::OnClose)); | ||
| 760 | m_listCtrl->Disconnect(wxEVT_COMMAND_LIST_END_LABEL_EDIT, wxListEventHandler(CYourAddressDialogBase::OnListEndLabelEdit), NULL, this); | ||
| 761 | m_listCtrl->Disconnect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CYourAddressDialogBase::OnListItemActivated), NULL, this); | ||
| 762 | m_listCtrl->Disconnect(wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(CYourAddressDialogBase::OnListItemSelected), NULL, this); | ||
| 763 | m_buttonRename->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CYourAddressDialogBase::OnButtonRename), NULL, this); | ||
| 764 | m_buttonNew->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CYourAddressDialogBase::OnButtonNew), NULL, this); | ||
| 765 | m_buttonCopy->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CYourAddressDialogBase::OnButtonCopy), NULL, this); | ||
| 766 | m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CYourAddressDialogBase::OnButtonOK), NULL, this); | ||
| 767 | m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CYourAddressDialogBase::OnButtonCancel), NULL, this); | ||
| 768 | } | ||
| 769 | |||
| 770 | CAddressBookDialogBase::CAddressBookDialogBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxDialog(parent, id, title, pos, size, style) | ||
| 771 | { | ||
| 772 | this->SetSizeHints(wxDefaultSize, wxDefaultSize); | ||
| 773 | |||
| 774 | wxBoxSizer* bSizer68; | ||
| 775 | bSizer68 = new wxBoxSizer(wxVERTICAL); | ||
| 776 | |||
| 777 | |||
| 778 | bSizer68->Add(0, 5, 0, wxEXPAND, 5); | ||
| 779 | |||
| 780 | m_staticText55 = new wxStaticText(this, wxID_ANY, wxT("Bitflash Address"), wxDefaultPosition, wxDefaultSize, 0); | ||
| 781 | m_staticText55->Wrap(-1); | ||
| 782 | m_staticText55->Hide(); | ||
| 783 | |||
| 784 | bSizer68->Add(m_staticText55, 0, wxTOP|wxRIGHT|wxLEFT, 5); | ||
| 785 | |||
| 786 | m_listCtrl = new wxListCtrl(this, wxID_LISTCTRL, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_ASCENDING); | ||
| 787 | bSizer68->Add(m_listCtrl, 1, wxALL|wxEXPAND, 5); | ||
| 788 | |||
| 789 | wxBoxSizer* bSizer69; | ||
| 790 | bSizer69 = new wxBoxSizer(wxHORIZONTAL); | ||
| 791 | |||
| 792 | |||
| 793 | bSizer69->Add(0, 0, 1, wxEXPAND, 5); | ||
| 794 | |||
| 795 | m_buttonEdit = new wxButton(this, wxID_BUTTONEDIT, wxT("&Edit..."), wxDefaultPosition, wxDefaultSize, 0); | ||
| 796 | m_buttonEdit->SetMinSize(wxSize(85,25)); | ||
| 797 | |||
| 798 | bSizer69->Add(m_buttonEdit, 0, wxALL, 5); | ||
| 799 | |||
| 800 | m_buttonNew = new wxButton(this, wxID_BUTTONNEW, wxT("&New Address..."), wxDefaultPosition, wxDefaultSize, 0); | ||
| 801 | m_buttonNew->SetMinSize(wxSize(110,25)); | ||
| 802 | |||
| 803 | bSizer69->Add(m_buttonNew, 0, wxALL, 5); | ||
| 804 | |||
| 805 | m_buttonDelete = new wxButton(this, wxID_BUTTONDELETE, wxT("&Delete"), wxDefaultPosition, wxDefaultSize, 0); | ||
| 806 | m_buttonDelete->SetMinSize(wxSize(85,25)); | ||
| 807 | |||
| 808 | bSizer69->Add(m_buttonDelete, 0, wxALL, 5); | ||
| 809 | |||
| 810 | m_buttonOK = new wxButton(this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize(-1,-1), 0); | ||
| 811 | m_buttonOK->SetMinSize(wxSize(85,25)); | ||
| 812 | |||
| 813 | bSizer69->Add(m_buttonOK, 0, wxALL, 5); | ||
| 814 | |||
| 815 | m_buttonCancel = new wxButton(this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize(-1,-1), 0); | ||
| 816 | m_buttonCancel->SetMinSize(wxSize(85,25)); | ||
| 817 | |||
| 818 | bSizer69->Add(m_buttonCancel, 0, wxALL, 5); | ||
| 819 | |||
| 820 | bSizer68->Add(bSizer69, 0, wxEXPAND, 5); | ||
| 821 | |||
| 822 | this->SetSizer(bSizer68); | ||
| 823 | this->Layout(); | ||
| 824 | |||
| 825 | // Connect Events | ||
| 826 | this->Connect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(CAddressBookDialogBase::OnClose)); | ||
| 827 | m_listCtrl->Connect(wxEVT_COMMAND_LIST_END_LABEL_EDIT, wxListEventHandler(CAddressBookDialogBase::OnListEndLabelEdit), NULL, this); | ||
| 828 | m_listCtrl->Connect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CAddressBookDialogBase::OnListItemActivated), NULL, this); | ||
| 829 | m_listCtrl->Connect(wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(CAddressBookDialogBase::OnListItemSelected), NULL, this); | ||
| 830 | m_buttonEdit->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CAddressBookDialogBase::OnButtonEdit), NULL, this); | ||
| 831 | m_buttonNew->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CAddressBookDialogBase::OnButtonNew), NULL, this); | ||
| 832 | m_buttonDelete->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CAddressBookDialogBase::OnButtonDelete), NULL, this); | ||
| 833 | m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CAddressBookDialogBase::OnButtonOK), NULL, this); | ||
| 834 | m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CAddressBookDialogBase::OnButtonCancel), NULL, this); | ||
| 835 | } | ||
| 836 | |||
| 837 | CAddressBookDialogBase::~CAddressBookDialogBase() | ||
| 838 | { | ||
| 839 | // Disconnect Events | ||
| 840 | this->Disconnect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(CAddressBookDialogBase::OnClose)); | ||
| 841 | m_listCtrl->Disconnect(wxEVT_COMMAND_LIST_END_LABEL_EDIT, wxListEventHandler(CAddressBookDialogBase::OnListEndLabelEdit), NULL, this); | ||
| 842 | m_listCtrl->Disconnect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CAddressBookDialogBase::OnListItemActivated), NULL, this); | ||
| 843 | m_listCtrl->Disconnect(wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(CAddressBookDialogBase::OnListItemSelected), NULL, this); | ||
| 844 | m_buttonEdit->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CAddressBookDialogBase::OnButtonEdit), NULL, this); | ||
| 845 | m_buttonNew->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CAddressBookDialogBase::OnButtonNew), NULL, this); | ||
| 846 | m_buttonDelete->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CAddressBookDialogBase::OnButtonDelete), NULL, this); | ||
| 847 | m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CAddressBookDialogBase::OnButtonOK), NULL, this); | ||
| 848 | m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CAddressBookDialogBase::OnButtonCancel), NULL, this); | ||
| 849 | } | ||
| 850 | |||
| 851 | CProductsDialogBase::CProductsDialogBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxDialog(parent, id, title, pos, size, style) | ||
| 852 | { | ||
| 853 | this->SetSizeHints(wxDefaultSize, wxDefaultSize); | ||
| 854 | |||
| 855 | wxBoxSizer* bSizer22; | ||
| 856 | bSizer22 = new wxBoxSizer(wxVERTICAL); | ||
| 857 | |||
| 858 | wxBoxSizer* bSizer23; | ||
| 859 | bSizer23 = new wxBoxSizer(wxHORIZONTAL); | ||
| 860 | |||
| 861 | m_comboBoxCategory = new wxComboBox(this, wxID_ANY, wxT("(Any Category)"), wxDefaultPosition, wxSize(150,-1), 0, NULL, 0); | ||
| 862 | m_comboBoxCategory->Append(wxT("(Any Category)")); | ||
| 863 | bSizer23->Add(m_comboBoxCategory, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); | ||
| 864 | |||
| 865 | m_textCtrlSearch = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); | ||
| 866 | bSizer23->Add(m_textCtrlSearch, 1, wxALL|wxALIGN_CENTER_VERTICAL, 5); | ||
| 867 | |||
| 868 | m_buttonSearch = new wxButton(this, wxID_ANY, wxT("&Search"), wxDefaultPosition, wxDefaultSize, 0); | ||
| 869 | bSizer23->Add(m_buttonSearch, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); | ||
| 870 | |||
| 871 | bSizer22->Add(bSizer23, 0, wxEXPAND|wxTOP|wxBOTTOM|wxRIGHT, 5); | ||
| 872 | |||
| 873 | m_listCtrl = new wxListCtrl(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT); | ||
| 874 | bSizer22->Add(m_listCtrl, 1, wxALL|wxEXPAND, 5); | ||
| 875 | |||
| 876 | this->SetSizer(bSizer22); | ||
| 877 | this->Layout(); | ||
| 878 | |||
| 879 | // Connect Events | ||
| 880 | m_comboBoxCategory->Connect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(CProductsDialogBase::OnCombobox), NULL, this); | ||
| 881 | m_textCtrlSearch->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CProductsDialogBase::OnKeyDown), NULL, this); | ||
| 882 | m_buttonSearch->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CProductsDialogBase::OnButtonSearch), NULL, this); | ||
| 883 | m_listCtrl->Connect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CProductsDialogBase::OnListItemActivated), NULL, this); | ||
| 884 | } | ||
| 885 | |||
| 886 | CProductsDialogBase::~CProductsDialogBase() | ||
| 887 | { | ||
| 888 | // Disconnect Events | ||
| 889 | m_comboBoxCategory->Disconnect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(CProductsDialogBase::OnCombobox), NULL, this); | ||
| 890 | m_textCtrlSearch->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CProductsDialogBase::OnKeyDown), NULL, this); | ||
| 891 | m_buttonSearch->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CProductsDialogBase::OnButtonSearch), NULL, this); | ||
| 892 | m_listCtrl->Disconnect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CProductsDialogBase::OnListItemActivated), NULL, this); | ||
| 893 | } | ||
| 894 | |||
| 895 | CEditProductDialogBase::CEditProductDialogBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxFrame(parent, id, title, pos, size, style) | ||
| 896 | { | ||
| 897 | this->SetSizeHints(wxDefaultSize, wxDefaultSize); | ||
| 898 | this->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_MENU)); | ||
| 899 | |||
| 900 | wxBoxSizer* bSizer20; | ||
| 901 | bSizer20 = new wxBoxSizer(wxVERTICAL); | ||
| 902 | |||
| 903 | m_scrolledWindow = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxTAB_TRAVERSAL|wxVSCROLL); | ||
| 904 | m_scrolledWindow->SetScrollRate(5, 5); | ||
| 905 | m_scrolledWindow->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); | ||
| 906 | |||
| 907 | wxBoxSizer* bSizer21; | ||
| 908 | bSizer21 = new wxBoxSizer(wxVERTICAL); | ||
| 909 | |||
| 910 | wxFlexGridSizer* fgSizer8; | ||
| 911 | fgSizer8 = new wxFlexGridSizer(0, 2, 0, 0); | ||
| 912 | fgSizer8->AddGrowableCol(1); | ||
| 913 | fgSizer8->SetFlexibleDirection(wxBOTH); | ||
| 914 | fgSizer8->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); | ||
| 915 | |||
| 916 | m_staticText106 = new wxStaticText(m_scrolledWindow, wxID_ANY, wxT("Category"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); | ||
| 917 | m_staticText106->Wrap(-1); | ||
| 918 | fgSizer8->Add(m_staticText106, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT, 5); | ||
| 919 | |||
| 920 | m_comboBoxCategory = new wxComboBox(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0); | ||
| 921 | m_comboBoxCategory->SetMinSize(wxSize(180,-1)); | ||
| 922 | |||
| 923 | fgSizer8->Add(m_comboBoxCategory, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); | ||
| 924 | |||
| 925 | m_staticText108 = new wxStaticText(m_scrolledWindow, wxID_ANY, wxT("Title"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); | ||
| 926 | m_staticText108->Wrap(-1); | ||
| 927 | fgSizer8->Add(m_staticText108, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT, 5); | ||
| 928 | |||
| 929 | m_textCtrlTitle = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); | ||
| 930 | fgSizer8->Add(m_textCtrlTitle, 1, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5); | ||
| 931 | |||
| 932 | m_staticText107 = new wxStaticText(m_scrolledWindow, wxID_ANY, wxT("Price"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); | ||
| 933 | m_staticText107->Wrap(-1); | ||
| 934 | fgSizer8->Add(m_staticText107, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT, 5); | ||
| 935 | |||
| 936 | m_textCtrlPrice = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); | ||
| 937 | m_textCtrlPrice->SetMinSize(wxSize(105,-1)); | ||
| 938 | |||
| 939 | fgSizer8->Add(m_textCtrlPrice, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); | ||
| 940 | |||
| 941 | bSizer21->Add(fgSizer8, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5); | ||
| 942 | |||
| 943 | m_staticText22 = new wxStaticText(m_scrolledWindow, wxID_ANY, wxT("Page 1: Description"), wxDefaultPosition, wxDefaultSize, 0); | ||
| 944 | m_staticText22->Wrap(-1); | ||
| 945 | bSizer21->Add(m_staticText22, 0, wxTOP|wxRIGHT|wxLEFT, 5); | ||
| 946 | |||
| 947 | m_textCtrlDescription = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE); | ||
| 948 | m_textCtrlDescription->SetMinSize(wxSize(-1,170)); | ||
| 949 | |||
| 950 | bSizer21->Add(m_textCtrlDescription, 0, wxALL|wxEXPAND, 5); | ||
| 951 | |||
| 952 | m_staticText23 = new wxStaticText(m_scrolledWindow, wxID_ANY, wxT("Page 2: Order Form"), wxDefaultPosition, wxDefaultSize, 0); | ||
| 953 | m_staticText23->Wrap(-1); | ||
| 954 | bSizer21->Add(m_staticText23, 0, wxTOP|wxRIGHT|wxLEFT, 5); | ||
| 955 | |||
| 956 | m_textCtrlInstructions = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE); | ||
| 957 | m_textCtrlInstructions->SetMinSize(wxSize(-1,120)); | ||
| 958 | |||
| 959 | bSizer21->Add(m_textCtrlInstructions, 0, wxEXPAND|wxALL, 5); | ||
| 960 | |||
| 961 | fgSizer5 = new wxFlexGridSizer(0, 3, 0, 0); | ||
| 962 | fgSizer5->AddGrowableCol(1); | ||
| 963 | fgSizer5->SetFlexibleDirection(wxBOTH); | ||
| 964 | fgSizer5->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); | ||
| 965 | |||
| 966 | m_staticText24 = new wxStaticText(m_scrolledWindow, wxID_ANY, wxT("Label"), wxDefaultPosition, wxDefaultSize, 0); | ||
| 967 | m_staticText24->Wrap(-1); | ||
| 968 | fgSizer5->Add(m_staticText24, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT, 5); | ||
| 969 | |||
| 970 | m_staticText25 = new wxStaticText(m_scrolledWindow, wxID_ANY, wxT("Comma separated list of choices, or leave blank for text field"), wxDefaultPosition, wxDefaultSize, 0); | ||
| 971 | m_staticText25->Wrap(-1); | ||
| 972 | fgSizer5->Add(m_staticText25, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT, 5); | ||
| 973 | |||
| 974 | |||
| 975 | fgSizer5->Add(0, 0, 1, wxEXPAND, 5); | ||
| 976 | |||
| 977 | m_textCtrlLabel0 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); | ||
| 978 | m_textCtrlLabel0->SetMinSize(wxSize(150,-1)); | ||
| 979 | |||
| 980 | fgSizer5->Add(m_textCtrlLabel0, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); | ||
| 981 | |||
| 982 | m_textCtrlField0 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); | ||
| 983 | fgSizer5->Add(m_textCtrlField0, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); | ||
| 984 | |||
| 985 | m_buttonDel0 = new wxButton(m_scrolledWindow, wxID_DEL0, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); | ||
| 986 | fgSizer5->Add(m_buttonDel0, 0, wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5); | ||
| 987 | |||
| 988 | m_textCtrlLabel1 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); | ||
| 989 | m_textCtrlLabel1->SetMinSize(wxSize(150,-1)); | ||
| 990 | |||
| 991 | fgSizer5->Add(m_textCtrlLabel1, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); | ||
| 992 | |||
| 993 | m_textCtrlField1 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); | ||
| 994 | fgSizer5->Add(m_textCtrlField1, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); | ||
| 995 | |||
| 996 | m_buttonDel1 = new wxButton(m_scrolledWindow, wxID_DEL1, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); | ||
| 997 | fgSizer5->Add(m_buttonDel1, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); | ||
| 998 | |||
| 999 | m_textCtrlLabel2 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); | ||
| 1000 | m_textCtrlLabel2->SetMinSize(wxSize(150,-1)); | ||
| 1001 | |||
| 1002 | fgSizer5->Add(m_textCtrlLabel2, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); | ||
| 1003 | |||
| 1004 | m_textCtrlField2 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); | ||
| 1005 | fgSizer5->Add(m_textCtrlField2, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); | ||
| 1006 | |||
| 1007 | m_buttonDel2 = new wxButton(m_scrolledWindow, wxID_DEL2, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); | ||
| 1008 | fgSizer5->Add(m_buttonDel2, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); | ||
| 1009 | |||
| 1010 | m_textCtrlLabel3 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); | ||
| 1011 | m_textCtrlLabel3->SetMinSize(wxSize(150,-1)); | ||
| 1012 | |||
| 1013 | fgSizer5->Add(m_textCtrlLabel3, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); | ||
| 1014 | |||
| 1015 | m_textCtrlField3 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); | ||
| 1016 | fgSizer5->Add(m_textCtrlField3, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); | ||
| 1017 | |||
| 1018 | m_buttonDel3 = new wxButton(m_scrolledWindow, wxID_DEL3, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); | ||
| 1019 | fgSizer5->Add(m_buttonDel3, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); | ||
| 1020 | |||
| 1021 | m_textCtrlLabel4 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); | ||
| 1022 | m_textCtrlLabel4->SetMinSize(wxSize(150,-1)); | ||
| 1023 | |||
| 1024 | fgSizer5->Add(m_textCtrlLabel4, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); | ||
| 1025 | |||
| 1026 | m_textCtrlField4 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); | ||
| 1027 | fgSizer5->Add(m_textCtrlField4, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); | ||
| 1028 | |||
| 1029 | m_buttonDel4 = new wxButton(m_scrolledWindow, wxID_DEL4, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); | ||
| 1030 | fgSizer5->Add(m_buttonDel4, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); | ||
| 1031 | |||
| 1032 | m_textCtrlLabel5 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); | ||
| 1033 | m_textCtrlLabel5->SetMinSize(wxSize(150,-1)); | ||
| 1034 | |||
| 1035 | fgSizer5->Add(m_textCtrlLabel5, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); | ||
| 1036 | |||
| 1037 | m_textCtrlField5 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); | ||
| 1038 | fgSizer5->Add(m_textCtrlField5, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); | ||
| 1039 | |||
| 1040 | m_buttonDel5 = new wxButton(m_scrolledWindow, wxID_DEL5, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); | ||
| 1041 | fgSizer5->Add(m_buttonDel5, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); | ||
| 1042 | |||
| 1043 | m_textCtrlLabel6 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); | ||
| 1044 | m_textCtrlLabel6->SetMinSize(wxSize(150,-1)); | ||
| 1045 | |||
| 1046 | fgSizer5->Add(m_textCtrlLabel6, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); | ||
| 1047 | |||
| 1048 | m_textCtrlField6 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); | ||
| 1049 | fgSizer5->Add(m_textCtrlField6, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); | ||
| 1050 | |||
| 1051 | m_buttonDel6 = new wxButton(m_scrolledWindow, wxID_DEL6, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); | ||
| 1052 | fgSizer5->Add(m_buttonDel6, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); | ||
| 1053 | |||
| 1054 | m_textCtrlLabel7 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); | ||
| 1055 | m_textCtrlLabel7->SetMinSize(wxSize(150,-1)); | ||
| 1056 | |||
| 1057 | fgSizer5->Add(m_textCtrlLabel7, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); | ||
| 1058 | |||
| 1059 | m_textCtrlField7 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); | ||
| 1060 | fgSizer5->Add(m_textCtrlField7, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); | ||
| 1061 | |||
| 1062 | m_buttonDel7 = new wxButton(m_scrolledWindow, wxID_DEL7, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); | ||
| 1063 | fgSizer5->Add(m_buttonDel7, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); | ||
| 1064 | |||
| 1065 | m_textCtrlLabel8 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); | ||
| 1066 | m_textCtrlLabel8->SetMinSize(wxSize(150,-1)); | ||
| 1067 | |||
| 1068 | fgSizer5->Add(m_textCtrlLabel8, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); | ||
| 1069 | |||
| 1070 | m_textCtrlField8 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); | ||
| 1071 | fgSizer5->Add(m_textCtrlField8, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); | ||
| 1072 | |||
| 1073 | m_buttonDel8 = new wxButton(m_scrolledWindow, wxID_DEL8, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); | ||
| 1074 | fgSizer5->Add(m_buttonDel8, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); | ||
| 1075 | |||
| 1076 | m_textCtrlLabel9 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); | ||
| 1077 | m_textCtrlLabel9->SetMinSize(wxSize(150,-1)); | ||
| 1078 | |||
| 1079 | fgSizer5->Add(m_textCtrlLabel9, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); | ||
| 1080 | |||
| 1081 | m_textCtrlField9 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); | ||
| 1082 | fgSizer5->Add(m_textCtrlField9, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); | ||
| 1083 | |||
| 1084 | m_buttonDel9 = new wxButton(m_scrolledWindow, wxID_DEL9, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); | ||
| 1085 | fgSizer5->Add(m_buttonDel9, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); | ||
| 1086 | |||
| 1087 | m_textCtrlLabel10 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); | ||
| 1088 | m_textCtrlLabel10->SetMinSize(wxSize(150,-1)); | ||
| 1089 | |||
| 1090 | fgSizer5->Add(m_textCtrlLabel10, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); | ||
| 1091 | |||
| 1092 | m_textCtrlField10 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); | ||
| 1093 | fgSizer5->Add(m_textCtrlField10, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); | ||
| 1094 | |||
| 1095 | m_buttonDel10 = new wxButton(m_scrolledWindow, wxID_DEL10, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); | ||
| 1096 | fgSizer5->Add(m_buttonDel10, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); | ||
| 1097 | |||
| 1098 | m_textCtrlLabel11 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); | ||
| 1099 | m_textCtrlLabel11->SetMinSize(wxSize(150,-1)); | ||
| 1100 | |||
| 1101 | fgSizer5->Add(m_textCtrlLabel11, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); | ||
| 1102 | |||
| 1103 | m_textCtrlField11 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); | ||
| 1104 | fgSizer5->Add(m_textCtrlField11, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); | ||
| 1105 | |||
| 1106 | m_buttonDel11 = new wxButton(m_scrolledWindow, wxID_DEL11, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); | ||
| 1107 | fgSizer5->Add(m_buttonDel11, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); | ||
| 1108 | |||
| 1109 | m_textCtrlLabel12 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); | ||
| 1110 | m_textCtrlLabel12->SetMinSize(wxSize(150,-1)); | ||
| 1111 | |||
| 1112 | fgSizer5->Add(m_textCtrlLabel12, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); | ||
| 1113 | |||
| 1114 | m_textCtrlField12 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); | ||
| 1115 | fgSizer5->Add(m_textCtrlField12, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); | ||
| 1116 | |||
| 1117 | m_buttonDel12 = new wxButton(m_scrolledWindow, wxID_DEL12, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); | ||
| 1118 | fgSizer5->Add(m_buttonDel12, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); | ||
| 1119 | |||
| 1120 | m_textCtrlLabel13 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); | ||
| 1121 | m_textCtrlLabel13->SetMinSize(wxSize(150,-1)); | ||
| 1122 | |||
| 1123 | fgSizer5->Add(m_textCtrlLabel13, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); | ||
| 1124 | |||
| 1125 | m_textCtrlField13 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); | ||
| 1126 | fgSizer5->Add(m_textCtrlField13, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); | ||
| 1127 | |||
| 1128 | m_buttonDel13 = new wxButton(m_scrolledWindow, wxID_DEL13, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); | ||
| 1129 | fgSizer5->Add(m_buttonDel13, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); | ||
| 1130 | |||
| 1131 | m_textCtrlLabel14 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); | ||
| 1132 | m_textCtrlLabel14->SetMinSize(wxSize(150,-1)); | ||
| 1133 | |||
| 1134 | fgSizer5->Add(m_textCtrlLabel14, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); | ||
| 1135 | |||
| 1136 | m_textCtrlField14 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); | ||
| 1137 | fgSizer5->Add(m_textCtrlField14, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); | ||
| 1138 | |||
| 1139 | m_buttonDel14 = new wxButton(m_scrolledWindow, wxID_DEL14, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); | ||
| 1140 | fgSizer5->Add(m_buttonDel14, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); | ||
| 1141 | |||
| 1142 | m_textCtrlLabel15 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); | ||
| 1143 | m_textCtrlLabel15->SetMinSize(wxSize(150,-1)); | ||
| 1144 | |||
| 1145 | fgSizer5->Add(m_textCtrlLabel15, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); | ||
| 1146 | |||
| 1147 | m_textCtrlField15 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); | ||
| 1148 | fgSizer5->Add(m_textCtrlField15, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); | ||
| 1149 | |||
| 1150 | m_buttonDel15 = new wxButton(m_scrolledWindow, wxID_DEL15, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); | ||
| 1151 | fgSizer5->Add(m_buttonDel15, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); | ||
| 1152 | |||
| 1153 | m_textCtrlLabel16 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); | ||
| 1154 | m_textCtrlLabel16->SetMinSize(wxSize(150,-1)); | ||
| 1155 | |||
| 1156 | fgSizer5->Add(m_textCtrlLabel16, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); | ||
| 1157 | |||
| 1158 | m_textCtrlField16 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); | ||
| 1159 | fgSizer5->Add(m_textCtrlField16, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); | ||
| 1160 | |||
| 1161 | m_buttonDel16 = new wxButton(m_scrolledWindow, wxID_DEL16, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); | ||
| 1162 | fgSizer5->Add(m_buttonDel16, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); | ||
| 1163 | |||
| 1164 | m_textCtrlLabel17 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); | ||
| 1165 | m_textCtrlLabel17->SetMinSize(wxSize(150,-1)); | ||
| 1166 | |||
| 1167 | fgSizer5->Add(m_textCtrlLabel17, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); | ||
| 1168 | |||
| 1169 | m_textCtrlField17 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); | ||
| 1170 | fgSizer5->Add(m_textCtrlField17, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); | ||
| 1171 | |||
| 1172 | m_buttonDel17 = new wxButton(m_scrolledWindow, wxID_DEL17, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); | ||
| 1173 | fgSizer5->Add(m_buttonDel17, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); | ||
| 1174 | |||
| 1175 | m_textCtrlLabel18 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); | ||
| 1176 | m_textCtrlLabel18->SetMinSize(wxSize(150,-1)); | ||
| 1177 | |||
| 1178 | fgSizer5->Add(m_textCtrlLabel18, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); | ||
| 1179 | |||
| 1180 | m_textCtrlField18 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); | ||
| 1181 | fgSizer5->Add(m_textCtrlField18, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); | ||
| 1182 | |||
| 1183 | m_buttonDel18 = new wxButton(m_scrolledWindow, wxID_DEL18, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); | ||
| 1184 | fgSizer5->Add(m_buttonDel18, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); | ||
| 1185 | |||
| 1186 | m_textCtrlLabel19 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); | ||
| 1187 | m_textCtrlLabel19->SetMinSize(wxSize(150,-1)); | ||
| 1188 | |||
| 1189 | fgSizer5->Add(m_textCtrlLabel19, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); | ||
| 1190 | |||
| 1191 | m_textCtrlField19 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); | ||
| 1192 | fgSizer5->Add(m_textCtrlField19, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); | ||
| 1193 | |||
| 1194 | m_buttonDel19 = new wxButton(m_scrolledWindow, wxID_DEL19, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); | ||
| 1195 | fgSizer5->Add(m_buttonDel19, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); | ||
| 1196 | |||
| 1197 | bSizer21->Add(fgSizer5, 0, wxEXPAND, 5); | ||
| 1198 | |||
| 1199 | wxBoxSizer* bSizer25; | ||
| 1200 | bSizer25 = new wxBoxSizer(wxHORIZONTAL); | ||
| 1201 | |||
| 1202 | m_buttonAddField = new wxButton(m_scrolledWindow, wxID_ANY, wxT("&Add Field"), wxDefaultPosition, wxDefaultSize, 0); | ||
| 1203 | bSizer25->Add(m_buttonAddField, 0, wxALL, 5); | ||
| 1204 | |||
| 1205 | bSizer21->Add(bSizer25, 0, wxALIGN_CENTER_HORIZONTAL, 5); | ||
| 1206 | |||
| 1207 | m_scrolledWindow->SetSizer(bSizer21); | ||
| 1208 | m_scrolledWindow->Layout(); | ||
| 1209 | bSizer21->Fit(m_scrolledWindow); | ||
| 1210 | bSizer20->Add(m_scrolledWindow, 1, wxEXPAND|wxALL, 5); | ||
| 1211 | |||
| 1212 | wxBoxSizer* bSizer26; | ||
| 1213 | bSizer26 = new wxBoxSizer(wxHORIZONTAL); | ||
| 1214 | |||
| 1215 | m_buttonOK = new wxButton(this, wxID_BUTTONSEND, wxT("&Send"), wxDefaultPosition, wxDefaultSize, 0); | ||
| 1216 | m_buttonOK->SetMinSize(wxSize(85,25)); | ||
| 1217 | |||
| 1218 | bSizer26->Add(m_buttonOK, 0, wxALL, 5); | ||
| 1219 | |||
| 1220 | m_buttonPreview = new wxButton(this, wxID_BUTTONPREVIEW, wxT("&Preview"), wxDefaultPosition, wxDefaultSize, 0); | ||
| 1221 | m_buttonPreview->SetMinSize(wxSize(85,25)); | ||
| 1222 | |||
| 1223 | bSizer26->Add(m_buttonPreview, 0, wxALL, 5); | ||
| 1224 | |||
| 1225 | m_buttonCancel = new wxButton(this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0); | ||
| 1226 | m_buttonCancel->SetMinSize(wxSize(85,25)); | ||
| 1227 | |||
| 1228 | bSizer26->Add(m_buttonCancel, 0, wxALL, 5); | ||
| 1229 | |||
| 1230 | bSizer20->Add(bSizer26, 0, wxALIGN_RIGHT, 5); | ||
| 1231 | |||
| 1232 | this->SetSizer(bSizer20); | ||
| 1233 | this->Layout(); | ||
| 1234 | |||
| 1235 | // Connect Events | ||
| 1236 | m_textCtrlTitle->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1237 | m_textCtrlPrice->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1238 | m_textCtrlDescription->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1239 | m_textCtrlInstructions->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1240 | m_textCtrlLabel0->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1241 | m_textCtrlField0->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1242 | m_buttonDel0->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel0), NULL, this); | ||
| 1243 | m_textCtrlLabel1->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1244 | m_textCtrlField1->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1245 | m_buttonDel1->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel1), NULL, this); | ||
| 1246 | m_textCtrlLabel2->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1247 | m_textCtrlField2->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1248 | m_buttonDel2->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel2), NULL, this); | ||
| 1249 | m_textCtrlLabel3->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1250 | m_textCtrlField3->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1251 | m_buttonDel3->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel3), NULL, this); | ||
| 1252 | m_textCtrlLabel4->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1253 | m_textCtrlField4->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1254 | m_buttonDel4->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel4), NULL, this); | ||
| 1255 | m_textCtrlLabel5->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1256 | m_textCtrlField5->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1257 | m_buttonDel5->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel5), NULL, this); | ||
| 1258 | m_textCtrlLabel6->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1259 | m_textCtrlField6->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1260 | m_buttonDel6->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel6), NULL, this); | ||
| 1261 | m_textCtrlLabel7->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1262 | m_textCtrlField7->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1263 | m_buttonDel7->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel7), NULL, this); | ||
| 1264 | m_textCtrlLabel8->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1265 | m_textCtrlField8->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1266 | m_buttonDel8->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel8), NULL, this); | ||
| 1267 | m_textCtrlLabel9->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1268 | m_textCtrlField9->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1269 | m_buttonDel9->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel9), NULL, this); | ||
| 1270 | m_textCtrlLabel10->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1271 | m_textCtrlField10->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1272 | m_buttonDel10->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel10), NULL, this); | ||
| 1273 | m_textCtrlLabel11->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1274 | m_textCtrlField11->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1275 | m_buttonDel11->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel11), NULL, this); | ||
| 1276 | m_textCtrlLabel12->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1277 | m_textCtrlField12->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1278 | m_buttonDel12->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel12), NULL, this); | ||
| 1279 | m_textCtrlLabel13->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1280 | m_textCtrlField13->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1281 | m_buttonDel13->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel13), NULL, this); | ||
| 1282 | m_textCtrlLabel14->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1283 | m_textCtrlField14->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1284 | m_buttonDel14->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel14), NULL, this); | ||
| 1285 | m_textCtrlLabel15->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1286 | m_textCtrlField15->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1287 | m_buttonDel15->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel15), NULL, this); | ||
| 1288 | m_textCtrlLabel16->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1289 | m_textCtrlField16->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1290 | m_buttonDel16->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel16), NULL, this); | ||
| 1291 | m_textCtrlLabel17->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1292 | m_textCtrlField17->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1293 | m_buttonDel17->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel17), NULL, this); | ||
| 1294 | m_textCtrlLabel18->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1295 | m_textCtrlField18->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1296 | m_buttonDel18->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel18), NULL, this); | ||
| 1297 | m_textCtrlLabel19->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1298 | m_textCtrlField19->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1299 | m_buttonDel19->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel19), NULL, this); | ||
| 1300 | m_buttonAddField->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonAddField), NULL, this); | ||
| 1301 | m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonSend), NULL, this); | ||
| 1302 | m_buttonPreview->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonPreview), NULL, this); | ||
| 1303 | m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonCancel), NULL, this); | ||
| 1304 | } | ||
| 1305 | |||
| 1306 | CEditProductDialogBase::~CEditProductDialogBase() | ||
| 1307 | { | ||
| 1308 | // Disconnect Events | ||
| 1309 | m_textCtrlTitle->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1310 | m_textCtrlPrice->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1311 | m_textCtrlDescription->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1312 | m_textCtrlInstructions->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1313 | m_textCtrlLabel0->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1314 | m_textCtrlField0->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1315 | m_buttonDel0->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel0), NULL, this); | ||
| 1316 | m_textCtrlLabel1->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1317 | m_textCtrlField1->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1318 | m_buttonDel1->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel1), NULL, this); | ||
| 1319 | m_textCtrlLabel2->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1320 | m_textCtrlField2->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1321 | m_buttonDel2->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel2), NULL, this); | ||
| 1322 | m_textCtrlLabel3->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1323 | m_textCtrlField3->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1324 | m_buttonDel3->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel3), NULL, this); | ||
| 1325 | m_textCtrlLabel4->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1326 | m_textCtrlField4->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1327 | m_buttonDel4->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel4), NULL, this); | ||
| 1328 | m_textCtrlLabel5->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1329 | m_textCtrlField5->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1330 | m_buttonDel5->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel5), NULL, this); | ||
| 1331 | m_textCtrlLabel6->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1332 | m_textCtrlField6->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1333 | m_buttonDel6->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel6), NULL, this); | ||
| 1334 | m_textCtrlLabel7->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1335 | m_textCtrlField7->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1336 | m_buttonDel7->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel7), NULL, this); | ||
| 1337 | m_textCtrlLabel8->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1338 | m_textCtrlField8->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1339 | m_buttonDel8->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel8), NULL, this); | ||
| 1340 | m_textCtrlLabel9->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1341 | m_textCtrlField9->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1342 | m_buttonDel9->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel9), NULL, this); | ||
| 1343 | m_textCtrlLabel10->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1344 | m_textCtrlField10->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1345 | m_buttonDel10->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel10), NULL, this); | ||
| 1346 | m_textCtrlLabel11->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1347 | m_textCtrlField11->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1348 | m_buttonDel11->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel11), NULL, this); | ||
| 1349 | m_textCtrlLabel12->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1350 | m_textCtrlField12->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1351 | m_buttonDel12->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel12), NULL, this); | ||
| 1352 | m_textCtrlLabel13->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1353 | m_textCtrlField13->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1354 | m_buttonDel13->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel13), NULL, this); | ||
| 1355 | m_textCtrlLabel14->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1356 | m_textCtrlField14->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1357 | m_buttonDel14->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel14), NULL, this); | ||
| 1358 | m_textCtrlLabel15->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1359 | m_textCtrlField15->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1360 | m_buttonDel15->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel15), NULL, this); | ||
| 1361 | m_textCtrlLabel16->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1362 | m_textCtrlField16->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1363 | m_buttonDel16->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel16), NULL, this); | ||
| 1364 | m_textCtrlLabel17->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1365 | m_textCtrlField17->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1366 | m_buttonDel17->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel17), NULL, this); | ||
| 1367 | m_textCtrlLabel18->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1368 | m_textCtrlField18->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1369 | m_buttonDel18->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel18), NULL, this); | ||
| 1370 | m_textCtrlLabel19->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1371 | m_textCtrlField19->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); | ||
| 1372 | m_buttonDel19->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel19), NULL, this); | ||
| 1373 | m_buttonAddField->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonAddField), NULL, this); | ||
| 1374 | m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonSend), NULL, this); | ||
| 1375 | m_buttonPreview->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonPreview), NULL, this); | ||
| 1376 | m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonCancel), NULL, this); | ||
| 1377 | } | ||
| 1378 | |||
| 1379 | CViewProductDialogBase::CViewProductDialogBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxFrame(parent, id, title, pos, size, style) | ||
| 1380 | { | ||
| 1381 | this->SetSizeHints(wxDefaultSize, wxDefaultSize); | ||
| 1382 | this->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_MENU)); | ||
| 1383 | |||
| 1384 | wxBoxSizer* bSizer20; | ||
| 1385 | bSizer20 = new wxBoxSizer(wxVERTICAL); | ||
| 1386 | |||
| 1387 | wxBoxSizer* bSizer116; | ||
| 1388 | bSizer116 = new wxBoxSizer(wxHORIZONTAL); | ||
| 1389 | |||
| 1390 | m_htmlWinReviews = new wxHtmlWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO); | ||
| 1391 | m_htmlWinReviews->Hide(); | ||
| 1392 | |||
| 1393 | bSizer116->Add(m_htmlWinReviews, 1, wxALL|wxEXPAND, 5); | ||
| 1394 | |||
| 1395 | m_scrolledWindow = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxTAB_TRAVERSAL|wxVSCROLL); | ||
| 1396 | m_scrolledWindow->SetScrollRate(5, 5); | ||
| 1397 | m_scrolledWindow->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); | ||
| 1398 | |||
| 1399 | wxBoxSizer* bSizer21; | ||
| 1400 | bSizer21 = new wxBoxSizer(wxVERTICAL); | ||
| 1401 | |||
| 1402 | m_richTextHeading = new wxRichTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,50), wxTE_READONLY|wxNO_BORDER); | ||
| 1403 | bSizer21->Add(m_richTextHeading, 0, wxEXPAND, 5); | ||
| 1404 | |||
| 1405 | m_staticTextInstructions = new wxStaticText(m_scrolledWindow, wxID_ANY, wxT("Order Form instructions here\nmultiple lines\n1\n2\n3\n4\n5\n6"), wxDefaultPosition, wxDefaultSize, 0); | ||
| 1406 | m_staticTextInstructions->Wrap(-1); | ||
| 1407 | bSizer21->Add(m_staticTextInstructions, 0, wxALL|wxEXPAND, 5); | ||
| 1408 | |||
| 1409 | wxBoxSizer* bSizer25; | ||
| 1410 | bSizer25 = new wxBoxSizer(wxHORIZONTAL); | ||
| 1411 | |||
| 1412 | m_buttonSubmitForm = new wxButton(m_scrolledWindow, wxID_BUTTONSAMPLE, wxT("&Submit"), wxDefaultPosition, wxDefaultSize, 0); | ||
| 1413 | bSizer25->Add(m_buttonSubmitForm, 0, wxALL, 5); | ||
| 1414 | |||
| 1415 | m_buttonCancelForm = new wxButton(m_scrolledWindow, wxID_CANCEL2, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0); | ||
| 1416 | bSizer25->Add(m_buttonCancelForm, 0, wxALL, 5); | ||
| 1417 | |||
| 1418 | bSizer21->Add(bSizer25, 0, wxALIGN_CENTER_HORIZONTAL, 5); | ||
| 1419 | |||
| 1420 | m_scrolledWindow->SetSizer(bSizer21); | ||
| 1421 | m_scrolledWindow->Layout(); | ||
| 1422 | bSizer21->Fit(m_scrolledWindow); | ||
| 1423 | bSizer116->Add(m_scrolledWindow, 1, wxEXPAND|wxALL, 5); | ||
| 1424 | |||
| 1425 | bSizer20->Add(bSizer116, 1, wxEXPAND, 5); | ||
| 1426 | |||
| 1427 | wxBoxSizer* bSizer26; | ||
| 1428 | bSizer26 = new wxBoxSizer(wxHORIZONTAL); | ||
| 1429 | |||
| 1430 | m_buttonBack = new wxButton(this, wxID_BUTTONBACK, wxT("< &Back "), wxDefaultPosition, wxDefaultSize, 0); | ||
| 1431 | m_buttonBack->Enable(false); | ||
| 1432 | m_buttonBack->SetMinSize(wxSize(85,25)); | ||
| 1433 | |||
| 1434 | bSizer26->Add(m_buttonBack, 0, wxALL, 5); | ||
| 1435 | |||
| 1436 | m_buttonNext = new wxButton(this, wxID_BUTTONNEXT, wxT(" &Next >"), wxDefaultPosition, wxDefaultSize, 0); | ||
| 1437 | m_buttonNext->SetMinSize(wxSize(85,25)); | ||
| 1438 | |||
| 1439 | bSizer26->Add(m_buttonNext, 0, wxALL, 5); | ||
| 1440 | |||
| 1441 | m_buttonCancel = new wxButton(this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0); | ||
| 1442 | m_buttonCancel->SetMinSize(wxSize(85,25)); | ||
| 1443 | |||
| 1444 | bSizer26->Add(m_buttonCancel, 0, wxALL, 5); | ||
| 1445 | |||
| 1446 | bSizer20->Add(bSizer26, 0, wxALIGN_RIGHT, 5); | ||
| 1447 | |||
| 1448 | this->SetSizer(bSizer20); | ||
| 1449 | this->Layout(); | ||
| 1450 | |||
| 1451 | // Connect Events | ||
| 1452 | m_buttonSubmitForm->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonSubmitForm), NULL, this); | ||
| 1453 | m_buttonCancelForm->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonCancelForm), NULL, this); | ||
| 1454 | m_buttonBack->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonBack), NULL, this); | ||
| 1455 | m_buttonNext->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonNext), NULL, this); | ||
| 1456 | m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonCancel), NULL, this); | ||
| 1457 | } | ||
| 1458 | |||
| 1459 | CViewProductDialogBase::~CViewProductDialogBase() | ||
| 1460 | { | ||
| 1461 | // Disconnect Events | ||
| 1462 | m_buttonSubmitForm->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonSubmitForm), NULL, this); | ||
| 1463 | m_buttonCancelForm->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonCancelForm), NULL, this); | ||
| 1464 | m_buttonBack->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonBack), NULL, this); | ||
| 1465 | m_buttonNext->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonNext), NULL, this); | ||
| 1466 | m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonCancel), NULL, this); | ||
| 1467 | } | ||
| 1468 | |||
| 1469 | CViewOrderDialogBase::CViewOrderDialogBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxFrame(parent, id, title, pos, size, style) | ||
| 1470 | { | ||
| 1471 | this->SetSizeHints(wxDefaultSize, wxDefaultSize); | ||
| 1472 | this->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_MENU)); | ||
| 1473 | |||
| 1474 | wxBoxSizer* bSizer20; | ||
| 1475 | bSizer20 = new wxBoxSizer(wxVERTICAL); | ||
| 1476 | |||
| 1477 | wxBoxSizer* bSizer116; | ||
| 1478 | bSizer116 = new wxBoxSizer(wxHORIZONTAL); | ||
| 1479 | |||
| 1480 | m_htmlWin = new wxHtmlWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO); | ||
| 1481 | bSizer116->Add(m_htmlWin, 1, wxALL|wxEXPAND, 5); | ||
| 1482 | |||
| 1483 | bSizer20->Add(bSizer116, 1, wxEXPAND, 5); | ||
| 1484 | |||
| 1485 | wxBoxSizer* bSizer26; | ||
| 1486 | bSizer26 = new wxBoxSizer(wxHORIZONTAL); | ||
| 1487 | |||
| 1488 | m_buttonOK = new wxButton(this, wxID_OK, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0); | ||
| 1489 | m_buttonOK->SetMinSize(wxSize(85,25)); | ||
| 1490 | |||
| 1491 | bSizer26->Add(m_buttonOK, 0, wxALL, 5); | ||
| 1492 | |||
| 1493 | bSizer20->Add(bSizer26, 0, wxALIGN_RIGHT, 5); | ||
| 1494 | |||
| 1495 | this->SetSizer(bSizer20); | ||
| 1496 | this->Layout(); | ||
| 1497 | |||
| 1498 | // Connect Events | ||
| 1499 | m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewOrderDialogBase::OnButtonOK), NULL, this); | ||
| 1500 | } | ||
| 1501 | |||
| 1502 | CViewOrderDialogBase::~CViewOrderDialogBase() | ||
| 1503 | { | ||
| 1504 | // Disconnect Events | ||
| 1505 | m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewOrderDialogBase::OnButtonOK), NULL, this); | ||
| 1506 | } | ||
| 1507 | |||
| 1508 | CEditReviewDialogBase::CEditReviewDialogBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxFrame(parent, id, title, pos, size, style) | ||
| 1509 | { | ||
| 1510 | this->SetSizeHints(wxDefaultSize, wxDefaultSize); | ||
| 1511 | this->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_MENU)); | ||
| 1512 | |||
| 1513 | wxBoxSizer* bSizer112; | ||
| 1514 | bSizer112 = new wxBoxSizer(wxVERTICAL); | ||
| 1515 | |||
| 1516 | |||
| 1517 | bSizer112->Add(0, 3, 0, 0, 5); | ||
| 1518 | |||
| 1519 | m_staticTextSeller = new wxStaticText(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); | ||
| 1520 | m_staticTextSeller->Wrap(-1); | ||
| 1521 | bSizer112->Add(m_staticTextSeller, 0, wxALL|wxEXPAND, 5); | ||
| 1522 | |||
| 1523 | |||
| 1524 | bSizer112->Add(0, 3, 0, 0, 5); | ||
| 1525 | |||
| 1526 | m_staticText110 = new wxStaticText(this, wxID_ANY, wxT("Rating"), wxDefaultPosition, wxDefaultSize, 0); | ||
| 1527 | m_staticText110->Wrap(-1); | ||
| 1528 | bSizer112->Add(m_staticText110, 0, wxTOP|wxRIGHT|wxLEFT, 5); | ||
| 1529 | |||
| 1530 | wxString m_choiceStarsChoices[] = { wxT(" 1 star"), wxT(" 2 stars"), wxT(" 3 stars"), wxT(" 4 stars"), wxT(" 5 stars") }; | ||
| 1531 | int m_choiceStarsNChoices = sizeof(m_choiceStarsChoices) / sizeof(wxString); | ||
| 1532 | m_choiceStars = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choiceStarsNChoices, m_choiceStarsChoices, 0); | ||
| 1533 | m_choiceStars->SetSelection(0); | ||
| 1534 | bSizer112->Add(m_choiceStars, 0, wxALL, 5); | ||
| 1535 | |||
| 1536 | m_staticText43 = new wxStaticText(this, wxID_ANY, wxT("Review"), wxDefaultPosition, wxDefaultSize, 0); | ||
| 1537 | m_staticText43->Wrap(-1); | ||
| 1538 | bSizer112->Add(m_staticText43, 0, wxTOP|wxRIGHT|wxLEFT, 5); | ||
| 1539 | |||
| 1540 | m_textCtrlReview = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE); | ||
| 1541 | bSizer112->Add(m_textCtrlReview, 1, wxALL|wxEXPAND, 5); | ||
| 1542 | |||
| 1543 | wxBoxSizer* bSizer113; | ||
| 1544 | bSizer113 = new wxBoxSizer(wxHORIZONTAL); | ||
| 1545 | |||
| 1546 | m_buttonSubmit = new wxButton(this, wxID_SUBMIT, wxT("&Submit"), wxDefaultPosition, wxDefaultSize, 0); | ||
| 1547 | m_buttonSubmit->SetMinSize(wxSize(85,25)); | ||
| 1548 | |||
| 1549 | bSizer113->Add(m_buttonSubmit, 0, wxALL, 5); | ||
| 1550 | |||
| 1551 | m_buttonCancel = new wxButton(this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0); | ||
| 1552 | m_buttonCancel->SetMinSize(wxSize(85,25)); | ||
| 1553 | |||
| 1554 | bSizer113->Add(m_buttonCancel, 0, wxALL, 5); | ||
| 1555 | |||
| 1556 | bSizer112->Add(bSizer113, 0, wxALIGN_RIGHT, 5); | ||
| 1557 | |||
| 1558 | this->SetSizer(bSizer112); | ||
| 1559 | this->Layout(); | ||
| 1560 | |||
| 1561 | // Connect Events | ||
| 1562 | m_textCtrlReview->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditReviewDialogBase::OnKeyDown), NULL, this); | ||
| 1563 | m_buttonSubmit->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditReviewDialogBase::OnButtonSubmit), NULL, this); | ||
| 1564 | m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditReviewDialogBase::OnButtonCancel), NULL, this); | ||
| 1565 | } | ||
| 1566 | |||
| 1567 | CEditReviewDialogBase::~CEditReviewDialogBase() | ||
| 1568 | { | ||
| 1569 | // Disconnect Events | ||
| 1570 | m_textCtrlReview->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditReviewDialogBase::OnKeyDown), NULL, this); | ||
| 1571 | m_buttonSubmit->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditReviewDialogBase::OnButtonSubmit), NULL, this); | ||
| 1572 | m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditReviewDialogBase::OnButtonCancel), NULL, this); | ||
| 1573 | } | ||
| 1574 | |||
| 1575 | CPokerLobbyDialogBase::CPokerLobbyDialogBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxFrame(parent, id, title, pos, size, style) | ||
| 1576 | { | ||
| 1577 | this->SetSizeHints(wxDefaultSize, wxDefaultSize); | ||
| 1578 | this->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)); | ||
| 1579 | |||
| 1580 | wxBoxSizer* bSizer156; | ||
| 1581 | bSizer156 = new wxBoxSizer(wxHORIZONTAL); | ||
| 1582 | |||
| 1583 | m_treeCtrl = new wxTreeCtrl(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTR_HAS_BUTTONS|wxTR_HIDE_ROOT|wxTR_LINES_AT_ROOT); | ||
| 1584 | m_treeCtrl->SetMinSize(wxSize(130,-1)); | ||
| 1585 | |||
| 1586 | bSizer156->Add(m_treeCtrl, 0, wxEXPAND|wxTOP|wxBOTTOM|wxLEFT, 5); | ||
| 1587 | |||
| 1588 | wxBoxSizer* bSizer172; | ||
| 1589 | bSizer172 = new wxBoxSizer(wxVERTICAL); | ||
| 1590 | |||
| 1591 | m_listCtrl = new wxListCtrl(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT); | ||
| 1592 | bSizer172->Add(m_listCtrl, 1, wxEXPAND|wxALL, 5); | ||
| 1593 | |||
| 1594 | m_buttonNewTable = new wxButton(this, wxID_OPENNEWTABLE, wxT("&Open New Table"), wxDefaultPosition, wxDefaultSize, 0); | ||
| 1595 | bSizer172->Add(m_buttonNewTable, 0, wxALL, 5); | ||
| 1596 | |||
| 1597 | bSizer156->Add(bSizer172, 1, wxEXPAND, 5); | ||
| 1598 | |||
| 1599 | this->SetSizer(bSizer156); | ||
| 1600 | this->Layout(); | ||
| 1601 | |||
| 1602 | // Connect Events | ||
| 1603 | m_treeCtrl->Connect(wxEVT_COMMAND_TREE_SEL_CHANGED, wxTreeEventHandler(CPokerLobbyDialogBase::OnTreeSelChanged), NULL, this); | ||
| 1604 | m_listCtrl->Connect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CPokerLobbyDialogBase::OnListItemActivated), NULL, this); | ||
| 1605 | m_listCtrl->Connect(wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(CPokerLobbyDialogBase::OnListItemSelected), NULL, this); | ||
| 1606 | m_buttonNewTable->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerLobbyDialogBase::OnButtonNewTable), NULL, this); | ||
| 1607 | } | ||
| 1608 | |||
| 1609 | CPokerLobbyDialogBase::~CPokerLobbyDialogBase() | ||
| 1610 | { | ||
| 1611 | // Disconnect Events | ||
| 1612 | m_treeCtrl->Disconnect(wxEVT_COMMAND_TREE_SEL_CHANGED, wxTreeEventHandler(CPokerLobbyDialogBase::OnTreeSelChanged), NULL, this); | ||
| 1613 | m_listCtrl->Disconnect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CPokerLobbyDialogBase::OnListItemActivated), NULL, this); | ||
| 1614 | m_listCtrl->Disconnect(wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(CPokerLobbyDialogBase::OnListItemSelected), NULL, this); | ||
| 1615 | m_buttonNewTable->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerLobbyDialogBase::OnButtonNewTable), NULL, this); | ||
| 1616 | } | ||
| 1617 | |||
| 1618 | CPokerDialogBase::CPokerDialogBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxFrame(parent, id, title, pos, size, style) | ||
| 1619 | { | ||
| 1620 | this->SetSizeHints(wxDefaultSize, wxDefaultSize); | ||
| 1621 | |||
| 1622 | wxBoxSizer* bSizer174; | ||
| 1623 | bSizer174 = new wxBoxSizer(wxVERTICAL); | ||
| 1624 | |||
| 1625 | m_checkSitOut = new wxCheckBox(this, wxID_ANY, wxT("Deal Me Out"), wxDefaultPosition, wxDefaultSize, 0); | ||
| 1626 | |||
| 1627 | bSizer174->Add(m_checkSitOut, 0, wxALL, 5); | ||
| 1628 | |||
| 1629 | m_buttonDealHand = new wxButton(this, wxID_DEALHAND, wxT("&Deal Hand"), wxDefaultPosition, wxSize(150,25), 0); | ||
| 1630 | bSizer174->Add(m_buttonDealHand, 0, wxALL, 5); | ||
| 1631 | |||
| 1632 | m_buttonFold = new wxButton(this, wxID_FOLD, wxT("&Fold"), wxDefaultPosition, wxSize(80,25), 0); | ||
| 1633 | bSizer174->Add(m_buttonFold, 0, wxALL, 5); | ||
| 1634 | |||
| 1635 | m_buttonCall = new wxButton(this, wxID_CALL, wxT("&Call"), wxDefaultPosition, wxSize(80,25), 0); | ||
| 1636 | bSizer174->Add(m_buttonCall, 0, wxALL, 5); | ||
| 1637 | |||
| 1638 | m_buttonRaise = new wxButton(this, wxID_RAISE, wxT("&Raise"), wxDefaultPosition, wxSize(80,25), 0); | ||
| 1639 | bSizer174->Add(m_buttonRaise, 0, wxALL, 5); | ||
| 1640 | |||
| 1641 | m_buttonLeaveTable = new wxButton(this, wxID_LEAVETABLE, wxT("&Leave Table"), wxDefaultPosition, wxSize(90,25), 0); | ||
| 1642 | bSizer174->Add(m_buttonLeaveTable, 0, wxALL, 5); | ||
| 1643 | |||
| 1644 | m_textDitchPlayer = new wxTextCtrl(this, wxID_DITCHPLAYER, wxEmptyString, wxDefaultPosition, wxSize(45,-1), wxTE_PROCESS_ENTER); | ||
| 1645 | bSizer174->Add(m_textDitchPlayer, 0, wxALL, 5); | ||
| 1646 | |||
| 1647 | m_checkPreFold = new wxCheckBox(this, wxID_ANY, wxT("FOLD"), wxDefaultPosition, wxSize(100,-1), 0); | ||
| 1648 | |||
| 1649 | bSizer174->Add(m_checkPreFold, 0, wxALL, 5); | ||
| 1650 | |||
| 1651 | m_checkPreCall = new wxCheckBox(this, wxID_ANY, wxT("CALL"), wxDefaultPosition, wxSize(100,-1), 0); | ||
| 1652 | |||
| 1653 | bSizer174->Add(m_checkPreCall, 0, wxALL, 5); | ||
| 1654 | |||
| 1655 | m_checkPreCallAny = new wxCheckBox(this, wxID_ANY, wxT("CALL ANY"), wxDefaultPosition, wxSize(100,-1), 0); | ||
| 1656 | |||
| 1657 | bSizer174->Add(m_checkPreCallAny, 0, wxALL, 5); | ||
| 1658 | |||
| 1659 | m_checkPreRaise = new wxCheckBox(this, wxID_ANY, wxT("RAISE"), wxDefaultPosition, wxSize(100,-1), 0); | ||
| 1660 | |||
| 1661 | bSizer174->Add(m_checkPreRaise, 0, wxALL, 5); | ||
| 1662 | |||
| 1663 | m_checkPreRaiseAny = new wxCheckBox(this, wxID_ANY, wxT("RAISE ANY"), wxDefaultPosition, wxSize(100,-1), 0); | ||
| 1664 | |||
| 1665 | bSizer174->Add(m_checkPreRaiseAny, 0, wxALL, 5); | ||
| 1666 | |||
| 1667 | this->SetSizer(bSizer174); | ||
| 1668 | this->Layout(); | ||
| 1669 | m_statusBar = this->CreateStatusBar(1, wxST_SIZEGRIP, wxID_ANY); | ||
| 1670 | |||
| 1671 | // Connect Events | ||
| 1672 | this->Connect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(CPokerDialogBase::OnClose)); | ||
| 1673 | this->Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); | ||
| 1674 | this->Connect(wxEVT_LEFT_UP, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); | ||
| 1675 | this->Connect(wxEVT_MIDDLE_DOWN, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); | ||
| 1676 | this->Connect(wxEVT_MIDDLE_UP, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); | ||
| 1677 | this->Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); | ||
| 1678 | this->Connect(wxEVT_RIGHT_UP, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); | ||
| 1679 | this->Connect(wxEVT_MOTION, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); | ||
| 1680 | this->Connect(wxEVT_LEFT_DCLICK, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); | ||
| 1681 | this->Connect(wxEVT_MIDDLE_DCLICK, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); | ||
| 1682 | this->Connect(wxEVT_RIGHT_DCLICK, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); | ||
| 1683 | this->Connect(wxEVT_LEAVE_WINDOW, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); | ||
| 1684 | this->Connect(wxEVT_ENTER_WINDOW, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); | ||
| 1685 | this->Connect(wxEVT_MOUSEWHEEL, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); | ||
| 1686 | this->Connect(wxEVT_PAINT, wxPaintEventHandler(CPokerDialogBase::OnPaint)); | ||
| 1687 | this->Connect(wxEVT_SIZE, wxSizeEventHandler(CPokerDialogBase::OnSize)); | ||
| 1688 | m_checkSitOut->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckSitOut), NULL, this); | ||
| 1689 | m_buttonDealHand->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonDealHand), NULL, this); | ||
| 1690 | m_buttonFold->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonFold), NULL, this); | ||
| 1691 | m_buttonCall->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonCall), NULL, this); | ||
| 1692 | m_buttonRaise->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonRaise), NULL, this); | ||
| 1693 | m_buttonLeaveTable->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonLeaveTable), NULL, this); | ||
| 1694 | m_textDitchPlayer->Connect(wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler(CPokerDialogBase::OnDitchPlayer), NULL, this); | ||
| 1695 | m_checkPreFold->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreFold), NULL, this); | ||
| 1696 | m_checkPreCall->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreCall), NULL, this); | ||
| 1697 | m_checkPreCallAny->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreCallAny), NULL, this); | ||
| 1698 | m_checkPreRaise->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreRaise), NULL, this); | ||
| 1699 | m_checkPreRaiseAny->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreRaiseAny), NULL, this); | ||
| 1700 | } | ||
| 1701 | |||
| 1702 | CPokerDialogBase::~CPokerDialogBase() | ||
| 1703 | { | ||
| 1704 | // Disconnect Events | ||
| 1705 | this->Disconnect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(CPokerDialogBase::OnClose)); | ||
| 1706 | this->Disconnect(wxEVT_LEFT_DOWN, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); | ||
| 1707 | this->Disconnect(wxEVT_LEFT_UP, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); | ||
| 1708 | this->Disconnect(wxEVT_MIDDLE_DOWN, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); | ||
| 1709 | this->Disconnect(wxEVT_MIDDLE_UP, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); | ||
| 1710 | this->Disconnect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); | ||
| 1711 | this->Disconnect(wxEVT_RIGHT_UP, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); | ||
| 1712 | this->Disconnect(wxEVT_MOTION, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); | ||
| 1713 | this->Disconnect(wxEVT_LEFT_DCLICK, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); | ||
| 1714 | this->Disconnect(wxEVT_MIDDLE_DCLICK, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); | ||
| 1715 | this->Disconnect(wxEVT_RIGHT_DCLICK, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); | ||
| 1716 | this->Disconnect(wxEVT_LEAVE_WINDOW, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); | ||
| 1717 | this->Disconnect(wxEVT_ENTER_WINDOW, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); | ||
| 1718 | this->Disconnect(wxEVT_MOUSEWHEEL, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); | ||
| 1719 | this->Disconnect(wxEVT_PAINT, wxPaintEventHandler(CPokerDialogBase::OnPaint)); | ||
| 1720 | this->Disconnect(wxEVT_SIZE, wxSizeEventHandler(CPokerDialogBase::OnSize)); | ||
| 1721 | m_checkSitOut->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckSitOut), NULL, this); | ||
| 1722 | m_buttonDealHand->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonDealHand), NULL, this); | ||
| 1723 | m_buttonFold->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonFold), NULL, this); | ||
| 1724 | m_buttonCall->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonCall), NULL, this); | ||
| 1725 | m_buttonRaise->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonRaise), NULL, this); | ||
| 1726 | m_buttonLeaveTable->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonLeaveTable), NULL, this); | ||
| 1727 | m_textDitchPlayer->Disconnect(wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler(CPokerDialogBase::OnDitchPlayer), NULL, this); | ||
| 1728 | m_checkPreFold->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreFold), NULL, this); | ||
| 1729 | m_checkPreCall->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreCall), NULL, this); | ||
| 1730 | m_checkPreCallAny->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreCallAny), NULL, this); | ||
| 1731 | m_checkPreRaise->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreRaise), NULL, this); | ||
| 1732 | m_checkPreRaiseAny->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreRaiseAny), NULL, this); | ||
| 1733 | } | ||
| 1734 | |||
| 1735 | CGetTextFromUserDialogBase::CGetTextFromUserDialogBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxDialog(parent, id, title, pos, size, style) | ||
| 1736 | { | ||
| 1737 | this->SetSizeHints(wxDefaultSize, wxDefaultSize); | ||
| 1738 | |||
| 1739 | wxBoxSizer* bSizer79; | ||
| 1740 | bSizer79 = new wxBoxSizer(wxVERTICAL); | ||
| 1741 | |||
| 1742 | wxBoxSizer* bSizer81; | ||
| 1743 | bSizer81 = new wxBoxSizer(wxVERTICAL); | ||
| 1744 | |||
| 1745 | |||
| 1746 | bSizer81->Add(0, 0, 1, wxEXPAND, 5); | ||
| 1747 | |||
| 1748 | m_staticTextMessage1 = new wxStaticText(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); | ||
| 1749 | m_staticTextMessage1->Wrap(-1); | ||
| 1750 | bSizer81->Add(m_staticTextMessage1, 0, wxTOP|wxRIGHT|wxLEFT, 5); | ||
| 1751 | |||
| 1752 | m_textCtrl1 = new wxTextCtrl(this, wxID_TEXTCTRL, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER); | ||
| 1753 | bSizer81->Add(m_textCtrl1, 0, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL, 5); | ||
| 1754 | |||
| 1755 | m_staticTextMessage2 = new wxStaticText(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); | ||
| 1756 | m_staticTextMessage2->Wrap(-1); | ||
| 1757 | m_staticTextMessage2->Hide(); | ||
| 1758 | |||
| 1759 | bSizer81->Add(m_staticTextMessage2, 0, wxTOP|wxRIGHT|wxLEFT, 5); | ||
| 1760 | |||
| 1761 | m_textCtrl2 = new wxTextCtrl(this, wxID_TEXTCTRL, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER); | ||
| 1762 | m_textCtrl2->Hide(); | ||
| 1763 | |||
| 1764 | bSizer81->Add(m_textCtrl2, 0, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL, 5); | ||
| 1765 | |||
| 1766 | |||
| 1767 | bSizer81->Add(0, 0, 1, wxEXPAND, 5); | ||
| 1768 | |||
| 1769 | bSizer79->Add(bSizer81, 1, wxEXPAND|wxALL, 10); | ||
| 1770 | |||
| 1771 | wxBoxSizer* bSizer80; | ||
| 1772 | bSizer80 = new wxBoxSizer(wxHORIZONTAL); | ||
| 1773 | |||
| 1774 | |||
| 1775 | bSizer80->Add(0, 0, 1, wxEXPAND, 5); | ||
| 1776 | |||
| 1777 | m_buttonOK = new wxButton(this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize(-1,-1), 0); | ||
| 1778 | m_buttonOK->SetMinSize(wxSize(85,25)); | ||
| 1779 | |||
| 1780 | bSizer80->Add(m_buttonOK, 0, wxALL, 5); | ||
| 1781 | |||
| 1782 | m_buttonCancel = new wxButton(this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0); | ||
| 1783 | m_buttonCancel->SetMinSize(wxSize(85,25)); | ||
| 1784 | |||
| 1785 | bSizer80->Add(m_buttonCancel, 0, wxALL, 5); | ||
| 1786 | |||
| 1787 | bSizer79->Add(bSizer80, 0, wxEXPAND, 5); | ||
| 1788 | |||
| 1789 | this->SetSizer(bSizer79); | ||
| 1790 | this->Layout(); | ||
| 1791 | |||
| 1792 | // Connect Events | ||
| 1793 | this->Connect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(CGetTextFromUserDialogBase::OnClose)); | ||
| 1794 | m_textCtrl1->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CGetTextFromUserDialogBase::OnKeyDown), NULL, this); | ||
| 1795 | m_textCtrl2->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CGetTextFromUserDialogBase::OnKeyDown), NULL, this); | ||
| 1796 | m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CGetTextFromUserDialogBase::OnButtonOK), NULL, this); | ||
| 1797 | m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CGetTextFromUserDialogBase::OnButtonCancel), NULL, this); | ||
| 1798 | } | ||
| 1799 | |||
| 1800 | CGetTextFromUserDialogBase::~CGetTextFromUserDialogBase() | ||
| 1801 | { | ||
| 1802 | // Disconnect Events | ||
| 1803 | this->Disconnect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(CGetTextFromUserDialogBase::OnClose)); | ||
| 1804 | m_textCtrl1->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CGetTextFromUserDialogBase::OnKeyDown), NULL, this); | ||
| 1805 | m_textCtrl2->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CGetTextFromUserDialogBase::OnKeyDown), NULL, this); | ||
| 1806 | m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CGetTextFromUserDialogBase::OnButtonOK), NULL, this); | ||
| 1807 | m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CGetTextFromUserDialogBase::OnButtonCancel), NULL, this); | ||
| 1808 | } | ||
diff --git a/src/uibase.h b/src/uibase.h new file mode 100644 index 0000000..6d7799e --- /dev/null +++ b/src/uibase.h | |||
| @@ -0,0 +1,720 @@ | |||
| 1 | // Copyright (c) 2009 Satoshi Nakamoto | ||
| 2 | // Distributed under the MIT/X11 software license, see the accompanying | ||
| 3 | // file license.txt or http://www.opensource.org/licenses/mit-license.php. | ||
| 4 | |||
| 5 | /////////////////////////////////////////////////////////////////////////// | ||
| 6 | // C++ code generated with wxFormBuilder (version Apr 16 2008) | ||
| 7 | // http://www.wxformbuilder.org/ | ||
| 8 | // | ||
| 9 | // PLEASE DO "NOT" EDIT THIS FILE! | ||
| 10 | /////////////////////////////////////////////////////////////////////////// | ||
| 11 | |||
| 12 | #ifndef __uibase__ | ||
| 13 | #define __uibase__ | ||
| 14 | |||
| 15 | #include <wx/string.h> | ||
| 16 | #include <wx/bitmap.h> | ||
| 17 | #include <wx/image.h> | ||
| 18 | #include <wx/icon.h> | ||
| 19 | #include <wx/menu.h> | ||
| 20 | #include <wx/gdicmn.h> | ||
| 21 | #include <wx/font.h> | ||
| 22 | #include <wx/colour.h> | ||
| 23 | #include <wx/settings.h> | ||
| 24 | #include <wx/toolbar.h> | ||
| 25 | #include <wx/statusbr.h> | ||
| 26 | #include <wx/stattext.h> | ||
| 27 | #include <wx/textctrl.h> | ||
| 28 | #include <wx/button.h> | ||
| 29 | #include <wx/sizer.h> | ||
| 30 | #include <wx/panel.h> | ||
| 31 | #include <wx/choice.h> | ||
| 32 | #include <wx/listctrl.h> | ||
| 33 | #include <wx/notebook.h> | ||
| 34 | #include <wx/frame.h> | ||
| 35 | #include <wx/html/htmlwin.h> | ||
| 36 | #include <wx/dialog.h> | ||
| 37 | #include <wx/statbmp.h> | ||
| 38 | #include <wx/combobox.h> | ||
| 39 | #include <wx/scrolwin.h> | ||
| 40 | #include <wx/richtext/richtextctrl.h> | ||
| 41 | #include <wx/treectrl.h> | ||
| 42 | #include <wx/checkbox.h> | ||
| 43 | |||
| 44 | /////////////////////////////////////////////////////////////////////////// | ||
| 45 | |||
| 46 | #define wxID_MAINFRAME 1000 | ||
| 47 | #define wxID_OPTIONSGENERATEBITCOINS 1001 | ||
| 48 | #define wxID_BUTTONSEND 1002 | ||
| 49 | #define wxID_BUTTONRECEIVE 1003 | ||
| 50 | #define wxID_TEXTCTRLADDRESS 1004 | ||
| 51 | #define wxID_BUTTONCOPY 1005 | ||
| 52 | #define wxID_BUTTONCHANGE 1006 | ||
| 53 | #define wxID_TRANSACTIONFEE 1007 | ||
| 54 | #define wxID_TEXTCTRLPAYTO 1008 | ||
| 55 | #define wxID_BUTTONPASTE 1009 | ||
| 56 | #define wxID_BUTTONADDRESSBOOK 1010 | ||
| 57 | #define wxID_TEXTCTRLAMOUNT 1011 | ||
| 58 | #define wxID_CHOICETRANSFERTYPE 1012 | ||
| 59 | #define wxID_LISTCTRL 1013 | ||
| 60 | #define wxID_BUTTONRENAME 1014 | ||
| 61 | #define wxID_BUTTONNEW 1015 | ||
| 62 | #define wxID_BUTTONEDIT 1016 | ||
| 63 | #define wxID_BUTTONDELETE 1017 | ||
| 64 | #define wxID_DEL0 1018 | ||
| 65 | #define wxID_DEL1 1019 | ||
| 66 | #define wxID_DEL2 1020 | ||
| 67 | #define wxID_DEL3 1021 | ||
| 68 | #define wxID_DEL4 1022 | ||
| 69 | #define wxID_DEL5 1023 | ||
| 70 | #define wxID_DEL6 1024 | ||
| 71 | #define wxID_DEL7 1025 | ||
| 72 | #define wxID_DEL8 1026 | ||
| 73 | #define wxID_DEL9 1027 | ||
| 74 | #define wxID_DEL10 1028 | ||
| 75 | #define wxID_DEL11 1029 | ||
| 76 | #define wxID_DEL12 1030 | ||
| 77 | #define wxID_DEL13 1031 | ||
| 78 | #define wxID_DEL14 1032 | ||
| 79 | #define wxID_DEL15 1033 | ||
| 80 | #define wxID_DEL16 1034 | ||
| 81 | #define wxID_DEL17 1035 | ||
| 82 | #define wxID_DEL18 1036 | ||
| 83 | #define wxID_DEL19 1037 | ||
| 84 | #define wxID_BUTTONPREVIEW 1038 | ||
| 85 | #define wxID_BUTTONSAMPLE 1039 | ||
| 86 | #define wxID_CANCEL2 1040 | ||
| 87 | #define wxID_BUTTONBACK 1041 | ||
| 88 | #define wxID_BUTTONNEXT 1042 | ||
| 89 | #define wxID_SUBMIT 1043 | ||
| 90 | #define wxID_OPENNEWTABLE 1044 | ||
| 91 | #define wxID_DEALHAND 1045 | ||
| 92 | #define wxID_FOLD 1046 | ||
| 93 | #define wxID_CALL 1047 | ||
| 94 | #define wxID_RAISE 1048 | ||
| 95 | #define wxID_LEAVETABLE 1049 | ||
| 96 | #define wxID_DITCHPLAYER 1050 | ||
| 97 | #define wxID_TEXTCTRL 1051 | ||
| 98 | |||
| 99 | /////////////////////////////////////////////////////////////////////////////// | ||
| 100 | /// Class CMainFrameBase | ||
| 101 | /////////////////////////////////////////////////////////////////////////////// | ||
| 102 | class CMainFrameBase : public wxFrame | ||
| 103 | { | ||
| 104 | private: | ||
| 105 | |||
| 106 | protected: | ||
| 107 | wxMenuBar* m_menubar; | ||
| 108 | wxMenu* m_menuFile; | ||
| 109 | wxMenu* m_menuHelp; | ||
| 110 | wxToolBar* m_toolBar; | ||
| 111 | wxStatusBar* m_statusBar; | ||
| 112 | |||
| 113 | wxStaticText* m_staticText32; | ||
| 114 | wxTextCtrl* m_textCtrlAddress; | ||
| 115 | wxButton* m_buttonCopy; | ||
| 116 | wxButton* m_button91; | ||
| 117 | |||
| 118 | wxPanel* m_panel14; | ||
| 119 | wxStaticText* m_staticText41; | ||
| 120 | wxStaticText* m_staticTextBalance; | ||
| 121 | |||
| 122 | wxChoice* m_choiceFilter; | ||
| 123 | wxNotebook* m_notebook; | ||
| 124 | wxPanel* m_panel7; | ||
| 125 | wxPanel* m_panel9; | ||
| 126 | wxPanel* m_panel8; | ||
| 127 | wxPanel* m_panel10; | ||
| 128 | wxPanel* m_panel11; | ||
| 129 | |||
| 130 | // Virtual event handlers, overide them in your derived class | ||
| 131 | virtual void OnClose(wxCloseEvent& event){ event.Skip(); } | ||
| 132 | virtual void OnIdle(wxIdleEvent& event){ event.Skip(); } | ||
| 133 | virtual void OnMouseEvents(wxMouseEvent& event){ event.Skip(); } | ||
| 134 | virtual void OnPaint(wxPaintEvent& event){ event.Skip(); } | ||
| 135 | virtual void OnMenuFileExit(wxCommandEvent& event){ event.Skip(); } | ||
| 136 | virtual void OnMenuOptionsGenerate(wxCommandEvent& event){ event.Skip(); } | ||
| 137 | virtual void OnMenuOptionsOptions(wxCommandEvent& event){ event.Skip(); } | ||
| 138 | virtual void OnMenuHelpAbout(wxCommandEvent& event){ event.Skip(); } | ||
| 139 | virtual void OnButtonSend(wxCommandEvent& event){ event.Skip(); } | ||
| 140 | virtual void OnButtonAddressBook(wxCommandEvent& event){ event.Skip(); } | ||
| 141 | virtual void OnKeyDown(wxKeyEvent& event){ event.Skip(); } | ||
| 142 | virtual void OnMouseEventsAddress(wxMouseEvent& event){ event.Skip(); } | ||
| 143 | virtual void OnSetFocusAddress(wxFocusEvent& event){ event.Skip(); } | ||
| 144 | virtual void OnButtonCopy(wxCommandEvent& event){ event.Skip(); } | ||
| 145 | virtual void OnButtonChange(wxCommandEvent& event){ event.Skip(); } | ||
| 146 | virtual void OnListColBeginDrag(wxListEvent& event){ event.Skip(); } | ||
| 147 | virtual void OnListItemActivatedAllTransactions(wxListEvent& event){ event.Skip(); } | ||
| 148 | virtual void OnPaintListCtrl(wxPaintEvent& event){ event.Skip(); } | ||
| 149 | virtual void OnListItemActivatedOrdersSent(wxListEvent& event){ event.Skip(); } | ||
| 150 | virtual void OnListItemActivatedProductsSent(wxListEvent& event){ event.Skip(); } | ||
| 151 | virtual void OnListItemActivatedOrdersReceived(wxListEvent& event){ event.Skip(); } | ||
| 152 | |||
| 153 | |||
| 154 | public: | ||
| 155 | wxMenu* m_menuOptions; | ||
| 156 | wxListCtrl* m_listCtrl; | ||
| 157 | wxListCtrl* m_listCtrlEscrows; | ||
| 158 | wxListCtrl* m_listCtrlOrdersSent; | ||
| 159 | wxListCtrl* m_listCtrlProductsSent; | ||
| 160 | wxListCtrl* m_listCtrlOrdersReceived; | ||
| 161 | CMainFrameBase(wxWindow* parent, wxWindowID id = wxID_MAINFRAME, const wxString& title = wxT("Bitflash"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(705,484), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL); | ||
| 162 | ~CMainFrameBase(); | ||
| 163 | |||
| 164 | }; | ||
| 165 | |||
| 166 | /////////////////////////////////////////////////////////////////////////////// | ||
| 167 | /// Class CTxDetailsDialogBase | ||
| 168 | /////////////////////////////////////////////////////////////////////////////// | ||
| 169 | class CTxDetailsDialogBase : public wxDialog | ||
| 170 | { | ||
| 171 | private: | ||
| 172 | |||
| 173 | protected: | ||
| 174 | wxHtmlWindow* m_htmlWin; | ||
| 175 | wxButton* m_buttonOK; | ||
| 176 | |||
| 177 | // Virtual event handlers, overide them in your derived class | ||
| 178 | virtual void OnButtonOK(wxCommandEvent& event){ event.Skip(); } | ||
| 179 | |||
| 180 | |||
| 181 | public: | ||
| 182 | CTxDetailsDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Transaction Details"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(620,450), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER); | ||
| 183 | ~CTxDetailsDialogBase(); | ||
| 184 | |||
| 185 | }; | ||
| 186 | |||
| 187 | /////////////////////////////////////////////////////////////////////////////// | ||
| 188 | /// Class COptionsDialogBase | ||
| 189 | /////////////////////////////////////////////////////////////////////////////// | ||
| 190 | class COptionsDialogBase : public wxDialog | ||
| 191 | { | ||
| 192 | private: | ||
| 193 | |||
| 194 | protected: | ||
| 195 | |||
| 196 | wxStaticText* m_staticText32; | ||
| 197 | wxStaticText* m_staticText31; | ||
| 198 | wxTextCtrl* m_textCtrlTransactionFee; | ||
| 199 | wxButton* m_buttonOK; | ||
| 200 | wxButton* m_buttonCancel; | ||
| 201 | |||
| 202 | // Virtual event handlers, overide them in your derived class | ||
| 203 | virtual void OnKillFocusTransactionFee(wxFocusEvent& event){ event.Skip(); } | ||
| 204 | virtual void OnButtonOK(wxCommandEvent& event){ event.Skip(); } | ||
| 205 | virtual void OnButtonCancel(wxCommandEvent& event){ event.Skip(); } | ||
| 206 | |||
| 207 | |||
| 208 | public: | ||
| 209 | COptionsDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Options"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(500,261), long style = wxDEFAULT_DIALOG_STYLE); | ||
| 210 | ~COptionsDialogBase(); | ||
| 211 | |||
| 212 | }; | ||
| 213 | |||
| 214 | /////////////////////////////////////////////////////////////////////////////// | ||
| 215 | /// Class CAboutDialogBase | ||
| 216 | /////////////////////////////////////////////////////////////////////////////// | ||
| 217 | class CAboutDialogBase : public wxDialog | ||
| 218 | { | ||
| 219 | private: | ||
| 220 | |||
| 221 | protected: | ||
| 222 | |||
| 223 | |||
| 224 | wxStaticText* m_staticText40; | ||
| 225 | |||
| 226 | wxStaticText* m_staticTextMain; | ||
| 227 | |||
| 228 | |||
| 229 | wxButton* m_buttonOK; | ||
| 230 | |||
| 231 | // Virtual event handlers, overide them in your derived class | ||
| 232 | virtual void OnButtonOK(wxCommandEvent& event){ event.Skip(); } | ||
| 233 | |||
| 234 | |||
| 235 | public: | ||
| 236 | wxStaticText* m_staticTextVersion; | ||
| 237 | CAboutDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("About Bitflash"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(507,298), long style = wxDEFAULT_DIALOG_STYLE); | ||
| 238 | ~CAboutDialogBase(); | ||
| 239 | |||
| 240 | }; | ||
| 241 | |||
| 242 | /////////////////////////////////////////////////////////////////////////////// | ||
| 243 | /// Class CSendDialogBase | ||
| 244 | /////////////////////////////////////////////////////////////////////////////// | ||
| 245 | class CSendDialogBase : public wxDialog | ||
| 246 | { | ||
| 247 | private: | ||
| 248 | |||
| 249 | protected: | ||
| 250 | |||
| 251 | |||
| 252 | wxStaticText* m_staticText14; | ||
| 253 | |||
| 254 | wxStaticBitmap* m_bitmapCheckMark; | ||
| 255 | wxStaticText* m_staticText36; | ||
| 256 | wxTextCtrl* m_textCtrlAddress; | ||
| 257 | wxButton* m_buttonPaste; | ||
| 258 | wxButton* m_buttonAddress; | ||
| 259 | wxStaticText* m_staticText19; | ||
| 260 | wxTextCtrl* m_textCtrlAmount; | ||
| 261 | wxStaticText* m_staticText20; | ||
| 262 | wxChoice* m_choiceTransferType; | ||
| 263 | wxStaticText* m_staticTextFrom; | ||
| 264 | wxTextCtrl* m_textCtrlFrom; | ||
| 265 | wxStaticText* m_staticTextMessage; | ||
| 266 | wxTextCtrl* m_textCtrlMessage; | ||
| 267 | |||
| 268 | wxButton* m_buttonSend; | ||
| 269 | wxButton* m_buttonCancel; | ||
| 270 | |||
| 271 | // Virtual event handlers, overide them in your derived class | ||
| 272 | virtual void OnKeyDown(wxKeyEvent& event){ event.Skip(); } | ||
| 273 | virtual void OnTextAddress(wxCommandEvent& event){ event.Skip(); } | ||
| 274 | virtual void OnButtonPaste(wxCommandEvent& event){ event.Skip(); } | ||
| 275 | virtual void OnButtonAddressBook(wxCommandEvent& event){ event.Skip(); } | ||
| 276 | virtual void OnKillFocusAmount(wxFocusEvent& event){ event.Skip(); } | ||
| 277 | virtual void OnButtonSend(wxCommandEvent& event){ event.Skip(); } | ||
| 278 | virtual void OnButtonCancel(wxCommandEvent& event){ event.Skip(); } | ||
| 279 | |||
| 280 | |||
| 281 | public: | ||
| 282 | CSendDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Send Coins"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(675,338), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER); | ||
| 283 | ~CSendDialogBase(); | ||
| 284 | |||
| 285 | }; | ||
| 286 | |||
| 287 | /////////////////////////////////////////////////////////////////////////////// | ||
| 288 | /// Class CSendingDialogBase | ||
| 289 | /////////////////////////////////////////////////////////////////////////////// | ||
| 290 | class CSendingDialogBase : public wxDialog | ||
| 291 | { | ||
| 292 | private: | ||
| 293 | |||
| 294 | protected: | ||
| 295 | wxStaticText* m_staticTextSending; | ||
| 296 | wxTextCtrl* m_textCtrlStatus; | ||
| 297 | |||
| 298 | wxButton* m_buttonOK; | ||
| 299 | wxButton* m_buttonCancel; | ||
| 300 | |||
| 301 | // Virtual event handlers, overide them in your derived class | ||
| 302 | virtual void OnClose(wxCloseEvent& event){ event.Skip(); } | ||
| 303 | virtual void OnPaint(wxPaintEvent& event){ event.Skip(); } | ||
| 304 | virtual void OnButtonOK(wxCommandEvent& event){ event.Skip(); } | ||
| 305 | virtual void OnButtonCancel(wxCommandEvent& event){ event.Skip(); } | ||
| 306 | |||
| 307 | |||
| 308 | public: | ||
| 309 | CSendingDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Sending..."), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(442,151), long style = wxDEFAULT_DIALOG_STYLE); | ||
| 310 | ~CSendingDialogBase(); | ||
| 311 | |||
| 312 | }; | ||
| 313 | |||
| 314 | /////////////////////////////////////////////////////////////////////////////// | ||
| 315 | /// Class CYourAddressDialogBase | ||
| 316 | /////////////////////////////////////////////////////////////////////////////// | ||
| 317 | class CYourAddressDialogBase : public wxDialog | ||
| 318 | { | ||
| 319 | private: | ||
| 320 | |||
| 321 | protected: | ||
| 322 | |||
| 323 | wxStaticText* m_staticText45; | ||
| 324 | wxListCtrl* m_listCtrl; | ||
| 325 | |||
| 326 | wxButton* m_buttonRename; | ||
| 327 | wxButton* m_buttonNew; | ||
| 328 | wxButton* m_buttonCopy; | ||
| 329 | wxButton* m_buttonOK; | ||
| 330 | wxButton* m_buttonCancel; | ||
| 331 | |||
| 332 | // Virtual event handlers, overide them in your derived class | ||
| 333 | virtual void OnClose(wxCloseEvent& event){ event.Skip(); } | ||
| 334 | virtual void OnListEndLabelEdit(wxListEvent& event){ event.Skip(); } | ||
| 335 | virtual void OnListItemActivated(wxListEvent& event){ event.Skip(); } | ||
| 336 | virtual void OnListItemSelected(wxListEvent& event){ event.Skip(); } | ||
| 337 | virtual void OnButtonRename(wxCommandEvent& event){ event.Skip(); } | ||
| 338 | virtual void OnButtonNew(wxCommandEvent& event){ event.Skip(); } | ||
| 339 | virtual void OnButtonCopy(wxCommandEvent& event){ event.Skip(); } | ||
| 340 | virtual void OnButtonOK(wxCommandEvent& event){ event.Skip(); } | ||
| 341 | virtual void OnButtonCancel(wxCommandEvent& event){ event.Skip(); } | ||
| 342 | |||
| 343 | |||
| 344 | public: | ||
| 345 | CYourAddressDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Your Bitflash Address"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(610,390), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER); | ||
| 346 | ~CYourAddressDialogBase(); | ||
| 347 | |||
| 348 | }; | ||
| 349 | |||
| 350 | /////////////////////////////////////////////////////////////////////////////// | ||
| 351 | /// Class CAddressBookDialogBase | ||
| 352 | /////////////////////////////////////////////////////////////////////////////// | ||
| 353 | class CAddressBookDialogBase : public wxDialog | ||
| 354 | { | ||
| 355 | private: | ||
| 356 | |||
| 357 | protected: | ||
| 358 | |||
| 359 | wxStaticText* m_staticText55; | ||
| 360 | wxListCtrl* m_listCtrl; | ||
| 361 | |||
| 362 | wxButton* m_buttonEdit; | ||
| 363 | wxButton* m_buttonNew; | ||
| 364 | wxButton* m_buttonDelete; | ||
| 365 | wxButton* m_buttonOK; | ||
| 366 | |||
| 367 | // Virtual event handlers, overide them in your derived class | ||
| 368 | virtual void OnClose(wxCloseEvent& event){ event.Skip(); } | ||
| 369 | virtual void OnListEndLabelEdit(wxListEvent& event){ event.Skip(); } | ||
| 370 | virtual void OnListItemActivated(wxListEvent& event){ event.Skip(); } | ||
| 371 | virtual void OnListItemSelected(wxListEvent& event){ event.Skip(); } | ||
| 372 | virtual void OnButtonEdit(wxCommandEvent& event){ event.Skip(); } | ||
| 373 | virtual void OnButtonNew(wxCommandEvent& event){ event.Skip(); } | ||
| 374 | virtual void OnButtonDelete(wxCommandEvent& event){ event.Skip(); } | ||
| 375 | virtual void OnButtonOK(wxCommandEvent& event){ event.Skip(); } | ||
| 376 | virtual void OnButtonCancel(wxCommandEvent& event){ event.Skip(); } | ||
| 377 | |||
| 378 | |||
| 379 | public: | ||
| 380 | wxButton* m_buttonCancel; | ||
| 381 | CAddressBookDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Address Book"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(610,390), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER); | ||
| 382 | ~CAddressBookDialogBase(); | ||
| 383 | |||
| 384 | }; | ||
| 385 | |||
| 386 | /////////////////////////////////////////////////////////////////////////////// | ||
| 387 | /// Class CProductsDialogBase | ||
| 388 | /////////////////////////////////////////////////////////////////////////////// | ||
| 389 | class CProductsDialogBase : public wxDialog | ||
| 390 | { | ||
| 391 | private: | ||
| 392 | |||
| 393 | protected: | ||
| 394 | wxComboBox* m_comboBoxCategory; | ||
| 395 | wxTextCtrl* m_textCtrlSearch; | ||
| 396 | wxButton* m_buttonSearch; | ||
| 397 | wxListCtrl* m_listCtrl; | ||
| 398 | |||
| 399 | // Virtual event handlers, overide them in your derived class | ||
| 400 | virtual void OnCombobox(wxCommandEvent& event){ event.Skip(); } | ||
| 401 | virtual void OnKeyDown(wxKeyEvent& event){ event.Skip(); } | ||
| 402 | virtual void OnButtonSearch(wxCommandEvent& event){ event.Skip(); } | ||
| 403 | virtual void OnListItemActivated(wxListEvent& event){ event.Skip(); } | ||
| 404 | |||
| 405 | |||
| 406 | public: | ||
| 407 | CProductsDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Marketplace"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(708,535), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER); | ||
| 408 | ~CProductsDialogBase(); | ||
| 409 | |||
| 410 | }; | ||
| 411 | |||
| 412 | /////////////////////////////////////////////////////////////////////////////// | ||
| 413 | /// Class CEditProductDialogBase | ||
| 414 | /////////////////////////////////////////////////////////////////////////////// | ||
| 415 | class CEditProductDialogBase : public wxFrame | ||
| 416 | { | ||
| 417 | private: | ||
| 418 | |||
| 419 | protected: | ||
| 420 | wxScrolledWindow* m_scrolledWindow; | ||
| 421 | wxStaticText* m_staticText106; | ||
| 422 | wxComboBox* m_comboBoxCategory; | ||
| 423 | wxStaticText* m_staticText108; | ||
| 424 | wxTextCtrl* m_textCtrlTitle; | ||
| 425 | wxStaticText* m_staticText107; | ||
| 426 | wxTextCtrl* m_textCtrlPrice; | ||
| 427 | wxStaticText* m_staticText22; | ||
| 428 | wxTextCtrl* m_textCtrlDescription; | ||
| 429 | wxStaticText* m_staticText23; | ||
| 430 | wxTextCtrl* m_textCtrlInstructions; | ||
| 431 | wxStaticText* m_staticText24; | ||
| 432 | wxStaticText* m_staticText25; | ||
| 433 | |||
| 434 | wxTextCtrl* m_textCtrlLabel0; | ||
| 435 | wxTextCtrl* m_textCtrlField0; | ||
| 436 | wxButton* m_buttonDel0; | ||
| 437 | wxTextCtrl* m_textCtrlLabel1; | ||
| 438 | wxTextCtrl* m_textCtrlField1; | ||
| 439 | wxButton* m_buttonDel1; | ||
| 440 | wxTextCtrl* m_textCtrlLabel2; | ||
| 441 | wxTextCtrl* m_textCtrlField2; | ||
| 442 | wxButton* m_buttonDel2; | ||
| 443 | wxTextCtrl* m_textCtrlLabel3; | ||
| 444 | wxTextCtrl* m_textCtrlField3; | ||
| 445 | wxButton* m_buttonDel3; | ||
| 446 | wxTextCtrl* m_textCtrlLabel4; | ||
| 447 | wxTextCtrl* m_textCtrlField4; | ||
| 448 | wxButton* m_buttonDel4; | ||
| 449 | wxTextCtrl* m_textCtrlLabel5; | ||
| 450 | wxTextCtrl* m_textCtrlField5; | ||
| 451 | wxButton* m_buttonDel5; | ||
| 452 | wxTextCtrl* m_textCtrlLabel6; | ||
| 453 | wxTextCtrl* m_textCtrlField6; | ||
| 454 | wxButton* m_buttonDel6; | ||
| 455 | wxTextCtrl* m_textCtrlLabel7; | ||
| 456 | wxTextCtrl* m_textCtrlField7; | ||
| 457 | wxButton* m_buttonDel7; | ||
| 458 | wxTextCtrl* m_textCtrlLabel8; | ||
| 459 | wxTextCtrl* m_textCtrlField8; | ||
| 460 | wxButton* m_buttonDel8; | ||
| 461 | wxTextCtrl* m_textCtrlLabel9; | ||
| 462 | wxTextCtrl* m_textCtrlField9; | ||
| 463 | wxButton* m_buttonDel9; | ||
| 464 | wxTextCtrl* m_textCtrlLabel10; | ||
| 465 | wxTextCtrl* m_textCtrlField10; | ||
| 466 | wxButton* m_buttonDel10; | ||
| 467 | wxTextCtrl* m_textCtrlLabel11; | ||
| 468 | wxTextCtrl* m_textCtrlField11; | ||
| 469 | wxButton* m_buttonDel11; | ||
| 470 | wxTextCtrl* m_textCtrlLabel12; | ||
| 471 | wxTextCtrl* m_textCtrlField12; | ||
| 472 | wxButton* m_buttonDel12; | ||
| 473 | wxTextCtrl* m_textCtrlLabel13; | ||
| 474 | wxTextCtrl* m_textCtrlField13; | ||
| 475 | wxButton* m_buttonDel13; | ||
| 476 | wxTextCtrl* m_textCtrlLabel14; | ||
| 477 | wxTextCtrl* m_textCtrlField14; | ||
| 478 | wxButton* m_buttonDel14; | ||
| 479 | wxTextCtrl* m_textCtrlLabel15; | ||
| 480 | wxTextCtrl* m_textCtrlField15; | ||
| 481 | wxButton* m_buttonDel15; | ||
| 482 | wxTextCtrl* m_textCtrlLabel16; | ||
| 483 | wxTextCtrl* m_textCtrlField16; | ||
| 484 | wxButton* m_buttonDel16; | ||
| 485 | wxTextCtrl* m_textCtrlLabel17; | ||
| 486 | wxTextCtrl* m_textCtrlField17; | ||
| 487 | wxButton* m_buttonDel17; | ||
| 488 | wxTextCtrl* m_textCtrlLabel18; | ||
| 489 | wxTextCtrl* m_textCtrlField18; | ||
| 490 | wxButton* m_buttonDel18; | ||
| 491 | wxTextCtrl* m_textCtrlLabel19; | ||
| 492 | wxTextCtrl* m_textCtrlField19; | ||
| 493 | wxButton* m_buttonDel19; | ||
| 494 | wxButton* m_buttonAddField; | ||
| 495 | wxButton* m_buttonOK; | ||
| 496 | wxButton* m_buttonPreview; | ||
| 497 | wxButton* m_buttonCancel; | ||
| 498 | |||
| 499 | // Virtual event handlers, overide them in your derived class | ||
| 500 | virtual void OnKeyDown(wxKeyEvent& event){ event.Skip(); } | ||
| 501 | virtual void OnButtonDel0(wxCommandEvent& event){ event.Skip(); } | ||
| 502 | virtual void OnButtonDel1(wxCommandEvent& event){ event.Skip(); } | ||
| 503 | virtual void OnButtonDel2(wxCommandEvent& event){ event.Skip(); } | ||
| 504 | virtual void OnButtonDel3(wxCommandEvent& event){ event.Skip(); } | ||
| 505 | virtual void OnButtonDel4(wxCommandEvent& event){ event.Skip(); } | ||
| 506 | virtual void OnButtonDel5(wxCommandEvent& event){ event.Skip(); } | ||
| 507 | virtual void OnButtonDel6(wxCommandEvent& event){ event.Skip(); } | ||
| 508 | virtual void OnButtonDel7(wxCommandEvent& event){ event.Skip(); } | ||
| 509 | virtual void OnButtonDel8(wxCommandEvent& event){ event.Skip(); } | ||
| 510 | virtual void OnButtonDel9(wxCommandEvent& event){ event.Skip(); } | ||
| 511 | virtual void OnButtonDel10(wxCommandEvent& event){ event.Skip(); } | ||
| 512 | virtual void OnButtonDel11(wxCommandEvent& event){ event.Skip(); } | ||
| 513 | virtual void OnButtonDel12(wxCommandEvent& event){ event.Skip(); } | ||
| 514 | virtual void OnButtonDel13(wxCommandEvent& event){ event.Skip(); } | ||
| 515 | virtual void OnButtonDel14(wxCommandEvent& event){ event.Skip(); } | ||
| 516 | virtual void OnButtonDel15(wxCommandEvent& event){ event.Skip(); } | ||
| 517 | virtual void OnButtonDel16(wxCommandEvent& event){ event.Skip(); } | ||
| 518 | virtual void OnButtonDel17(wxCommandEvent& event){ event.Skip(); } | ||
| 519 | virtual void OnButtonDel18(wxCommandEvent& event){ event.Skip(); } | ||
| 520 | virtual void OnButtonDel19(wxCommandEvent& event){ event.Skip(); } | ||
| 521 | virtual void OnButtonAddField(wxCommandEvent& event){ event.Skip(); } | ||
| 522 | virtual void OnButtonSend(wxCommandEvent& event){ event.Skip(); } | ||
| 523 | virtual void OnButtonPreview(wxCommandEvent& event){ event.Skip(); } | ||
| 524 | virtual void OnButtonCancel(wxCommandEvent& event){ event.Skip(); } | ||
| 525 | |||
| 526 | |||
| 527 | public: | ||
| 528 | wxFlexGridSizer* fgSizer5; | ||
| 529 | CEditProductDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Edit Product"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(660,640), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL); | ||
| 530 | ~CEditProductDialogBase(); | ||
| 531 | |||
| 532 | }; | ||
| 533 | |||
| 534 | /////////////////////////////////////////////////////////////////////////////// | ||
| 535 | /// Class CViewProductDialogBase | ||
| 536 | /////////////////////////////////////////////////////////////////////////////// | ||
| 537 | class CViewProductDialogBase : public wxFrame | ||
| 538 | { | ||
| 539 | private: | ||
| 540 | |||
| 541 | protected: | ||
| 542 | wxHtmlWindow* m_htmlWinReviews; | ||
| 543 | wxScrolledWindow* m_scrolledWindow; | ||
| 544 | wxRichTextCtrl* m_richTextHeading; | ||
| 545 | wxStaticText* m_staticTextInstructions; | ||
| 546 | wxButton* m_buttonSubmitForm; | ||
| 547 | wxButton* m_buttonCancelForm; | ||
| 548 | wxButton* m_buttonBack; | ||
| 549 | wxButton* m_buttonNext; | ||
| 550 | wxButton* m_buttonCancel; | ||
| 551 | |||
| 552 | // Virtual event handlers, overide them in your derived class | ||
| 553 | virtual void OnButtonSubmitForm(wxCommandEvent& event){ event.Skip(); } | ||
| 554 | virtual void OnButtonCancelForm(wxCommandEvent& event){ event.Skip(); } | ||
| 555 | virtual void OnButtonBack(wxCommandEvent& event){ event.Skip(); } | ||
| 556 | virtual void OnButtonNext(wxCommandEvent& event){ event.Skip(); } | ||
| 557 | virtual void OnButtonCancel(wxCommandEvent& event){ event.Skip(); } | ||
| 558 | |||
| 559 | |||
| 560 | public: | ||
| 561 | CViewProductDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Order Form"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(630,520), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL); | ||
| 562 | ~CViewProductDialogBase(); | ||
| 563 | |||
| 564 | }; | ||
| 565 | |||
| 566 | /////////////////////////////////////////////////////////////////////////////// | ||
| 567 | /// Class CViewOrderDialogBase | ||
| 568 | /////////////////////////////////////////////////////////////////////////////// | ||
| 569 | class CViewOrderDialogBase : public wxFrame | ||
| 570 | { | ||
| 571 | private: | ||
| 572 | |||
| 573 | protected: | ||
| 574 | wxHtmlWindow* m_htmlWin; | ||
| 575 | wxButton* m_buttonOK; | ||
| 576 | |||
| 577 | // Virtual event handlers, overide them in your derived class | ||
| 578 | virtual void OnButtonOK(wxCommandEvent& event){ event.Skip(); } | ||
| 579 | |||
| 580 | |||
| 581 | public: | ||
| 582 | CViewOrderDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("View Order"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(630,520), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL); | ||
| 583 | ~CViewOrderDialogBase(); | ||
| 584 | |||
| 585 | }; | ||
| 586 | |||
| 587 | /////////////////////////////////////////////////////////////////////////////// | ||
| 588 | /// Class CEditReviewDialogBase | ||
| 589 | /////////////////////////////////////////////////////////////////////////////// | ||
| 590 | class CEditReviewDialogBase : public wxFrame | ||
| 591 | { | ||
| 592 | private: | ||
| 593 | |||
| 594 | protected: | ||
| 595 | |||
| 596 | wxStaticText* m_staticTextSeller; | ||
| 597 | |||
| 598 | wxStaticText* m_staticText110; | ||
| 599 | wxChoice* m_choiceStars; | ||
| 600 | wxStaticText* m_staticText43; | ||
| 601 | wxTextCtrl* m_textCtrlReview; | ||
| 602 | wxButton* m_buttonSubmit; | ||
| 603 | wxButton* m_buttonCancel; | ||
| 604 | |||
| 605 | // Virtual event handlers, overide them in your derived class | ||
| 606 | virtual void OnKeyDown(wxKeyEvent& event){ event.Skip(); } | ||
| 607 | virtual void OnButtonSubmit(wxCommandEvent& event){ event.Skip(); } | ||
| 608 | virtual void OnButtonCancel(wxCommandEvent& event){ event.Skip(); } | ||
| 609 | |||
| 610 | |||
| 611 | public: | ||
| 612 | CEditReviewDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Enter Review"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(630,440), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL); | ||
| 613 | ~CEditReviewDialogBase(); | ||
| 614 | |||
| 615 | }; | ||
| 616 | |||
| 617 | /////////////////////////////////////////////////////////////////////////////// | ||
| 618 | /// Class CPokerLobbyDialogBase | ||
| 619 | /////////////////////////////////////////////////////////////////////////////// | ||
| 620 | class CPokerLobbyDialogBase : public wxFrame | ||
| 621 | { | ||
| 622 | private: | ||
| 623 | |||
| 624 | protected: | ||
| 625 | wxTreeCtrl* m_treeCtrl; | ||
| 626 | wxListCtrl* m_listCtrl; | ||
| 627 | wxButton* m_buttonNewTable; | ||
| 628 | |||
| 629 | // Virtual event handlers, overide them in your derived class | ||
| 630 | virtual void OnTreeSelChanged(wxTreeEvent& event){ event.Skip(); } | ||
| 631 | virtual void OnListItemActivated(wxListEvent& event){ event.Skip(); } | ||
| 632 | virtual void OnListItemSelected(wxListEvent& event){ event.Skip(); } | ||
| 633 | virtual void OnButtonNewTable(wxCommandEvent& event){ event.Skip(); } | ||
| 634 | |||
| 635 | |||
| 636 | public: | ||
| 637 | CPokerLobbyDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Poker Lobby"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(586,457), long style = wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL); | ||
| 638 | ~CPokerLobbyDialogBase(); | ||
| 639 | |||
| 640 | }; | ||
| 641 | |||
| 642 | /////////////////////////////////////////////////////////////////////////////// | ||
| 643 | /// Class CPokerDialogBase | ||
| 644 | /////////////////////////////////////////////////////////////////////////////// | ||
| 645 | class CPokerDialogBase : public wxFrame | ||
| 646 | { | ||
| 647 | private: | ||
| 648 | |||
| 649 | protected: | ||
| 650 | wxButton* m_buttonDealHand; | ||
| 651 | wxButton* m_buttonFold; | ||
| 652 | wxButton* m_buttonCall; | ||
| 653 | wxButton* m_buttonRaise; | ||
| 654 | wxButton* m_buttonLeaveTable; | ||
| 655 | wxTextCtrl* m_textDitchPlayer; | ||
| 656 | |||
| 657 | // Virtual event handlers, overide them in your derived class | ||
| 658 | virtual void OnClose(wxCloseEvent& event){ event.Skip(); } | ||
| 659 | virtual void OnMouseEvents(wxMouseEvent& event){ event.Skip(); } | ||
| 660 | virtual void OnPaint(wxPaintEvent& event){ event.Skip(); } | ||
| 661 | virtual void OnSize(wxSizeEvent& event){ event.Skip(); } | ||
| 662 | virtual void OnCheckSitOut(wxCommandEvent& event){ event.Skip(); } | ||
| 663 | virtual void OnButtonDealHand(wxCommandEvent& event){ event.Skip(); } | ||
| 664 | virtual void OnButtonFold(wxCommandEvent& event){ event.Skip(); } | ||
| 665 | virtual void OnButtonCall(wxCommandEvent& event){ event.Skip(); } | ||
| 666 | virtual void OnButtonRaise(wxCommandEvent& event){ event.Skip(); } | ||
| 667 | virtual void OnButtonLeaveTable(wxCommandEvent& event){ event.Skip(); } | ||
| 668 | virtual void OnDitchPlayer(wxCommandEvent& event){ event.Skip(); } | ||
| 669 | virtual void OnCheckPreFold(wxCommandEvent& event){ event.Skip(); } | ||
| 670 | virtual void OnCheckPreCall(wxCommandEvent& event){ event.Skip(); } | ||
| 671 | virtual void OnCheckPreCallAny(wxCommandEvent& event){ event.Skip(); } | ||
| 672 | virtual void OnCheckPreRaise(wxCommandEvent& event){ event.Skip(); } | ||
| 673 | virtual void OnCheckPreRaiseAny(wxCommandEvent& event){ event.Skip(); } | ||
| 674 | |||
| 675 | |||
| 676 | public: | ||
| 677 | wxCheckBox* m_checkSitOut; | ||
| 678 | wxCheckBox* m_checkPreFold; | ||
| 679 | wxCheckBox* m_checkPreCall; | ||
| 680 | wxCheckBox* m_checkPreCallAny; | ||
| 681 | wxCheckBox* m_checkPreRaise; | ||
| 682 | wxCheckBox* m_checkPreRaiseAny; | ||
| 683 | wxStatusBar* m_statusBar; | ||
| 684 | CPokerDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Poker"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(806,550), long style = wxDEFAULT_FRAME_STYLE|wxFRAME_NO_TASKBAR|wxFULL_REPAINT_ON_RESIZE|wxTAB_TRAVERSAL); | ||
| 685 | ~CPokerDialogBase(); | ||
| 686 | |||
| 687 | }; | ||
| 688 | |||
| 689 | /////////////////////////////////////////////////////////////////////////////// | ||
| 690 | /// Class CGetTextFromUserDialogBase | ||
| 691 | /////////////////////////////////////////////////////////////////////////////// | ||
| 692 | class CGetTextFromUserDialogBase : public wxDialog | ||
| 693 | { | ||
| 694 | private: | ||
| 695 | |||
| 696 | protected: | ||
| 697 | |||
| 698 | wxStaticText* m_staticTextMessage1; | ||
| 699 | wxTextCtrl* m_textCtrl1; | ||
| 700 | wxStaticText* m_staticTextMessage2; | ||
| 701 | wxTextCtrl* m_textCtrl2; | ||
| 702 | |||
| 703 | |||
| 704 | wxButton* m_buttonOK; | ||
| 705 | wxButton* m_buttonCancel; | ||
| 706 | |||
| 707 | // Virtual event handlers, overide them in your derived class | ||
| 708 | virtual void OnClose(wxCloseEvent& event){ event.Skip(); } | ||
| 709 | virtual void OnKeyDown(wxKeyEvent& event){ event.Skip(); } | ||
| 710 | virtual void OnButtonOK(wxCommandEvent& event){ event.Skip(); } | ||
| 711 | virtual void OnButtonCancel(wxCommandEvent& event){ event.Skip(); } | ||
| 712 | |||
| 713 | |||
| 714 | public: | ||
| 715 | CGetTextFromUserDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(403,138), long style = wxDEFAULT_DIALOG_STYLE); | ||
| 716 | ~CGetTextFromUserDialogBase(); | ||
| 717 | |||
| 718 | }; | ||
| 719 | |||
| 720 | #endif //__uibase__ | ||
diff --git a/src/uint256.h b/src/uint256.h new file mode 100644 index 0000000..61e11fc --- /dev/null +++ b/src/uint256.h | |||
| @@ -0,0 +1,750 @@ | |||
| 1 | // Copyright (c) 2009 Satoshi Nakamoto | ||
| 2 | // Distributed under the MIT/X11 software license, see the accompanying | ||
| 3 | // file license.txt or http://www.opensource.org/licenses/mit-license.php. | ||
| 4 | |||
| 5 | #include <limits.h> | ||
| 6 | #include <string> | ||
| 7 | #if defined(_MSC_VER) || defined(__BORLANDC__) | ||
| 8 | typedef __int64 int64; | ||
| 9 | typedef unsigned __int64 uint64; | ||
| 10 | #else | ||
| 11 | typedef long long int64; | ||
| 12 | typedef unsigned long long uint64; | ||
| 13 | #endif | ||
| 14 | #if defined(_MSC_VER) && _MSC_VER < 1300 | ||
| 15 | #define for if (false) ; else for | ||
| 16 | #endif | ||
| 17 | |||
| 18 | |||
| 19 | inline int Testuint256AdHoc(vector<string> vArg); | ||
| 20 | |||
| 21 | |||
| 22 | |||
| 23 | // We have to keep a separate base class without constructors | ||
| 24 | // so the compiler will let us use it in a union | ||
| 25 | template<unsigned int BITS> | ||
| 26 | class base_uint | ||
| 27 | { | ||
| 28 | protected: | ||
| 29 | enum { WIDTH=BITS/32 }; | ||
| 30 | unsigned int pn[WIDTH]; | ||
| 31 | public: | ||
| 32 | |||
| 33 | bool operator!() const | ||
| 34 | { | ||
| 35 | for (int i = 0; i < WIDTH; i++) | ||
| 36 | if (pn[i] != 0) | ||
| 37 | return false; | ||
| 38 | return true; | ||
| 39 | } | ||
| 40 | |||
| 41 | const base_uint operator~() const | ||
| 42 | { | ||
| 43 | base_uint ret; | ||
| 44 | for (int i = 0; i < WIDTH; i++) | ||
| 45 | ret.pn[i] = ~pn[i]; | ||
| 46 | return ret; | ||
| 47 | } | ||
| 48 | |||
| 49 | const base_uint operator-() const | ||
| 50 | { | ||
| 51 | base_uint ret; | ||
| 52 | for (int i = 0; i < WIDTH; i++) | ||
| 53 | ret.pn[i] = ~pn[i]; | ||
| 54 | ret++; | ||
| 55 | return ret; | ||
| 56 | } | ||
| 57 | |||
| 58 | |||
| 59 | base_uint& operator=(uint64 b) | ||
| 60 | { | ||
| 61 | pn[0] = (unsigned int)b; | ||
| 62 | pn[1] = (unsigned int)(b >> 32); | ||
| 63 | for (int i = 2; i < WIDTH; i++) | ||
| 64 | pn[i] = 0; | ||
| 65 | return *this; | ||
| 66 | } | ||
| 67 | |||
| 68 | base_uint& operator^=(const base_uint& b) | ||
| 69 | { | ||
| 70 | for (int i = 0; i < WIDTH; i++) | ||
| 71 | pn[i] ^= b.pn[i]; | ||
| 72 | return *this; | ||
| 73 | } | ||
| 74 | |||
| 75 | base_uint& operator&=(const base_uint& b) | ||
| 76 | { | ||
| 77 | for (int i = 0; i < WIDTH; i++) | ||
| 78 | pn[i] &= b.pn[i]; | ||
| 79 | return *this; | ||
| 80 | } | ||
| 81 | |||
| 82 | base_uint& operator|=(const base_uint& b) | ||
| 83 | { | ||
| 84 | for (int i = 0; i < WIDTH; i++) | ||
| 85 | pn[i] |= b.pn[i]; | ||
| 86 | return *this; | ||
| 87 | } | ||
| 88 | |||
| 89 | base_uint& operator^=(uint64 b) | ||
| 90 | { | ||
| 91 | pn[0] ^= (unsigned int)b; | ||
| 92 | pn[1] ^= (unsigned int)(b >> 32); | ||
| 93 | return *this; | ||
| 94 | } | ||
| 95 | |||
| 96 | base_uint& operator&=(uint64 b) | ||
| 97 | { | ||
| 98 | pn[0] &= (unsigned int)b; | ||
| 99 | pn[1] &= (unsigned int)(b >> 32); | ||
| 100 | return *this; | ||
| 101 | } | ||
| 102 | |||
| 103 | base_uint& operator|=(uint64 b) | ||
| 104 | { | ||
| 105 | pn[0] |= (unsigned int)b; | ||
| 106 | pn[1] |= (unsigned int)(b >> 32); | ||
| 107 | return *this; | ||
| 108 | } | ||
| 109 | |||
| 110 | base_uint& operator<<=(unsigned int shift) | ||
| 111 | { | ||
| 112 | base_uint a(*this); | ||
| 113 | for (int i = 0; i < WIDTH; i++) | ||
| 114 | pn[i] = 0; | ||
| 115 | int k = shift / 32; | ||
| 116 | shift = shift % 32; | ||
| 117 | for (int i = 0; i < WIDTH; i++) | ||
| 118 | { | ||
| 119 | if (i+k+1 < WIDTH && shift != 0) | ||
| 120 | pn[i+k+1] |= (a.pn[i] >> (32-shift)); | ||
| 121 | if (i+k < WIDTH) | ||
| 122 | pn[i+k] |= (a.pn[i] << shift); | ||
| 123 | } | ||
| 124 | return *this; | ||
| 125 | } | ||
| 126 | |||
| 127 | base_uint& operator>>=(unsigned int shift) | ||
| 128 | { | ||
| 129 | base_uint a(*this); | ||
| 130 | for (int i = 0; i < WIDTH; i++) | ||
| 131 | pn[i] = 0; | ||
| 132 | int k = shift / 32; | ||
| 133 | shift = shift % 32; | ||
| 134 | for (int i = 0; i < WIDTH; i++) | ||
| 135 | { | ||
| 136 | if (i-k-1 >= 0 && shift != 0) | ||
| 137 | pn[i-k-1] |= (a.pn[i] << (32-shift)); | ||
| 138 | if (i-k >= 0) | ||
| 139 | pn[i-k] |= (a.pn[i] >> shift); | ||
| 140 | } | ||
| 141 | return *this; | ||
| 142 | } | ||
| 143 | |||
| 144 | base_uint& operator+=(const base_uint& b) | ||
| 145 | { | ||
| 146 | uint64 carry = 0; | ||
| 147 | for (int i = 0; i < WIDTH; i++) | ||
| 148 | { | ||
| 149 | uint64 n = carry + pn[i] + b.pn[i]; | ||
| 150 | pn[i] = n & 0xffffffff; | ||
| 151 | carry = n >> 32; | ||
| 152 | } | ||
| 153 | return *this; | ||
| 154 | } | ||
| 155 | |||
| 156 | base_uint& operator-=(const base_uint& b) | ||
| 157 | { | ||
| 158 | *this += -b; | ||
| 159 | return *this; | ||
| 160 | } | ||
| 161 | |||
| 162 | base_uint& operator+=(uint64 b64) | ||
| 163 | { | ||
| 164 | base_uint b; | ||
| 165 | b = b64; | ||
| 166 | *this += b; | ||
| 167 | return *this; | ||
| 168 | } | ||
| 169 | |||
| 170 | base_uint& operator-=(uint64 b64) | ||
| 171 | { | ||
| 172 | base_uint b; | ||
| 173 | b = b64; | ||
| 174 | *this += -b; | ||
| 175 | return *this; | ||
| 176 | } | ||
| 177 | |||
| 178 | |||
| 179 | base_uint& operator++() | ||
| 180 | { | ||
| 181 | // prefix operator | ||
| 182 | int i = 0; | ||
| 183 | while (++pn[i] == 0 && i < WIDTH-1) | ||
| 184 | i++; | ||
| 185 | return *this; | ||
| 186 | } | ||
| 187 | |||
| 188 | const base_uint operator++(int) | ||
| 189 | { | ||
| 190 | // postfix operator | ||
| 191 | const base_uint ret = *this; | ||
| 192 | ++(*this); | ||
| 193 | return ret; | ||
| 194 | } | ||
| 195 | |||
| 196 | base_uint& operator--() | ||
| 197 | { | ||
| 198 | // prefix operator | ||
| 199 | int i = 0; | ||
| 200 | while (--pn[i] == -1 && i < WIDTH-1) | ||
| 201 | i++; | ||
| 202 | return *this; | ||
| 203 | } | ||
| 204 | |||
| 205 | const base_uint operator--(int) | ||
| 206 | { | ||
| 207 | // postfix operator | ||
| 208 | const base_uint ret = *this; | ||
| 209 | --(*this); | ||
| 210 | return ret; | ||
| 211 | } | ||
| 212 | |||
| 213 | |||
| 214 | friend inline bool operator<(const base_uint& a, const base_uint& b) | ||
| 215 | { | ||
| 216 | for (int i = base_uint::WIDTH-1; i >= 0; i--) | ||
| 217 | { | ||
| 218 | if (a.pn[i] < b.pn[i]) | ||
| 219 | return true; | ||
| 220 | else if (a.pn[i] > b.pn[i]) | ||
| 221 | return false; | ||
| 222 | } | ||
| 223 | return false; | ||
| 224 | } | ||
| 225 | |||
| 226 | friend inline bool operator<=(const base_uint& a, const base_uint& b) | ||
| 227 | { | ||
| 228 | for (int i = base_uint::WIDTH-1; i >= 0; i--) | ||
| 229 | { | ||
| 230 | if (a.pn[i] < b.pn[i]) | ||
| 231 | return true; | ||
| 232 | else if (a.pn[i] > b.pn[i]) | ||
| 233 | return false; | ||
| 234 | } | ||
| 235 | return true; | ||
| 236 | } | ||
| 237 | |||
| 238 | friend inline bool operator>(const base_uint& a, const base_uint& b) | ||
| 239 | { | ||
| 240 | for (int i = base_uint::WIDTH-1; i >= 0; i--) | ||
| 241 | { | ||
| 242 | if (a.pn[i] > b.pn[i]) | ||
| 243 | return true; | ||
| 244 | else if (a.pn[i] < b.pn[i]) | ||
| 245 | return false; | ||
| 246 | } | ||
| 247 | return false; | ||
| 248 | } | ||
| 249 | |||
| 250 | friend inline bool operator>=(const base_uint& a, const base_uint& b) | ||
| 251 | { | ||
| 252 | for (int i = base_uint::WIDTH-1; i >= 0; i--) | ||
| 253 | { | ||
| 254 | if (a.pn[i] > b.pn[i]) | ||
| 255 | return true; | ||
| 256 | else if (a.pn[i] < b.pn[i]) | ||
| 257 | return false; | ||
| 258 | } | ||
| 259 | return true; | ||
| 260 | } | ||
| 261 | |||
| 262 | friend inline bool operator==(const base_uint& a, const base_uint& b) | ||
| 263 | { | ||
| 264 | for (int i = 0; i < base_uint::WIDTH; i++) | ||
| 265 | if (a.pn[i] != b.pn[i]) | ||
| 266 | return false; | ||
| 267 | return true; | ||
| 268 | } | ||
| 269 | |||
| 270 | friend inline bool operator==(const base_uint& a, uint64 b) | ||
| 271 | { | ||
| 272 | if (a.pn[0] != (unsigned int)b) | ||
| 273 | return false; | ||
| 274 | if (a.pn[1] != (unsigned int)(b >> 32)) | ||
| 275 | return false; | ||
| 276 | for (int i = 2; i < base_uint::WIDTH; i++) | ||
| 277 | if (a.pn[i] != 0) | ||
| 278 | return false; | ||
| 279 | return true; | ||
| 280 | } | ||
| 281 | |||
| 282 | friend inline bool operator!=(const base_uint& a, const base_uint& b) | ||
| 283 | { | ||
| 284 | return (!(a == b)); | ||
| 285 | } | ||
| 286 | |||
| 287 | friend inline bool operator!=(const base_uint& a, uint64 b) | ||
| 288 | { | ||
| 289 | return (!(a == b)); | ||
| 290 | } | ||
| 291 | |||
| 292 | |||
| 293 | |||
| 294 | std::string GetHex() const | ||
| 295 | { | ||
| 296 | char psz[sizeof(pn)*2 + 1]; | ||
| 297 | for (int i = 0; i < sizeof(pn); i++) | ||
| 298 | sprintf(psz + i*2, "%02x", ((unsigned char*)pn)[sizeof(pn) - i - 1]); | ||
| 299 | return string(psz, psz + sizeof(pn)*2); | ||
| 300 | } | ||
| 301 | |||
| 302 | void SetHex(const std::string& str) | ||
| 303 | { | ||
| 304 | for (int i = 0; i < WIDTH; i++) | ||
| 305 | pn[i] = 0; | ||
| 306 | |||
| 307 | // skip 0x | ||
| 308 | const char* psz = str.c_str(); | ||
| 309 | while (isspace(*psz)) | ||
| 310 | psz++; | ||
| 311 | if (psz[0] == '0' && tolower(psz[1]) == 'x') | ||
| 312 | psz += 2; | ||
| 313 | while (isspace(*psz)) | ||
| 314 | psz++; | ||
| 315 | |||
| 316 | // hex string to uint | ||
| 317 | static char phexdigit[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0 }; | ||
| 318 | const char* pbegin = psz; | ||
| 319 | while (phexdigit[*psz] || *psz == '0') | ||
| 320 | psz++; | ||
| 321 | psz--; | ||
| 322 | unsigned char* p1 = (unsigned char*)pn; | ||
| 323 | unsigned char* pend = p1 + WIDTH * 4; | ||
| 324 | while (psz >= pbegin && p1 < pend) | ||
| 325 | { | ||
| 326 | *p1 = phexdigit[(unsigned char)*psz--]; | ||
| 327 | if (psz >= pbegin) | ||
| 328 | { | ||
| 329 | *p1 |= (phexdigit[(unsigned char)*psz--] << 4); | ||
| 330 | p1++; | ||
| 331 | } | ||
| 332 | } | ||
| 333 | } | ||
| 334 | |||
| 335 | std::string ToString() const | ||
| 336 | { | ||
| 337 | return (GetHex()); | ||
| 338 | } | ||
| 339 | |||
| 340 | unsigned char* begin() | ||
| 341 | { | ||
| 342 | return (unsigned char*)&pn[0]; | ||
| 343 | } | ||
| 344 | |||
| 345 | unsigned char* end() | ||
| 346 | { | ||
| 347 | return (unsigned char*)&pn[WIDTH]; | ||
| 348 | } | ||
| 349 | |||
| 350 | unsigned int size() | ||
| 351 | { | ||
| 352 | return sizeof(pn); | ||
| 353 | } | ||
| 354 | |||
| 355 | |||
| 356 | unsigned int GetSerializeSize(int nType=0, int nVersion=VERSION) const | ||
| 357 | { | ||
| 358 | return sizeof(pn); | ||
| 359 | } | ||
| 360 | |||
| 361 | template<typename Stream> | ||
| 362 | void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const | ||
| 363 | { | ||
| 364 | s.write((char*)pn, sizeof(pn)); | ||
| 365 | } | ||
| 366 | |||
| 367 | template<typename Stream> | ||
| 368 | void Unserialize(Stream& s, int nType=0, int nVersion=VERSION) | ||
| 369 | { | ||
| 370 | s.read((char*)pn, sizeof(pn)); | ||
| 371 | } | ||
| 372 | |||
| 373 | |||
| 374 | friend class uint160; | ||
| 375 | friend class uint256; | ||
| 376 | friend inline int Testuint256AdHoc(vector<string> vArg); | ||
| 377 | }; | ||
| 378 | |||
| 379 | typedef base_uint<160> base_uint160; | ||
| 380 | typedef base_uint<256> base_uint256; | ||
| 381 | |||
| 382 | |||
| 383 | |||
| 384 | // | ||
| 385 | // uint160 and uint256 could be implemented as templates, but to keep | ||
| 386 | // compile errors and debugging cleaner, they're copy and pasted. | ||
| 387 | // It's safe to search and replace 160 with 256 and vice versa. | ||
| 388 | // | ||
| 389 | |||
| 390 | |||
| 391 | |||
| 392 | ////////////////////////////////////////////////////////////////////////////// | ||
| 393 | // | ||
| 394 | // uint160 | ||
| 395 | // | ||
| 396 | |||
| 397 | class uint160 : public base_uint160 | ||
| 398 | { | ||
| 399 | public: | ||
| 400 | typedef base_uint160 basetype; | ||
| 401 | |||
| 402 | uint160() | ||
| 403 | { | ||
| 404 | } | ||
| 405 | |||
| 406 | uint160(const basetype& b) | ||
| 407 | { | ||
| 408 | for (int i = 0; i < WIDTH; i++) | ||
| 409 | pn[i] = b.pn[i]; | ||
| 410 | } | ||
| 411 | |||
| 412 | uint160& operator=(const basetype& b) | ||
| 413 | { | ||
| 414 | for (int i = 0; i < WIDTH; i++) | ||
| 415 | pn[i] = b.pn[i]; | ||
| 416 | return *this; | ||
| 417 | } | ||
| 418 | |||
| 419 | uint160(uint64 b) | ||
| 420 | { | ||
| 421 | pn[0] = (unsigned int)b; | ||
| 422 | pn[1] = (unsigned int)(b >> 32); | ||
| 423 | for (int i = 2; i < WIDTH; i++) | ||
| 424 | pn[i] = 0; | ||
| 425 | } | ||
| 426 | |||
| 427 | uint160& operator=(uint64 b) | ||
| 428 | { | ||
| 429 | pn[0] = (unsigned int)b; | ||
| 430 | pn[1] = (unsigned int)(b >> 32); | ||
| 431 | for (int i = 2; i < WIDTH; i++) | ||
| 432 | pn[i] = 0; | ||
| 433 | return *this; | ||
| 434 | } | ||
| 435 | |||
| 436 | explicit uint160(const std::string& str) | ||
| 437 | { | ||
| 438 | SetHex(str); | ||
| 439 | } | ||
| 440 | |||
| 441 | explicit uint160(const std::vector<unsigned char>& vch) | ||
| 442 | { | ||
| 443 | if (vch.size() == sizeof(pn)) | ||
| 444 | memcpy(pn, &vch[0], sizeof(pn)); | ||
| 445 | else | ||
| 446 | *this = 0; | ||
| 447 | } | ||
| 448 | }; | ||
| 449 | |||
| 450 | inline bool operator==(const uint160& a, uint64 b) { return (base_uint160)a == b; } | ||
| 451 | inline bool operator!=(const uint160& a, uint64 b) { return (base_uint160)a != b; } | ||
| 452 | inline const uint160 operator<<(const base_uint160& a, unsigned int shift) { return uint160(a) <<= shift; } | ||
| 453 | inline const uint160 operator>>(const base_uint160& a, unsigned int shift) { return uint160(a) >>= shift; } | ||
| 454 | inline const uint160 operator<<(const uint160& a, unsigned int shift) { return uint160(a) <<= shift; } | ||
| 455 | inline const uint160 operator>>(const uint160& a, unsigned int shift) { return uint160(a) >>= shift; } | ||
| 456 | |||
| 457 | inline const uint160 operator^(const base_uint160& a, const base_uint160& b) { return uint160(a) ^= b; } | ||
| 458 | inline const uint160 operator&(const base_uint160& a, const base_uint160& b) { return uint160(a) &= b; } | ||
| 459 | inline const uint160 operator|(const base_uint160& a, const base_uint160& b) { return uint160(a) |= b; } | ||
| 460 | inline const uint160 operator+(const base_uint160& a, const base_uint160& b) { return uint160(a) += b; } | ||
| 461 | inline const uint160 operator-(const base_uint160& a, const base_uint160& b) { return uint160(a) -= b; } | ||
| 462 | |||
| 463 | inline bool operator<(const base_uint160& a, const uint160& b) { return (base_uint160)a < (base_uint160)b; } | ||
| 464 | inline bool operator<=(const base_uint160& a, const uint160& b) { return (base_uint160)a <= (base_uint160)b; } | ||
| 465 | inline bool operator>(const base_uint160& a, const uint160& b) { return (base_uint160)a > (base_uint160)b; } | ||
| 466 | inline bool operator>=(const base_uint160& a, const uint160& b) { return (base_uint160)a >= (base_uint160)b; } | ||
| 467 | inline bool operator==(const base_uint160& a, const uint160& b) { return (base_uint160)a == (base_uint160)b; } | ||
| 468 | inline bool operator!=(const base_uint160& a, const uint160& b) { return (base_uint160)a != (base_uint160)b; } | ||
| 469 | inline const uint160 operator^(const base_uint160& a, const uint160& b) { return (base_uint160)a ^ (base_uint160)b; } | ||
| 470 | inline const uint160 operator&(const base_uint160& a, const uint160& b) { return (base_uint160)a & (base_uint160)b; } | ||
| 471 | inline const uint160 operator|(const base_uint160& a, const uint160& b) { return (base_uint160)a | (base_uint160)b; } | ||
| 472 | inline const uint160 operator+(const base_uint160& a, const uint160& b) { return (base_uint160)a + (base_uint160)b; } | ||
| 473 | inline const uint160 operator-(const base_uint160& a, const uint160& b) { return (base_uint160)a - (base_uint160)b; } | ||
| 474 | |||
| 475 | inline bool operator<(const uint160& a, const base_uint160& b) { return (base_uint160)a < (base_uint160)b; } | ||
| 476 | inline bool operator<=(const uint160& a, const base_uint160& b) { return (base_uint160)a <= (base_uint160)b; } | ||
| 477 | inline bool operator>(const uint160& a, const base_uint160& b) { return (base_uint160)a > (base_uint160)b; } | ||
| 478 | inline bool operator>=(const uint160& a, const base_uint160& b) { return (base_uint160)a >= (base_uint160)b; } | ||
| 479 | inline bool operator==(const uint160& a, const base_uint160& b) { return (base_uint160)a == (base_uint160)b; } | ||
| 480 | inline bool operator!=(const uint160& a, const base_uint160& b) { return (base_uint160)a != (base_uint160)b; } | ||
| 481 | inline const uint160 operator^(const uint160& a, const base_uint160& b) { return (base_uint160)a ^ (base_uint160)b; } | ||
| 482 | inline const uint160 operator&(const uint160& a, const base_uint160& b) { return (base_uint160)a & (base_uint160)b; } | ||
| 483 | inline const uint160 operator|(const uint160& a, const base_uint160& b) { return (base_uint160)a | (base_uint160)b; } | ||
| 484 | inline const uint160 operator+(const uint160& a, const base_uint160& b) { return (base_uint160)a + (base_uint160)b; } | ||
| 485 | inline const uint160 operator-(const uint160& a, const base_uint160& b) { return (base_uint160)a - (base_uint160)b; } | ||
| 486 | |||
| 487 | inline bool operator<(const uint160& a, const uint160& b) { return (base_uint160)a < (base_uint160)b; } | ||
| 488 | inline bool operator<=(const uint160& a, const uint160& b) { return (base_uint160)a <= (base_uint160)b; } | ||
| 489 | inline bool operator>(const uint160& a, const uint160& b) { return (base_uint160)a > (base_uint160)b; } | ||
| 490 | inline bool operator>=(const uint160& a, const uint160& b) { return (base_uint160)a >= (base_uint160)b; } | ||
| 491 | inline bool operator==(const uint160& a, const uint160& b) { return (base_uint160)a == (base_uint160)b; } | ||
| 492 | inline bool operator!=(const uint160& a, const uint160& b) { return (base_uint160)a != (base_uint160)b; } | ||
| 493 | inline const uint160 operator^(const uint160& a, const uint160& b) { return (base_uint160)a ^ (base_uint160)b; } | ||
| 494 | inline const uint160 operator&(const uint160& a, const uint160& b) { return (base_uint160)a & (base_uint160)b; } | ||
| 495 | inline const uint160 operator|(const uint160& a, const uint160& b) { return (base_uint160)a | (base_uint160)b; } | ||
| 496 | inline const uint160 operator+(const uint160& a, const uint160& b) { return (base_uint160)a + (base_uint160)b; } | ||
| 497 | inline const uint160 operator-(const uint160& a, const uint160& b) { return (base_uint160)a - (base_uint160)b; } | ||
| 498 | |||
| 499 | |||
| 500 | |||
| 501 | |||
| 502 | |||
| 503 | |||
| 504 | ////////////////////////////////////////////////////////////////////////////// | ||
| 505 | // | ||
| 506 | // uint256 | ||
| 507 | // | ||
| 508 | |||
| 509 | class uint256 : public base_uint256 | ||
| 510 | { | ||
| 511 | public: | ||
| 512 | typedef base_uint256 basetype; | ||
| 513 | |||
| 514 | uint256() | ||
| 515 | { | ||
| 516 | } | ||
| 517 | |||
| 518 | uint256(const basetype& b) | ||
| 519 | { | ||
| 520 | for (int i = 0; i < WIDTH; i++) | ||
| 521 | pn[i] = b.pn[i]; | ||
| 522 | } | ||
| 523 | |||
| 524 | uint256& operator=(const basetype& b) | ||
| 525 | { | ||
| 526 | for (int i = 0; i < WIDTH; i++) | ||
| 527 | pn[i] = b.pn[i]; | ||
| 528 | return *this; | ||
| 529 | } | ||
| 530 | |||
| 531 | uint256(uint64 b) | ||
| 532 | { | ||
| 533 | pn[0] = (unsigned int)b; | ||
| 534 | pn[1] = (unsigned int)(b >> 32); | ||
| 535 | for (int i = 2; i < WIDTH; i++) | ||
| 536 | pn[i] = 0; | ||
| 537 | } | ||
| 538 | |||
| 539 | uint256& operator=(uint64 b) | ||
| 540 | { | ||
| 541 | pn[0] = (unsigned int)b; | ||
| 542 | pn[1] = (unsigned int)(b >> 32); | ||
| 543 | for (int i = 2; i < WIDTH; i++) | ||
| 544 | pn[i] = 0; | ||
| 545 | return *this; | ||
| 546 | } | ||
| 547 | |||
| 548 | explicit uint256(const std::string& str) | ||
| 549 | { | ||
| 550 | SetHex(str); | ||
| 551 | } | ||
| 552 | |||
| 553 | explicit uint256(const std::vector<unsigned char>& vch) | ||
| 554 | { | ||
| 555 | if (vch.size() == sizeof(pn)) | ||
| 556 | memcpy(pn, &vch[0], sizeof(pn)); | ||
| 557 | else | ||
| 558 | *this = 0; | ||
| 559 | } | ||
| 560 | }; | ||
| 561 | |||
| 562 | inline bool operator==(const uint256& a, uint64 b) { return (base_uint256)a == b; } | ||
| 563 | inline bool operator!=(const uint256& a, uint64 b) { return (base_uint256)a != b; } | ||
| 564 | inline const uint256 operator<<(const base_uint256& a, unsigned int shift) { return uint256(a) <<= shift; } | ||
| 565 | inline const uint256 operator>>(const base_uint256& a, unsigned int shift) { return uint256(a) >>= shift; } | ||
| 566 | inline const uint256 operator<<(const uint256& a, unsigned int shift) { return uint256(a) <<= shift; } | ||
| 567 | inline const uint256 operator>>(const uint256& a, unsigned int shift) { return uint256(a) >>= shift; } | ||
| 568 | |||
| 569 | inline const uint256 operator^(const base_uint256& a, const base_uint256& b) { return uint256(a) ^= b; } | ||
| 570 | inline const uint256 operator&(const base_uint256& a, const base_uint256& b) { return uint256(a) &= b; } | ||
| 571 | inline const uint256 operator|(const base_uint256& a, const base_uint256& b) { return uint256(a) |= b; } | ||
| 572 | inline const uint256 operator+(const base_uint256& a, const base_uint256& b) { return uint256(a) += b; } | ||
| 573 | inline const uint256 operator-(const base_uint256& a, const base_uint256& b) { return uint256(a) -= b; } | ||
| 574 | |||
| 575 | inline bool operator<(const base_uint256& a, const uint256& b) { return (base_uint256)a < (base_uint256)b; } | ||
| 576 | inline bool operator<=(const base_uint256& a, const uint256& b) { return (base_uint256)a <= (base_uint256)b; } | ||
| 577 | inline bool operator>(const base_uint256& a, const uint256& b) { return (base_uint256)a > (base_uint256)b; } | ||
| 578 | inline bool operator>=(const base_uint256& a, const uint256& b) { return (base_uint256)a >= (base_uint256)b; } | ||
| 579 | inline bool operator==(const base_uint256& a, const uint256& b) { return (base_uint256)a == (base_uint256)b; } | ||
| 580 | inline bool operator!=(const base_uint256& a, const uint256& b) { return (base_uint256)a != (base_uint256)b; } | ||
| 581 | inline const uint256 operator^(const base_uint256& a, const uint256& b) { return (base_uint256)a ^ (base_uint256)b; } | ||
| 582 | inline const uint256 operator&(const base_uint256& a, const uint256& b) { return (base_uint256)a & (base_uint256)b; } | ||
| 583 | inline const uint256 operator|(const base_uint256& a, const uint256& b) { return (base_uint256)a | (base_uint256)b; } | ||
| 584 | inline const uint256 operator+(const base_uint256& a, const uint256& b) { return (base_uint256)a + (base_uint256)b; } | ||
| 585 | inline const uint256 operator-(const base_uint256& a, const uint256& b) { return (base_uint256)a - (base_uint256)b; } | ||
| 586 | |||
| 587 | inline bool operator<(const uint256& a, const base_uint256& b) { return (base_uint256)a < (base_uint256)b; } | ||
| 588 | inline bool operator<=(const uint256& a, const base_uint256& b) { return (base_uint256)a <= (base_uint256)b; } | ||
| 589 | inline bool operator>(const uint256& a, const base_uint256& b) { return (base_uint256)a > (base_uint256)b; } | ||
| 590 | inline bool operator>=(const uint256& a, const base_uint256& b) { return (base_uint256)a >= (base_uint256)b; } | ||
| 591 | inline bool operator==(const uint256& a, const base_uint256& b) { return (base_uint256)a == (base_uint256)b; } | ||
| 592 | inline bool operator!=(const uint256& a, const base_uint256& b) { return (base_uint256)a != (base_uint256)b; } | ||
| 593 | inline const uint256 operator^(const uint256& a, const base_uint256& b) { return (base_uint256)a ^ (base_uint256)b; } | ||
| 594 | inline const uint256 operator&(const uint256& a, const base_uint256& b) { return (base_uint256)a & (base_uint256)b; } | ||
| 595 | inline const uint256 operator|(const uint256& a, const base_uint256& b) { return (base_uint256)a | (base_uint256)b; } | ||
| 596 | inline const uint256 operator+(const uint256& a, const base_uint256& b) { return (base_uint256)a + (base_uint256)b; } | ||
| 597 | inline const uint256 operator-(const uint256& a, const base_uint256& b) { return (base_uint256)a - (base_uint256)b; } | ||
| 598 | |||
| 599 | inline bool operator<(const uint256& a, const uint256& b) { return (base_uint256)a < (base_uint256)b; } | ||
| 600 | inline bool operator<=(const uint256& a, const uint256& b) { return (base_uint256)a <= (base_uint256)b; } | ||
| 601 | inline bool operator>(const uint256& a, const uint256& b) { return (base_uint256)a > (base_uint256)b; } | ||
| 602 | inline bool operator>=(const uint256& a, const uint256& b) { return (base_uint256)a >= (base_uint256)b; } | ||
| 603 | inline bool operator==(const uint256& a, const uint256& b) { return (base_uint256)a == (base_uint256)b; } | ||
| 604 | inline bool operator!=(const uint256& a, const uint256& b) { return (base_uint256)a != (base_uint256)b; } | ||
| 605 | inline const uint256 operator^(const uint256& a, const uint256& b) { return (base_uint256)a ^ (base_uint256)b; } | ||
| 606 | inline const uint256 operator&(const uint256& a, const uint256& b) { return (base_uint256)a & (base_uint256)b; } | ||
| 607 | inline const uint256 operator|(const uint256& a, const uint256& b) { return (base_uint256)a | (base_uint256)b; } | ||
| 608 | inline const uint256 operator+(const uint256& a, const uint256& b) { return (base_uint256)a + (base_uint256)b; } | ||
| 609 | inline const uint256 operator-(const uint256& a, const uint256& b) { return (base_uint256)a - (base_uint256)b; } | ||
| 610 | |||
| 611 | |||
| 612 | |||
| 613 | |||
| 614 | |||
| 615 | |||
| 616 | |||
| 617 | |||
| 618 | |||
| 619 | |||
| 620 | |||
| 621 | |||
| 622 | inline int Testuint256AdHoc(vector<string> vArg) | ||
| 623 | { | ||
| 624 | uint256 g(0); | ||
| 625 | |||
| 626 | |||
| 627 | printf("%s\n", g.ToString().c_str()); | ||
| 628 | g--; printf("g--\n"); | ||
| 629 | printf("%s\n", g.ToString().c_str()); | ||
| 630 | g--; printf("g--\n"); | ||
| 631 | printf("%s\n", g.ToString().c_str()); | ||
| 632 | g++; printf("g++\n"); | ||
| 633 | printf("%s\n", g.ToString().c_str()); | ||
| 634 | g++; printf("g++\n"); | ||
| 635 | printf("%s\n", g.ToString().c_str()); | ||
| 636 | g++; printf("g++\n"); | ||
| 637 | printf("%s\n", g.ToString().c_str()); | ||
| 638 | g++; printf("g++\n"); | ||
| 639 | printf("%s\n", g.ToString().c_str()); | ||
| 640 | |||
| 641 | |||
| 642 | |||
| 643 | uint256 a(7); | ||
| 644 | printf("a=7\n"); | ||
| 645 | printf("%s\n", a.ToString().c_str()); | ||
| 646 | |||
| 647 | uint256 b; | ||
| 648 | printf("b undefined\n"); | ||
| 649 | printf("%s\n", b.ToString().c_str()); | ||
| 650 | int c = 3; | ||
| 651 | |||
| 652 | a = c; | ||
| 653 | a.pn[3] = 15; | ||
| 654 | printf("%s\n", a.ToString().c_str()); | ||
| 655 | uint256 k(c); | ||
| 656 | |||
| 657 | a = 5; | ||
| 658 | a.pn[3] = 15; | ||
| 659 | printf("%s\n", a.ToString().c_str()); | ||
| 660 | b = 1; | ||
| 661 | b <<= 52; | ||
| 662 | |||
| 663 | a |= b; | ||
| 664 | |||
| 665 | a ^= 0x500; | ||
| 666 | |||
| 667 | printf("a %s\n", a.ToString().c_str()); | ||
| 668 | |||
| 669 | a = a | b | (uint256)0x1000; | ||
| 670 | |||
| 671 | |||
| 672 | printf("a %s\n", a.ToString().c_str()); | ||
| 673 | printf("b %s\n", b.ToString().c_str()); | ||
| 674 | |||
| 675 | a = 0xfffffffe; | ||
| 676 | a.pn[4] = 9; | ||
| 677 | |||
| 678 | printf("%s\n", a.ToString().c_str()); | ||
| 679 | a++; | ||
| 680 | printf("%s\n", a.ToString().c_str()); | ||
| 681 | a++; | ||
| 682 | printf("%s\n", a.ToString().c_str()); | ||
| 683 | a++; | ||
| 684 | printf("%s\n", a.ToString().c_str()); | ||
| 685 | a++; | ||
| 686 | printf("%s\n", a.ToString().c_str()); | ||
| 687 | |||
| 688 | a--; | ||
| 689 | printf("%s\n", a.ToString().c_str()); | ||
| 690 | a--; | ||
| 691 | printf("%s\n", a.ToString().c_str()); | ||
| 692 | a--; | ||
| 693 | printf("%s\n", a.ToString().c_str()); | ||
| 694 | uint256 d = a--; | ||
| 695 | printf("%s\n", d.ToString().c_str()); | ||
| 696 | printf("%s\n", a.ToString().c_str()); | ||
| 697 | a--; | ||
| 698 | printf("%s\n", a.ToString().c_str()); | ||
| 699 | a--; | ||
| 700 | printf("%s\n", a.ToString().c_str()); | ||
| 701 | |||
| 702 | d = a; | ||
| 703 | |||
| 704 | printf("%s\n", d.ToString().c_str()); | ||
| 705 | for (int i = uint256::WIDTH-1; i >= 0; i--) printf("%08x", d.pn[i]); printf("\n"); | ||
| 706 | |||
| 707 | uint256 neg = d; | ||
| 708 | neg = ~neg; | ||
| 709 | printf("%s\n", neg.ToString().c_str()); | ||
| 710 | |||
| 711 | |||
| 712 | uint256 e = uint256("0xABCDEF123abcdef12345678909832180000011111111"); | ||
| 713 | printf("\n"); | ||
| 714 | printf("%s\n", e.ToString().c_str()); | ||
| 715 | |||
| 716 | |||
| 717 | printf("\n"); | ||
| 718 | uint256 x1 = uint256("0xABCDEF123abcdef12345678909832180000011111111"); | ||
| 719 | uint256 x2; | ||
| 720 | printf("%s\n", x1.ToString().c_str()); | ||
| 721 | for (int i = 0; i < 270; i += 4) | ||
| 722 | { | ||
| 723 | x2 = x1 << i; | ||
| 724 | printf("%s\n", x2.ToString().c_str()); | ||
| 725 | } | ||
| 726 | |||
| 727 | printf("\n"); | ||
| 728 | printf("%s\n", x1.ToString().c_str()); | ||
| 729 | for (int i = 0; i < 270; i += 4) | ||
| 730 | { | ||
| 731 | x2 = x1; | ||
| 732 | x2 >>= i; | ||
| 733 | printf("%s\n", x2.ToString().c_str()); | ||
| 734 | } | ||
| 735 | |||
| 736 | |||
| 737 | for (int i = 0; i < 100; i++) | ||
| 738 | { | ||
| 739 | uint256 k = (~uint256(0) >> i); | ||
| 740 | printf("%s\n", k.ToString().c_str()); | ||
| 741 | } | ||
| 742 | |||
| 743 | for (int i = 0; i < 100; i++) | ||
| 744 | { | ||
| 745 | uint256 k = (~uint256(0) << i); | ||
| 746 | printf("%s\n", k.ToString().c_str()); | ||
| 747 | } | ||
| 748 | |||
| 749 | return (0); | ||
| 750 | } | ||
diff --git a/src/uiproject.fbp b/src/uiproject.fbp new file mode 100644 index 0000000..57a2950 --- /dev/null +++ b/src/uiproject.fbp | |||
| @@ -0,0 +1,11825 @@ | |||
| 1 | <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> | ||
| 2 | <wxFormBuilder_Project> | ||
| 3 | <FileVersion major="1" minor="9" /> | ||
| 4 | <object class="Project" expanded="1"> | ||
| 5 | <property name="class_decoration"></property> | ||
| 6 | <property name="code_generation">C++</property> | ||
| 7 | <property name="disconnect_events">1</property> | ||
| 8 | <property name="encoding">UTF-8</property> | ||
| 9 | <property name="event_generation">connect</property> | ||
| 10 | <property name="file">uibase</property> | ||
| 11 | <property name="first_id">1000</property> | ||
| 12 | <property name="help_provider">none</property> | ||
| 13 | <property name="internationalize">0</property> | ||
| 14 | <property name="name"></property> | ||
| 15 | <property name="namespace"></property> | ||
| 16 | <property name="path">.</property> | ||
| 17 | <property name="precompiled_header"></property> | ||
| 18 | <property name="relative_path">1</property> | ||
| 19 | <property name="use_enum">0</property> | ||
| 20 | <property name="use_microsoft_bom">0</property> | ||
| 21 | <object class="Frame" expanded="0"> | ||
| 22 | <property name="bg">wxSYS_COLOUR_BTNFACE</property> | ||
| 23 | <property name="center"></property> | ||
| 24 | <property name="context_help"></property> | ||
| 25 | <property name="enabled">1</property> | ||
| 26 | <property name="extra_style"></property> | ||
| 27 | <property name="fg"></property> | ||
| 28 | <property name="font"></property> | ||
| 29 | <property name="hidden">0</property> | ||
| 30 | <property name="id">wxID_MAINFRAME</property> | ||
| 31 | <property name="maximum_size"></property> | ||
| 32 | <property name="minimum_size"></property> | ||
| 33 | <property name="name">CMainFrameBase</property> | ||
| 34 | <property name="pos"></property> | ||
| 35 | <property name="size">705,484</property> | ||
| 36 | <property name="style">wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER</property> | ||
| 37 | <property name="subclass"></property> | ||
| 38 | <property name="title">Bitcoin</property> | ||
| 39 | <property name="tooltip"></property> | ||
| 40 | <property name="window_extra_style"></property> | ||
| 41 | <property name="window_name"></property> | ||
| 42 | <property name="window_style">wxTAB_TRAVERSAL</property> | ||
| 43 | <property name="xrc_skip_sizer">1</property> | ||
| 44 | <event name="OnActivate"></event> | ||
| 45 | <event name="OnActivateApp"></event> | ||
| 46 | <event name="OnChar"></event> | ||
| 47 | <event name="OnClose">OnClose</event> | ||
| 48 | <event name="OnEnterWindow"></event> | ||
| 49 | <event name="OnEraseBackground"></event> | ||
| 50 | <event name="OnHibernate"></event> | ||
| 51 | <event name="OnIconize"></event> | ||
| 52 | <event name="OnIdle">OnIdle</event> | ||
| 53 | <event name="OnKeyDown"></event> | ||
| 54 | <event name="OnKeyUp"></event> | ||
| 55 | <event name="OnKillFocus"></event> | ||
| 56 | <event name="OnLeaveWindow"></event> | ||
| 57 | <event name="OnLeftDClick"></event> | ||
| 58 | <event name="OnLeftDown"></event> | ||
| 59 | <event name="OnLeftUp"></event> | ||
| 60 | <event name="OnMiddleDClick"></event> | ||
| 61 | <event name="OnMiddleDown"></event> | ||
| 62 | <event name="OnMiddleUp"></event> | ||
| 63 | <event name="OnMotion"></event> | ||
| 64 | <event name="OnMouseEvents">OnMouseEvents</event> | ||
| 65 | <event name="OnMouseWheel"></event> | ||
| 66 | <event name="OnPaint">OnPaint</event> | ||
| 67 | <event name="OnRightDClick"></event> | ||
| 68 | <event name="OnRightDown"></event> | ||
| 69 | <event name="OnRightUp"></event> | ||
| 70 | <event name="OnSetFocus"></event> | ||
| 71 | <event name="OnSize"></event> | ||
| 72 | <event name="OnUpdateUI"></event> | ||
| 73 | <object class="wxMenuBar" expanded="1"> | ||
| 74 | <property name="bg">240,240,240</property> | ||
| 75 | <property name="context_help"></property> | ||
| 76 | <property name="enabled">1</property> | ||
| 77 | <property name="fg"></property> | ||
| 78 | <property name="font"></property> | ||
| 79 | <property name="hidden">0</property> | ||
| 80 | <property name="id">wxID_ANY</property> | ||
| 81 | <property name="label">MyMenuBar</property> | ||
| 82 | <property name="maximum_size"></property> | ||
| 83 | <property name="minimum_size"></property> | ||
| 84 | <property name="name">m_menubar</property> | ||
| 85 | <property name="permission">protected</property> | ||
| 86 | <property name="pos"></property> | ||
| 87 | <property name="size"></property> | ||
| 88 | <property name="style"></property> | ||
| 89 | <property name="subclass"></property> | ||
| 90 | <property name="tooltip"></property> | ||
| 91 | <property name="window_extra_style"></property> | ||
| 92 | <property name="window_name"></property> | ||
| 93 | <property name="window_style"></property> | ||
| 94 | <event name="OnChar"></event> | ||
| 95 | <event name="OnEnterWindow"></event> | ||
| 96 | <event name="OnEraseBackground"></event> | ||
| 97 | <event name="OnKeyDown"></event> | ||
| 98 | <event name="OnKeyUp"></event> | ||
| 99 | <event name="OnKillFocus"></event> | ||
| 100 | <event name="OnLeaveWindow"></event> | ||
| 101 | <event name="OnLeftDClick"></event> | ||
| 102 | <event name="OnLeftDown"></event> | ||
| 103 | <event name="OnLeftUp"></event> | ||
| 104 | <event name="OnMiddleDClick"></event> | ||
| 105 | <event name="OnMiddleDown"></event> | ||
| 106 | <event name="OnMiddleUp"></event> | ||
| 107 | <event name="OnMotion"></event> | ||
| 108 | <event name="OnMouseEvents"></event> | ||
| 109 | <event name="OnMouseWheel"></event> | ||
| 110 | <event name="OnPaint"></event> | ||
| 111 | <event name="OnRightDClick"></event> | ||
| 112 | <event name="OnRightDown"></event> | ||
| 113 | <event name="OnRightUp"></event> | ||
| 114 | <event name="OnSetFocus"></event> | ||
| 115 | <event name="OnSize"></event> | ||
| 116 | <event name="OnUpdateUI"></event> | ||
| 117 | <object class="wxMenu" expanded="1"> | ||
| 118 | <property name="label">&File</property> | ||
| 119 | <property name="name">m_menuFile</property> | ||
| 120 | <property name="permission">protected</property> | ||
| 121 | <object class="wxMenuItem" expanded="1"> | ||
| 122 | <property name="bitmap"></property> | ||
| 123 | <property name="checked">0</property> | ||
| 124 | <property name="enabled">1</property> | ||
| 125 | <property name="help"></property> | ||
| 126 | <property name="id">wxID_ANY</property> | ||
| 127 | <property name="kind">wxITEM_NORMAL</property> | ||
| 128 | <property name="label">E&xit</property> | ||
| 129 | <property name="name">m_menuFileExit</property> | ||
| 130 | <property name="permission">none</property> | ||
| 131 | <property name="shortcut"></property> | ||
| 132 | <property name="unchecked_bitmap"></property> | ||
| 133 | <event name="OnMenuSelection">OnMenuFileExit</event> | ||
| 134 | <event name="OnUpdateUI"></event> | ||
| 135 | </object> | ||
| 136 | </object> | ||
| 137 | <object class="wxMenu" expanded="1"> | ||
| 138 | <property name="label">&Options</property> | ||
| 139 | <property name="name">m_menuOptions</property> | ||
| 140 | <property name="permission">public</property> | ||
| 141 | <object class="wxMenuItem" expanded="1"> | ||
| 142 | <property name="bitmap"></property> | ||
| 143 | <property name="checked">0</property> | ||
| 144 | <property name="enabled">1</property> | ||
| 145 | <property name="help"></property> | ||
| 146 | <property name="id">wxID_OPTIONSGENERATEBITCOINS</property> | ||
| 147 | <property name="kind">wxITEM_CHECK</property> | ||
| 148 | <property name="label">&Generate Coins</property> | ||
| 149 | <property name="name">m_menuOptionsGenerateBitcoins</property> | ||
| 150 | <property name="permission">none</property> | ||
| 151 | <property name="shortcut"></property> | ||
| 152 | <property name="unchecked_bitmap"></property> | ||
| 153 | <event name="OnMenuSelection">OnMenuOptionsGenerate</event> | ||
| 154 | <event name="OnUpdateUI"></event> | ||
| 155 | </object> | ||
| 156 | <object class="wxMenuItem" expanded="1"> | ||
| 157 | <property name="bitmap"></property> | ||
| 158 | <property name="checked">0</property> | ||
| 159 | <property name="enabled">1</property> | ||
| 160 | <property name="help"></property> | ||
| 161 | <property name="id">wxID_ANY</property> | ||
| 162 | <property name="kind">wxITEM_NORMAL</property> | ||
| 163 | <property name="label">&Options...</property> | ||
| 164 | <property name="name">m_menuOptionsOptions</property> | ||
| 165 | <property name="permission">none</property> | ||
| 166 | <property name="shortcut"></property> | ||
| 167 | <property name="unchecked_bitmap"></property> | ||
| 168 | <event name="OnMenuSelection">OnMenuOptionsOptions</event> | ||
| 169 | <event name="OnUpdateUI"></event> | ||
| 170 | </object> | ||
| 171 | </object> | ||
| 172 | <object class="wxMenu" expanded="1"> | ||
| 173 | <property name="label">&Help</property> | ||
| 174 | <property name="name">m_menuHelp</property> | ||
| 175 | <property name="permission">protected</property> | ||
| 176 | <object class="wxMenuItem" expanded="1"> | ||
| 177 | <property name="bitmap"></property> | ||
| 178 | <property name="checked">0</property> | ||
| 179 | <property name="enabled">1</property> | ||
| 180 | <property name="help"></property> | ||
| 181 | <property name="id">wxID_ANY</property> | ||
| 182 | <property name="kind">wxITEM_NORMAL</property> | ||
| 183 | <property name="label">&About...</property> | ||
| 184 | <property name="name">m_menuHelpAbout</property> | ||
| 185 | <property name="permission">none</property> | ||
| 186 | <property name="shortcut"></property> | ||
| 187 | <property name="unchecked_bitmap"></property> | ||
| 188 | <event name="OnMenuSelection">OnMenuHelpAbout</event> | ||
| 189 | <event name="OnUpdateUI"></event> | ||
| 190 | </object> | ||
| 191 | </object> | ||
| 192 | </object> | ||
| 193 | <object class="wxToolBar" expanded="0"> | ||
| 194 | <property name="bg"></property> | ||
| 195 | <property name="bitmapsize">20,20</property> | ||
| 196 | <property name="context_help"></property> | ||
| 197 | <property name="enabled">1</property> | ||
| 198 | <property name="fg"></property> | ||
| 199 | <property name="font">,90,90,-1,70,0</property> | ||
| 200 | <property name="hidden">0</property> | ||
| 201 | <property name="id">wxID_ANY</property> | ||
| 202 | <property name="margins"></property> | ||
| 203 | <property name="maximum_size"></property> | ||
| 204 | <property name="minimum_size"></property> | ||
| 205 | <property name="name">m_toolBar</property> | ||
| 206 | <property name="packing">1</property> | ||
| 207 | <property name="permission">protected</property> | ||
| 208 | <property name="pos"></property> | ||
| 209 | <property name="separation">1</property> | ||
| 210 | <property name="size">-1,-1</property> | ||
| 211 | <property name="style">wxTB_FLAT|wxTB_HORZ_TEXT</property> | ||
| 212 | <property name="subclass"></property> | ||
| 213 | <property name="tooltip"></property> | ||
| 214 | <property name="window_extra_style"></property> | ||
| 215 | <property name="window_name"></property> | ||
| 216 | <property name="window_style"></property> | ||
| 217 | <event name="OnChar"></event> | ||
| 218 | <event name="OnEnterWindow"></event> | ||
| 219 | <event name="OnEraseBackground"></event> | ||
| 220 | <event name="OnKeyDown"></event> | ||
| 221 | <event name="OnKeyUp"></event> | ||
| 222 | <event name="OnKillFocus"></event> | ||
| 223 | <event name="OnLeaveWindow"></event> | ||
| 224 | <event name="OnLeftDClick"></event> | ||
| 225 | <event name="OnLeftDown"></event> | ||
| 226 | <event name="OnLeftUp"></event> | ||
| 227 | <event name="OnMiddleDClick"></event> | ||
| 228 | <event name="OnMiddleDown"></event> | ||
| 229 | <event name="OnMiddleUp"></event> | ||
| 230 | <event name="OnMotion"></event> | ||
| 231 | <event name="OnMouseEvents"></event> | ||
| 232 | <event name="OnMouseWheel"></event> | ||
| 233 | <event name="OnPaint"></event> | ||
| 234 | <event name="OnRightDClick"></event> | ||
| 235 | <event name="OnRightDown"></event> | ||
| 236 | <event name="OnRightUp"></event> | ||
| 237 | <event name="OnSetFocus"></event> | ||
| 238 | <event name="OnSize"></event> | ||
| 239 | <event name="OnUpdateUI"></event> | ||
| 240 | <object class="tool" expanded="1"> | ||
| 241 | <property name="bitmap">send20; Load From Resource</property> | ||
| 242 | <property name="id">wxID_BUTTONSEND</property> | ||
| 243 | <property name="kind">wxITEM_NORMAL</property> | ||
| 244 | <property name="label">&Send Coins</property> | ||
| 245 | <property name="name">m_tool1</property> | ||
| 246 | <property name="statusbar"></property> | ||
| 247 | <property name="tooltip"></property> | ||
| 248 | <event name="OnMenuSelection"></event> | ||
| 249 | <event name="OnToolClicked">OnButtonSend</event> | ||
| 250 | <event name="OnToolEnter"></event> | ||
| 251 | <event name="OnToolRClicked"></event> | ||
| 252 | <event name="OnUpdateUI"></event> | ||
| 253 | </object> | ||
| 254 | <object class="tool" expanded="1"> | ||
| 255 | <property name="bitmap">addressbook20; Load From Resource</property> | ||
| 256 | <property name="id">wxID_BUTTONRECEIVE</property> | ||
| 257 | <property name="kind">wxITEM_NORMAL</property> | ||
| 258 | <property name="label">&Address Book</property> | ||
| 259 | <property name="name">m_tool2</property> | ||
| 260 | <property name="statusbar"></property> | ||
| 261 | <property name="tooltip"></property> | ||
| 262 | <event name="OnMenuSelection"></event> | ||
| 263 | <event name="OnToolClicked">OnButtonAddressBook</event> | ||
| 264 | <event name="OnToolEnter"></event> | ||
| 265 | <event name="OnToolRClicked"></event> | ||
| 266 | <event name="OnUpdateUI"></event> | ||
| 267 | </object> | ||
| 268 | </object> | ||
| 269 | <object class="wxStatusBar" expanded="1"> | ||
| 270 | <property name="bg">240,240,240</property> | ||
| 271 | <property name="context_help"></property> | ||
| 272 | <property name="enabled">1</property> | ||
| 273 | <property name="fg"></property> | ||
| 274 | <property name="fields">1</property> | ||
| 275 | <property name="font"></property> | ||
| 276 | <property name="hidden">0</property> | ||
| 277 | <property name="id">wxID_ANY</property> | ||
| 278 | <property name="maximum_size"></property> | ||
| 279 | <property name="minimum_size"></property> | ||
| 280 | <property name="name">m_statusBar</property> | ||
| 281 | <property name="permission">protected</property> | ||
| 282 | <property name="pos"></property> | ||
| 283 | <property name="size"></property> | ||
| 284 | <property name="style">wxST_SIZEGRIP</property> | ||
| 285 | <property name="subclass"></property> | ||
| 286 | <property name="tooltip"></property> | ||
| 287 | <property name="window_extra_style"></property> | ||
| 288 | <property name="window_name"></property> | ||
| 289 | <property name="window_style"></property> | ||
| 290 | <event name="OnChar"></event> | ||
| 291 | <event name="OnEnterWindow"></event> | ||
| 292 | <event name="OnEraseBackground"></event> | ||
| 293 | <event name="OnKeyDown"></event> | ||
| 294 | <event name="OnKeyUp"></event> | ||
| 295 | <event name="OnKillFocus"></event> | ||
| 296 | <event name="OnLeaveWindow"></event> | ||
| 297 | <event name="OnLeftDClick"></event> | ||
| 298 | <event name="OnLeftDown"></event> | ||
| 299 | <event name="OnLeftUp"></event> | ||
| 300 | <event name="OnMiddleDClick"></event> | ||
| 301 | <event name="OnMiddleDown"></event> | ||
| 302 | <event name="OnMiddleUp"></event> | ||
| 303 | <event name="OnMotion"></event> | ||
| 304 | <event name="OnMouseEvents"></event> | ||
| 305 | <event name="OnMouseWheel"></event> | ||
| 306 | <event name="OnPaint"></event> | ||
| 307 | <event name="OnRightDClick"></event> | ||
| 308 | <event name="OnRightDown"></event> | ||
| 309 | <event name="OnRightUp"></event> | ||
| 310 | <event name="OnSetFocus"></event> | ||
| 311 | <event name="OnSize"></event> | ||
| 312 | <event name="OnUpdateUI"></event> | ||
| 313 | </object> | ||
| 314 | <object class="wxBoxSizer" expanded="0"> | ||
| 315 | <property name="minimum_size"></property> | ||
| 316 | <property name="name">bSizer2</property> | ||
| 317 | <property name="orient">wxVERTICAL</property> | ||
| 318 | <property name="permission">none</property> | ||
| 319 | <object class="sizeritem" expanded="1"> | ||
| 320 | <property name="border">5</property> | ||
| 321 | <property name="flag">wxEXPAND</property> | ||
| 322 | <property name="proportion">0</property> | ||
| 323 | <object class="spacer" expanded="1"> | ||
| 324 | <property name="height">2</property> | ||
| 325 | <property name="permission">protected</property> | ||
| 326 | <property name="width">0</property> | ||
| 327 | </object> | ||
| 328 | </object> | ||
| 329 | <object class="sizeritem" expanded="1"> | ||
| 330 | <property name="border">5</property> | ||
| 331 | <property name="flag">wxEXPAND|wxRIGHT|wxLEFT</property> | ||
| 332 | <property name="proportion">0</property> | ||
| 333 | <object class="wxBoxSizer" expanded="1"> | ||
| 334 | <property name="minimum_size"></property> | ||
| 335 | <property name="name">bSizer85</property> | ||
| 336 | <property name="orient">wxHORIZONTAL</property> | ||
| 337 | <property name="permission">none</property> | ||
| 338 | <object class="sizeritem" expanded="1"> | ||
| 339 | <property name="border">5</property> | ||
| 340 | <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT</property> | ||
| 341 | <property name="proportion">0</property> | ||
| 342 | <object class="wxStaticText" expanded="1"> | ||
| 343 | <property name="bg"></property> | ||
| 344 | <property name="context_help"></property> | ||
| 345 | <property name="enabled">1</property> | ||
| 346 | <property name="fg"></property> | ||
| 347 | <property name="font"></property> | ||
| 348 | <property name="hidden">0</property> | ||
| 349 | <property name="id">wxID_ANY</property> | ||
| 350 | <property name="label">Your Bitcoin Address:</property> | ||
| 351 | <property name="maximum_size"></property> | ||
| 352 | <property name="minimum_size"></property> | ||
| 353 | <property name="name">m_staticText32</property> | ||
| 354 | <property name="permission">protected</property> | ||
| 355 | <property name="pos"></property> | ||
| 356 | <property name="size"></property> | ||
| 357 | <property name="style"></property> | ||
| 358 | <property name="subclass"></property> | ||
| 359 | <property name="tooltip"></property> | ||
| 360 | <property name="window_extra_style"></property> | ||
| 361 | <property name="window_name"></property> | ||
| 362 | <property name="window_style"></property> | ||
| 363 | <property name="wrap">-1</property> | ||
| 364 | <event name="OnChar"></event> | ||
| 365 | <event name="OnEnterWindow"></event> | ||
| 366 | <event name="OnEraseBackground"></event> | ||
| 367 | <event name="OnKeyDown"></event> | ||
| 368 | <event name="OnKeyUp"></event> | ||
| 369 | <event name="OnKillFocus"></event> | ||
| 370 | <event name="OnLeaveWindow"></event> | ||
| 371 | <event name="OnLeftDClick"></event> | ||
| 372 | <event name="OnLeftDown"></event> | ||
| 373 | <event name="OnLeftUp"></event> | ||
| 374 | <event name="OnMiddleDClick"></event> | ||
| 375 | <event name="OnMiddleDown"></event> | ||
| 376 | <event name="OnMiddleUp"></event> | ||
| 377 | <event name="OnMotion"></event> | ||
| 378 | <event name="OnMouseEvents"></event> | ||
| 379 | <event name="OnMouseWheel"></event> | ||
| 380 | <event name="OnPaint"></event> | ||
| 381 | <event name="OnRightDClick"></event> | ||
| 382 | <event name="OnRightDown"></event> | ||
| 383 | <event name="OnRightUp"></event> | ||
| 384 | <event name="OnSetFocus"></event> | ||
| 385 | <event name="OnSize"></event> | ||
| 386 | <event name="OnUpdateUI"></event> | ||
| 387 | </object> | ||
| 388 | </object> | ||
| 389 | <object class="sizeritem" expanded="1"> | ||
| 390 | <property name="border">5</property> | ||
| 391 | <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property> | ||
| 392 | <property name="proportion">0</property> | ||
| 393 | <object class="wxTextCtrl" expanded="1"> | ||
| 394 | <property name="bg">wxSYS_COLOUR_MENU</property> | ||
| 395 | <property name="context_help"></property> | ||
| 396 | <property name="enabled">1</property> | ||
| 397 | <property name="fg"></property> | ||
| 398 | <property name="font"></property> | ||
| 399 | <property name="hidden">0</property> | ||
| 400 | <property name="id">wxID_TEXTCTRLADDRESS</property> | ||
| 401 | <property name="maximum_size">-1,-1</property> | ||
| 402 | <property name="maxlength">0</property> | ||
| 403 | <property name="minimum_size">-1,-1</property> | ||
| 404 | <property name="name">m_textCtrlAddress</property> | ||
| 405 | <property name="permission">protected</property> | ||
| 406 | <property name="pos"></property> | ||
| 407 | <property name="size">250,-1</property> | ||
| 408 | <property name="style">wxTE_READONLY</property> | ||
| 409 | <property name="subclass"></property> | ||
| 410 | <property name="tooltip"></property> | ||
| 411 | <property name="value"></property> | ||
| 412 | <property name="window_extra_style"></property> | ||
| 413 | <property name="window_name"></property> | ||
| 414 | <property name="window_style"></property> | ||
| 415 | <event name="OnChar"></event> | ||
| 416 | <event name="OnEnterWindow"></event> | ||
| 417 | <event name="OnEraseBackground"></event> | ||
| 418 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 419 | <event name="OnKeyUp"></event> | ||
| 420 | <event name="OnKillFocus"></event> | ||
| 421 | <event name="OnLeaveWindow"></event> | ||
| 422 | <event name="OnLeftDClick"></event> | ||
| 423 | <event name="OnLeftDown"></event> | ||
| 424 | <event name="OnLeftUp"></event> | ||
| 425 | <event name="OnMiddleDClick"></event> | ||
| 426 | <event name="OnMiddleDown"></event> | ||
| 427 | <event name="OnMiddleUp"></event> | ||
| 428 | <event name="OnMotion"></event> | ||
| 429 | <event name="OnMouseEvents">OnMouseEventsAddress</event> | ||
| 430 | <event name="OnMouseWheel"></event> | ||
| 431 | <event name="OnPaint"></event> | ||
| 432 | <event name="OnRightDClick"></event> | ||
| 433 | <event name="OnRightDown"></event> | ||
| 434 | <event name="OnRightUp"></event> | ||
| 435 | <event name="OnSetFocus">OnSetFocusAddress</event> | ||
| 436 | <event name="OnSize"></event> | ||
| 437 | <event name="OnText"></event> | ||
| 438 | <event name="OnTextEnter"></event> | ||
| 439 | <event name="OnTextMaxLen"></event> | ||
| 440 | <event name="OnTextURL"></event> | ||
| 441 | <event name="OnUpdateUI"></event> | ||
| 442 | </object> | ||
| 443 | </object> | ||
| 444 | <object class="sizeritem" expanded="1"> | ||
| 445 | <property name="border">5</property> | ||
| 446 | <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT</property> | ||
| 447 | <property name="proportion">0</property> | ||
| 448 | <object class="wxButton" expanded="1"> | ||
| 449 | <property name="bg"></property> | ||
| 450 | <property name="context_help"></property> | ||
| 451 | <property name="default">0</property> | ||
| 452 | <property name="enabled">1</property> | ||
| 453 | <property name="fg"></property> | ||
| 454 | <property name="font"></property> | ||
| 455 | <property name="hidden">0</property> | ||
| 456 | <property name="id">wxID_BUTTONCOPY</property> | ||
| 457 | <property name="label">&Copy to Clipboard</property> | ||
| 458 | <property name="maximum_size"></property> | ||
| 459 | <property name="minimum_size"></property> | ||
| 460 | <property name="name">m_buttonCopy</property> | ||
| 461 | <property name="permission">protected</property> | ||
| 462 | <property name="pos"></property> | ||
| 463 | <property name="size"></property> | ||
| 464 | <property name="style">wxBU_EXACTFIT</property> | ||
| 465 | <property name="subclass"></property> | ||
| 466 | <property name="tooltip"></property> | ||
| 467 | <property name="window_extra_style"></property> | ||
| 468 | <property name="window_name"></property> | ||
| 469 | <property name="window_style"></property> | ||
| 470 | <event name="OnButtonClick">OnButtonCopy</event> | ||
| 471 | <event name="OnChar"></event> | ||
| 472 | <event name="OnEnterWindow"></event> | ||
| 473 | <event name="OnEraseBackground"></event> | ||
| 474 | <event name="OnKeyDown"></event> | ||
| 475 | <event name="OnKeyUp"></event> | ||
| 476 | <event name="OnKillFocus"></event> | ||
| 477 | <event name="OnLeaveWindow"></event> | ||
| 478 | <event name="OnLeftDClick"></event> | ||
| 479 | <event name="OnLeftDown"></event> | ||
| 480 | <event name="OnLeftUp"></event> | ||
| 481 | <event name="OnMiddleDClick"></event> | ||
| 482 | <event name="OnMiddleDown"></event> | ||
| 483 | <event name="OnMiddleUp"></event> | ||
| 484 | <event name="OnMotion"></event> | ||
| 485 | <event name="OnMouseEvents"></event> | ||
| 486 | <event name="OnMouseWheel"></event> | ||
| 487 | <event name="OnPaint"></event> | ||
| 488 | <event name="OnRightDClick"></event> | ||
| 489 | <event name="OnRightDown"></event> | ||
| 490 | <event name="OnRightUp"></event> | ||
| 491 | <event name="OnSetFocus"></event> | ||
| 492 | <event name="OnSize"></event> | ||
| 493 | <event name="OnUpdateUI"></event> | ||
| 494 | </object> | ||
| 495 | </object> | ||
| 496 | <object class="sizeritem" expanded="1"> | ||
| 497 | <property name="border">5</property> | ||
| 498 | <property name="flag">wxRIGHT</property> | ||
| 499 | <property name="proportion">0</property> | ||
| 500 | <object class="wxButton" expanded="1"> | ||
| 501 | <property name="bg"></property> | ||
| 502 | <property name="context_help"></property> | ||
| 503 | <property name="default">0</property> | ||
| 504 | <property name="enabled">1</property> | ||
| 505 | <property name="fg"></property> | ||
| 506 | <property name="font"></property> | ||
| 507 | <property name="hidden">0</property> | ||
| 508 | <property name="id">wxID_BUTTONCHANGE</property> | ||
| 509 | <property name="label">C&hange...</property> | ||
| 510 | <property name="maximum_size"></property> | ||
| 511 | <property name="minimum_size"></property> | ||
| 512 | <property name="name">m_button91</property> | ||
| 513 | <property name="permission">protected</property> | ||
| 514 | <property name="pos"></property> | ||
| 515 | <property name="size"></property> | ||
| 516 | <property name="style"></property> | ||
| 517 | <property name="subclass"></property> | ||
| 518 | <property name="tooltip"></property> | ||
| 519 | <property name="window_extra_style"></property> | ||
| 520 | <property name="window_name"></property> | ||
| 521 | <property name="window_style"></property> | ||
| 522 | <event name="OnButtonClick">OnButtonChange</event> | ||
| 523 | <event name="OnChar"></event> | ||
| 524 | <event name="OnEnterWindow"></event> | ||
| 525 | <event name="OnEraseBackground"></event> | ||
| 526 | <event name="OnKeyDown"></event> | ||
| 527 | <event name="OnKeyUp"></event> | ||
| 528 | <event name="OnKillFocus"></event> | ||
| 529 | <event name="OnLeaveWindow"></event> | ||
| 530 | <event name="OnLeftDClick"></event> | ||
| 531 | <event name="OnLeftDown"></event> | ||
| 532 | <event name="OnLeftUp"></event> | ||
| 533 | <event name="OnMiddleDClick"></event> | ||
| 534 | <event name="OnMiddleDown"></event> | ||
| 535 | <event name="OnMiddleUp"></event> | ||
| 536 | <event name="OnMotion"></event> | ||
| 537 | <event name="OnMouseEvents"></event> | ||
| 538 | <event name="OnMouseWheel"></event> | ||
| 539 | <event name="OnPaint"></event> | ||
| 540 | <event name="OnRightDClick"></event> | ||
| 541 | <event name="OnRightDown"></event> | ||
| 542 | <event name="OnRightUp"></event> | ||
| 543 | <event name="OnSetFocus"></event> | ||
| 544 | <event name="OnSize"></event> | ||
| 545 | <event name="OnUpdateUI"></event> | ||
| 546 | </object> | ||
| 547 | </object> | ||
| 548 | <object class="sizeritem" expanded="1"> | ||
| 549 | <property name="border">5</property> | ||
| 550 | <property name="flag">wxEXPAND</property> | ||
| 551 | <property name="proportion">0</property> | ||
| 552 | <object class="spacer" expanded="1"> | ||
| 553 | <property name="height">0</property> | ||
| 554 | <property name="permission">protected</property> | ||
| 555 | <property name="width">0</property> | ||
| 556 | </object> | ||
| 557 | </object> | ||
| 558 | </object> | ||
| 559 | </object> | ||
| 560 | <object class="sizeritem" expanded="1"> | ||
| 561 | <property name="border">5</property> | ||
| 562 | <property name="flag">wxEXPAND</property> | ||
| 563 | <property name="proportion">0</property> | ||
| 564 | <object class="wxBoxSizer" expanded="1"> | ||
| 565 | <property name="minimum_size"></property> | ||
| 566 | <property name="name">bSizer3</property> | ||
| 567 | <property name="orient">wxHORIZONTAL</property> | ||
| 568 | <property name="permission">none</property> | ||
| 569 | <object class="sizeritem" expanded="1"> | ||
| 570 | <property name="border">5</property> | ||
| 571 | <property name="flag">wxEXPAND|wxALIGN_BOTTOM|wxALL</property> | ||
| 572 | <property name="proportion">1</property> | ||
| 573 | <object class="wxPanel" expanded="1"> | ||
| 574 | <property name="bg"></property> | ||
| 575 | <property name="context_help"></property> | ||
| 576 | <property name="enabled">1</property> | ||
| 577 | <property name="fg"></property> | ||
| 578 | <property name="font"></property> | ||
| 579 | <property name="hidden">0</property> | ||
| 580 | <property name="id">wxID_ANY</property> | ||
| 581 | <property name="maximum_size"></property> | ||
| 582 | <property name="minimum_size"></property> | ||
| 583 | <property name="name">m_panel14</property> | ||
| 584 | <property name="permission">protected</property> | ||
| 585 | <property name="pos"></property> | ||
| 586 | <property name="size"></property> | ||
| 587 | <property name="subclass"></property> | ||
| 588 | <property name="tooltip"></property> | ||
| 589 | <property name="window_extra_style"></property> | ||
| 590 | <property name="window_name"></property> | ||
| 591 | <property name="window_style">wxTAB_TRAVERSAL</property> | ||
| 592 | <event name="OnChar"></event> | ||
| 593 | <event name="OnEnterWindow"></event> | ||
| 594 | <event name="OnEraseBackground"></event> | ||
| 595 | <event name="OnKeyDown"></event> | ||
| 596 | <event name="OnKeyUp"></event> | ||
| 597 | <event name="OnKillFocus"></event> | ||
| 598 | <event name="OnLeaveWindow"></event> | ||
| 599 | <event name="OnLeftDClick"></event> | ||
| 600 | <event name="OnLeftDown"></event> | ||
| 601 | <event name="OnLeftUp"></event> | ||
| 602 | <event name="OnMiddleDClick"></event> | ||
| 603 | <event name="OnMiddleDown"></event> | ||
| 604 | <event name="OnMiddleUp"></event> | ||
| 605 | <event name="OnMotion"></event> | ||
| 606 | <event name="OnMouseEvents"></event> | ||
| 607 | <event name="OnMouseWheel"></event> | ||
| 608 | <event name="OnPaint"></event> | ||
| 609 | <event name="OnRightDClick"></event> | ||
| 610 | <event name="OnRightDown"></event> | ||
| 611 | <event name="OnRightUp"></event> | ||
| 612 | <event name="OnSetFocus"></event> | ||
| 613 | <event name="OnSize"></event> | ||
| 614 | <event name="OnUpdateUI"></event> | ||
| 615 | <object class="wxBoxSizer" expanded="1"> | ||
| 616 | <property name="minimum_size"></property> | ||
| 617 | <property name="name">bSizer66</property> | ||
| 618 | <property name="orient">wxHORIZONTAL</property> | ||
| 619 | <property name="permission">none</property> | ||
| 620 | <object class="sizeritem" expanded="1"> | ||
| 621 | <property name="border">5</property> | ||
| 622 | <property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT</property> | ||
| 623 | <property name="proportion">0</property> | ||
| 624 | <object class="wxStaticText" expanded="1"> | ||
| 625 | <property name="bg"></property> | ||
| 626 | <property name="context_help"></property> | ||
| 627 | <property name="enabled">1</property> | ||
| 628 | <property name="fg"></property> | ||
| 629 | <property name="font"></property> | ||
| 630 | <property name="hidden">0</property> | ||
| 631 | <property name="id">wxID_ANY</property> | ||
| 632 | <property name="label">Balance:</property> | ||
| 633 | <property name="maximum_size"></property> | ||
| 634 | <property name="minimum_size"></property> | ||
| 635 | <property name="name">m_staticText41</property> | ||
| 636 | <property name="permission">protected</property> | ||
| 637 | <property name="pos"></property> | ||
| 638 | <property name="size">-1,15</property> | ||
| 639 | <property name="style"></property> | ||
| 640 | <property name="subclass"></property> | ||
| 641 | <property name="tooltip"></property> | ||
| 642 | <property name="window_extra_style"></property> | ||
| 643 | <property name="window_name"></property> | ||
| 644 | <property name="window_style"></property> | ||
| 645 | <property name="wrap">-1</property> | ||
| 646 | <event name="OnChar"></event> | ||
| 647 | <event name="OnEnterWindow"></event> | ||
| 648 | <event name="OnEraseBackground"></event> | ||
| 649 | <event name="OnKeyDown"></event> | ||
| 650 | <event name="OnKeyUp"></event> | ||
| 651 | <event name="OnKillFocus"></event> | ||
| 652 | <event name="OnLeaveWindow"></event> | ||
| 653 | <event name="OnLeftDClick"></event> | ||
| 654 | <event name="OnLeftDown"></event> | ||
| 655 | <event name="OnLeftUp"></event> | ||
| 656 | <event name="OnMiddleDClick"></event> | ||
| 657 | <event name="OnMiddleDown"></event> | ||
| 658 | <event name="OnMiddleUp"></event> | ||
| 659 | <event name="OnMotion"></event> | ||
| 660 | <event name="OnMouseEvents"></event> | ||
| 661 | <event name="OnMouseWheel"></event> | ||
| 662 | <event name="OnPaint"></event> | ||
| 663 | <event name="OnRightDClick"></event> | ||
| 664 | <event name="OnRightDown"></event> | ||
| 665 | <event name="OnRightUp"></event> | ||
| 666 | <event name="OnSetFocus"></event> | ||
| 667 | <event name="OnSize"></event> | ||
| 668 | <event name="OnUpdateUI"></event> | ||
| 669 | </object> | ||
| 670 | </object> | ||
| 671 | <object class="sizeritem" expanded="1"> | ||
| 672 | <property name="border">5</property> | ||
| 673 | <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property> | ||
| 674 | <property name="proportion">0</property> | ||
| 675 | <object class="wxStaticText" expanded="1"> | ||
| 676 | <property name="bg">240,240,240</property> | ||
| 677 | <property name="context_help"></property> | ||
| 678 | <property name="enabled">1</property> | ||
| 679 | <property name="fg"></property> | ||
| 680 | <property name="font">,90,90,8,70,0</property> | ||
| 681 | <property name="hidden">0</property> | ||
| 682 | <property name="id">wxID_ANY</property> | ||
| 683 | <property name="label"></property> | ||
| 684 | <property name="maximum_size"></property> | ||
| 685 | <property name="minimum_size"></property> | ||
| 686 | <property name="name">m_staticTextBalance</property> | ||
| 687 | <property name="permission">protected</property> | ||
| 688 | <property name="pos"></property> | ||
| 689 | <property name="size">120,15</property> | ||
| 690 | <property name="style">wxALIGN_RIGHT|wxST_NO_AUTORESIZE</property> | ||
| 691 | <property name="subclass"></property> | ||
| 692 | <property name="tooltip"></property> | ||
| 693 | <property name="window_extra_style"></property> | ||
| 694 | <property name="window_name"></property> | ||
| 695 | <property name="window_style"></property> | ||
| 696 | <property name="wrap">-1</property> | ||
| 697 | <event name="OnChar"></event> | ||
| 698 | <event name="OnEnterWindow"></event> | ||
| 699 | <event name="OnEraseBackground"></event> | ||
| 700 | <event name="OnKeyDown"></event> | ||
| 701 | <event name="OnKeyUp"></event> | ||
| 702 | <event name="OnKillFocus"></event> | ||
| 703 | <event name="OnLeaveWindow"></event> | ||
| 704 | <event name="OnLeftDClick"></event> | ||
| 705 | <event name="OnLeftDown"></event> | ||
| 706 | <event name="OnLeftUp"></event> | ||
| 707 | <event name="OnMiddleDClick"></event> | ||
| 708 | <event name="OnMiddleDown"></event> | ||
| 709 | <event name="OnMiddleUp"></event> | ||
| 710 | <event name="OnMotion"></event> | ||
| 711 | <event name="OnMouseEvents"></event> | ||
| 712 | <event name="OnMouseWheel"></event> | ||
| 713 | <event name="OnPaint"></event> | ||
| 714 | <event name="OnRightDClick"></event> | ||
| 715 | <event name="OnRightDown"></event> | ||
| 716 | <event name="OnRightUp"></event> | ||
| 717 | <event name="OnSetFocus"></event> | ||
| 718 | <event name="OnSize"></event> | ||
| 719 | <event name="OnUpdateUI"></event> | ||
| 720 | </object> | ||
| 721 | </object> | ||
| 722 | </object> | ||
| 723 | </object> | ||
| 724 | </object> | ||
| 725 | <object class="sizeritem" expanded="1"> | ||
| 726 | <property name="border">5</property> | ||
| 727 | <property name="flag">wxEXPAND</property> | ||
| 728 | <property name="proportion">0</property> | ||
| 729 | <object class="spacer" expanded="1"> | ||
| 730 | <property name="height">0</property> | ||
| 731 | <property name="permission">protected</property> | ||
| 732 | <property name="width">0</property> | ||
| 733 | </object> | ||
| 734 | </object> | ||
| 735 | <object class="sizeritem" expanded="1"> | ||
| 736 | <property name="border">5</property> | ||
| 737 | <property name="flag">wxALIGN_BOTTOM|wxTOP|wxRIGHT|wxLEFT</property> | ||
| 738 | <property name="proportion">0</property> | ||
| 739 | <object class="wxChoice" expanded="1"> | ||
| 740 | <property name="bg"></property> | ||
| 741 | <property name="choices">" All" " Sent" " Received" " In Progress"</property> | ||
| 742 | <property name="context_help"></property> | ||
| 743 | <property name="enabled">1</property> | ||
| 744 | <property name="fg"></property> | ||
| 745 | <property name="font"></property> | ||
| 746 | <property name="hidden">1</property> | ||
| 747 | <property name="id">wxID_ANY</property> | ||
| 748 | <property name="maximum_size"></property> | ||
| 749 | <property name="minimum_size"></property> | ||
| 750 | <property name="name">m_choiceFilter</property> | ||
| 751 | <property name="permission">protected</property> | ||
| 752 | <property name="pos"></property> | ||
| 753 | <property name="selection">0</property> | ||
| 754 | <property name="size">110,-1</property> | ||
| 755 | <property name="subclass"></property> | ||
| 756 | <property name="tooltip"></property> | ||
| 757 | <property name="window_extra_style"></property> | ||
| 758 | <property name="window_name"></property> | ||
| 759 | <property name="window_style"></property> | ||
| 760 | <event name="OnChar"></event> | ||
| 761 | <event name="OnChoice"></event> | ||
| 762 | <event name="OnEnterWindow"></event> | ||
| 763 | <event name="OnEraseBackground"></event> | ||
| 764 | <event name="OnKeyDown"></event> | ||
| 765 | <event name="OnKeyUp"></event> | ||
| 766 | <event name="OnKillFocus"></event> | ||
| 767 | <event name="OnLeaveWindow"></event> | ||
| 768 | <event name="OnLeftDClick"></event> | ||
| 769 | <event name="OnLeftDown"></event> | ||
| 770 | <event name="OnLeftUp"></event> | ||
| 771 | <event name="OnMiddleDClick"></event> | ||
| 772 | <event name="OnMiddleDown"></event> | ||
| 773 | <event name="OnMiddleUp"></event> | ||
| 774 | <event name="OnMotion"></event> | ||
| 775 | <event name="OnMouseEvents"></event> | ||
| 776 | <event name="OnMouseWheel"></event> | ||
| 777 | <event name="OnPaint"></event> | ||
| 778 | <event name="OnRightDClick"></event> | ||
| 779 | <event name="OnRightDown"></event> | ||
| 780 | <event name="OnRightUp"></event> | ||
| 781 | <event name="OnSetFocus"></event> | ||
| 782 | <event name="OnSize"></event> | ||
| 783 | <event name="OnUpdateUI"></event> | ||
| 784 | </object> | ||
| 785 | </object> | ||
| 786 | </object> | ||
| 787 | </object> | ||
| 788 | <object class="sizeritem" expanded="1"> | ||
| 789 | <property name="border">5</property> | ||
| 790 | <property name="flag">wxEXPAND</property> | ||
| 791 | <property name="proportion">1</property> | ||
| 792 | <object class="wxNotebook" expanded="1"> | ||
| 793 | <property name="bg"></property> | ||
| 794 | <property name="bitmapsize"></property> | ||
| 795 | <property name="context_help"></property> | ||
| 796 | <property name="enabled">1</property> | ||
| 797 | <property name="fg"></property> | ||
| 798 | <property name="font"></property> | ||
| 799 | <property name="hidden">0</property> | ||
| 800 | <property name="id">wxID_ANY</property> | ||
| 801 | <property name="maximum_size"></property> | ||
| 802 | <property name="minimum_size"></property> | ||
| 803 | <property name="name">m_notebook</property> | ||
| 804 | <property name="permission">protected</property> | ||
| 805 | <property name="pos"></property> | ||
| 806 | <property name="size"></property> | ||
| 807 | <property name="style"></property> | ||
| 808 | <property name="subclass"></property> | ||
| 809 | <property name="tooltip"></property> | ||
| 810 | <property name="window_extra_style"></property> | ||
| 811 | <property name="window_name"></property> | ||
| 812 | <property name="window_style"></property> | ||
| 813 | <event name="OnChar"></event> | ||
| 814 | <event name="OnEnterWindow"></event> | ||
| 815 | <event name="OnEraseBackground"></event> | ||
| 816 | <event name="OnKeyDown"></event> | ||
| 817 | <event name="OnKeyUp"></event> | ||
| 818 | <event name="OnKillFocus"></event> | ||
| 819 | <event name="OnLeaveWindow"></event> | ||
| 820 | <event name="OnLeftDClick"></event> | ||
| 821 | <event name="OnLeftDown"></event> | ||
| 822 | <event name="OnLeftUp"></event> | ||
| 823 | <event name="OnMiddleDClick"></event> | ||
| 824 | <event name="OnMiddleDown"></event> | ||
| 825 | <event name="OnMiddleUp"></event> | ||
| 826 | <event name="OnMotion"></event> | ||
| 827 | <event name="OnMouseEvents"></event> | ||
| 828 | <event name="OnMouseWheel"></event> | ||
| 829 | <event name="OnNotebookPageChanged"></event> | ||
| 830 | <event name="OnNotebookPageChanging"></event> | ||
| 831 | <event name="OnPaint"></event> | ||
| 832 | <event name="OnRightDClick"></event> | ||
| 833 | <event name="OnRightDown"></event> | ||
| 834 | <event name="OnRightUp"></event> | ||
| 835 | <event name="OnSetFocus"></event> | ||
| 836 | <event name="OnSize"></event> | ||
| 837 | <event name="OnUpdateUI"></event> | ||
| 838 | <object class="notebookpage" expanded="1"> | ||
| 839 | <property name="bitmap"></property> | ||
| 840 | <property name="label">All Transactions</property> | ||
| 841 | <property name="select">0</property> | ||
| 842 | <object class="wxPanel" expanded="1"> | ||
| 843 | <property name="bg"></property> | ||
| 844 | <property name="context_help"></property> | ||
| 845 | <property name="enabled">1</property> | ||
| 846 | <property name="fg"></property> | ||
| 847 | <property name="font"></property> | ||
| 848 | <property name="hidden">0</property> | ||
| 849 | <property name="id">wxID_ANY</property> | ||
| 850 | <property name="maximum_size"></property> | ||
| 851 | <property name="minimum_size"></property> | ||
| 852 | <property name="name">m_panel7</property> | ||
| 853 | <property name="permission">protected</property> | ||
| 854 | <property name="pos"></property> | ||
| 855 | <property name="size"></property> | ||
| 856 | <property name="subclass"></property> | ||
| 857 | <property name="tooltip"></property> | ||
| 858 | <property name="window_extra_style"></property> | ||
| 859 | <property name="window_name"></property> | ||
| 860 | <property name="window_style">wxTAB_TRAVERSAL</property> | ||
| 861 | <event name="OnChar"></event> | ||
| 862 | <event name="OnEnterWindow"></event> | ||
| 863 | <event name="OnEraseBackground"></event> | ||
| 864 | <event name="OnKeyDown"></event> | ||
| 865 | <event name="OnKeyUp"></event> | ||
| 866 | <event name="OnKillFocus"></event> | ||
| 867 | <event name="OnLeaveWindow"></event> | ||
| 868 | <event name="OnLeftDClick"></event> | ||
| 869 | <event name="OnLeftDown"></event> | ||
| 870 | <event name="OnLeftUp"></event> | ||
| 871 | <event name="OnMiddleDClick"></event> | ||
| 872 | <event name="OnMiddleDown"></event> | ||
| 873 | <event name="OnMiddleUp"></event> | ||
| 874 | <event name="OnMotion"></event> | ||
| 875 | <event name="OnMouseEvents"></event> | ||
| 876 | <event name="OnMouseWheel"></event> | ||
| 877 | <event name="OnPaint"></event> | ||
| 878 | <event name="OnRightDClick"></event> | ||
| 879 | <event name="OnRightDown"></event> | ||
| 880 | <event name="OnRightUp"></event> | ||
| 881 | <event name="OnSetFocus"></event> | ||
| 882 | <event name="OnSize"></event> | ||
| 883 | <event name="OnUpdateUI"></event> | ||
| 884 | <object class="wxBoxSizer" expanded="1"> | ||
| 885 | <property name="minimum_size"></property> | ||
| 886 | <property name="name">bSizer157</property> | ||
| 887 | <property name="orient">wxVERTICAL</property> | ||
| 888 | <property name="permission">none</property> | ||
| 889 | <object class="sizeritem" expanded="1"> | ||
| 890 | <property name="border">5</property> | ||
| 891 | <property name="flag">wxEXPAND|wxALL</property> | ||
| 892 | <property name="proportion">1</property> | ||
| 893 | <object class="wxListCtrl" expanded="1"> | ||
| 894 | <property name="bg"></property> | ||
| 895 | <property name="context_help"></property> | ||
| 896 | <property name="enabled">1</property> | ||
| 897 | <property name="fg"></property> | ||
| 898 | <property name="font"></property> | ||
| 899 | <property name="hidden">0</property> | ||
| 900 | <property name="id">wxID_ANY</property> | ||
| 901 | <property name="maximum_size"></property> | ||
| 902 | <property name="minimum_size"></property> | ||
| 903 | <property name="name">m_listCtrl</property> | ||
| 904 | <property name="permission">public</property> | ||
| 905 | <property name="pos"></property> | ||
| 906 | <property name="size"></property> | ||
| 907 | <property name="style">wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING</property> | ||
| 908 | <property name="subclass"></property> | ||
| 909 | <property name="tooltip"></property> | ||
| 910 | <property name="window_extra_style"></property> | ||
| 911 | <property name="window_name"></property> | ||
| 912 | <property name="window_style">wxALWAYS_SHOW_SB</property> | ||
| 913 | <event name="OnChar"></event> | ||
| 914 | <event name="OnEnterWindow"></event> | ||
| 915 | <event name="OnEraseBackground"></event> | ||
| 916 | <event name="OnKeyDown"></event> | ||
| 917 | <event name="OnKeyUp"></event> | ||
| 918 | <event name="OnKillFocus"></event> | ||
| 919 | <event name="OnLeaveWindow"></event> | ||
| 920 | <event name="OnLeftDClick"></event> | ||
| 921 | <event name="OnLeftDown"></event> | ||
| 922 | <event name="OnLeftUp"></event> | ||
| 923 | <event name="OnListBeginDrag"></event> | ||
| 924 | <event name="OnListBeginLabelEdit"></event> | ||
| 925 | <event name="OnListBeginRDrag"></event> | ||
| 926 | <event name="OnListCacheHint"></event> | ||
| 927 | <event name="OnListColBeginDrag">OnListColBeginDrag</event> | ||
| 928 | <event name="OnListColClick"></event> | ||
| 929 | <event name="OnListColDragging"></event> | ||
| 930 | <event name="OnListColEndDrag"></event> | ||
| 931 | <event name="OnListColRightClick"></event> | ||
| 932 | <event name="OnListDeleteAllItems"></event> | ||
| 933 | <event name="OnListDeleteItem"></event> | ||
| 934 | <event name="OnListEndLabelEdit"></event> | ||
| 935 | <event name="OnListInsertItem"></event> | ||
| 936 | <event name="OnListItemActivated">OnListItemActivatedAllTransactions</event> | ||
| 937 | <event name="OnListItemDeselected"></event> | ||
| 938 | <event name="OnListItemFocused"></event> | ||
| 939 | <event name="OnListItemMiddleClick"></event> | ||
| 940 | <event name="OnListItemRightClick"></event> | ||
| 941 | <event name="OnListItemSelected"></event> | ||
| 942 | <event name="OnListKeyDown"></event> | ||
| 943 | <event name="OnMiddleDClick"></event> | ||
| 944 | <event name="OnMiddleDown"></event> | ||
| 945 | <event name="OnMiddleUp"></event> | ||
| 946 | <event name="OnMotion"></event> | ||
| 947 | <event name="OnMouseEvents"></event> | ||
| 948 | <event name="OnMouseWheel"></event> | ||
| 949 | <event name="OnPaint">OnPaintListCtrl</event> | ||
| 950 | <event name="OnRightDClick"></event> | ||
| 951 | <event name="OnRightDown"></event> | ||
| 952 | <event name="OnRightUp"></event> | ||
| 953 | <event name="OnSetFocus"></event> | ||
| 954 | <event name="OnSize"></event> | ||
| 955 | <event name="OnUpdateUI"></event> | ||
| 956 | </object> | ||
| 957 | </object> | ||
| 958 | </object> | ||
| 959 | </object> | ||
| 960 | </object> | ||
| 961 | </object> | ||
| 962 | </object> | ||
| 963 | <object class="sizeritem" expanded="1"> | ||
| 964 | <property name="border">5</property> | ||
| 965 | <property name="flag">wxEXPAND</property> | ||
| 966 | <property name="proportion">1</property> | ||
| 967 | <object class="wxBoxSizer" expanded="1"> | ||
| 968 | <property name="minimum_size"></property> | ||
| 969 | <property name="name">bSizer_TabsForFutureUse</property> | ||
| 970 | <property name="orient">wxVERTICAL</property> | ||
| 971 | <property name="permission">none</property> | ||
| 972 | <object class="sizeritem" expanded="1"> | ||
| 973 | <property name="border">5</property> | ||
| 974 | <property name="flag">wxEXPAND | wxALL</property> | ||
| 975 | <property name="proportion">1</property> | ||
| 976 | <object class="wxPanel" expanded="1"> | ||
| 977 | <property name="bg"></property> | ||
| 978 | <property name="context_help"></property> | ||
| 979 | <property name="enabled">1</property> | ||
| 980 | <property name="fg"></property> | ||
| 981 | <property name="font"></property> | ||
| 982 | <property name="hidden">1</property> | ||
| 983 | <property name="id">wxID_ANY</property> | ||
| 984 | <property name="maximum_size"></property> | ||
| 985 | <property name="minimum_size"></property> | ||
| 986 | <property name="name">m_panel9</property> | ||
| 987 | <property name="permission">protected</property> | ||
| 988 | <property name="pos"></property> | ||
| 989 | <property name="size"></property> | ||
| 990 | <property name="subclass"></property> | ||
| 991 | <property name="tooltip"></property> | ||
| 992 | <property name="window_extra_style"></property> | ||
| 993 | <property name="window_name"></property> | ||
| 994 | <property name="window_style">wxTAB_TRAVERSAL</property> | ||
| 995 | <event name="OnChar"></event> | ||
| 996 | <event name="OnEnterWindow"></event> | ||
| 997 | <event name="OnEraseBackground"></event> | ||
| 998 | <event name="OnKeyDown"></event> | ||
| 999 | <event name="OnKeyUp"></event> | ||
| 1000 | <event name="OnKillFocus"></event> | ||
| 1001 | <event name="OnLeaveWindow"></event> | ||
| 1002 | <event name="OnLeftDClick"></event> | ||
| 1003 | <event name="OnLeftDown"></event> | ||
| 1004 | <event name="OnLeftUp"></event> | ||
| 1005 | <event name="OnMiddleDClick"></event> | ||
| 1006 | <event name="OnMiddleDown"></event> | ||
| 1007 | <event name="OnMiddleUp"></event> | ||
| 1008 | <event name="OnMotion"></event> | ||
| 1009 | <event name="OnMouseEvents"></event> | ||
| 1010 | <event name="OnMouseWheel"></event> | ||
| 1011 | <event name="OnPaint"></event> | ||
| 1012 | <event name="OnRightDClick"></event> | ||
| 1013 | <event name="OnRightDown"></event> | ||
| 1014 | <event name="OnRightUp"></event> | ||
| 1015 | <event name="OnSetFocus"></event> | ||
| 1016 | <event name="OnSize"></event> | ||
| 1017 | <event name="OnUpdateUI"></event> | ||
| 1018 | <object class="wxBoxSizer" expanded="1"> | ||
| 1019 | <property name="minimum_size"></property> | ||
| 1020 | <property name="name">bSizer159</property> | ||
| 1021 | <property name="orient">wxVERTICAL</property> | ||
| 1022 | <property name="permission">none</property> | ||
| 1023 | <object class="sizeritem" expanded="1"> | ||
| 1024 | <property name="border">5</property> | ||
| 1025 | <property name="flag">wxALL|wxEXPAND</property> | ||
| 1026 | <property name="proportion">1</property> | ||
| 1027 | <object class="wxListCtrl" expanded="1"> | ||
| 1028 | <property name="bg"></property> | ||
| 1029 | <property name="context_help"></property> | ||
| 1030 | <property name="enabled">1</property> | ||
| 1031 | <property name="fg"></property> | ||
| 1032 | <property name="font"></property> | ||
| 1033 | <property name="hidden">0</property> | ||
| 1034 | <property name="id">wxID_ANY</property> | ||
| 1035 | <property name="maximum_size"></property> | ||
| 1036 | <property name="minimum_size"></property> | ||
| 1037 | <property name="name">m_listCtrlEscrows</property> | ||
| 1038 | <property name="permission">public</property> | ||
| 1039 | <property name="pos"></property> | ||
| 1040 | <property name="size"></property> | ||
| 1041 | <property name="style">wxLC_NO_SORT_HEADER|wxLC_REPORT</property> | ||
| 1042 | <property name="subclass"></property> | ||
| 1043 | <property name="tooltip"></property> | ||
| 1044 | <property name="window_extra_style"></property> | ||
| 1045 | <property name="window_name"></property> | ||
| 1046 | <property name="window_style"></property> | ||
| 1047 | <event name="OnChar"></event> | ||
| 1048 | <event name="OnEnterWindow"></event> | ||
| 1049 | <event name="OnEraseBackground"></event> | ||
| 1050 | <event name="OnKeyDown"></event> | ||
| 1051 | <event name="OnKeyUp"></event> | ||
| 1052 | <event name="OnKillFocus"></event> | ||
| 1053 | <event name="OnLeaveWindow"></event> | ||
| 1054 | <event name="OnLeftDClick"></event> | ||
| 1055 | <event name="OnLeftDown"></event> | ||
| 1056 | <event name="OnLeftUp"></event> | ||
| 1057 | <event name="OnListBeginDrag"></event> | ||
| 1058 | <event name="OnListBeginLabelEdit"></event> | ||
| 1059 | <event name="OnListBeginRDrag"></event> | ||
| 1060 | <event name="OnListCacheHint"></event> | ||
| 1061 | <event name="OnListColBeginDrag"></event> | ||
| 1062 | <event name="OnListColClick"></event> | ||
| 1063 | <event name="OnListColDragging"></event> | ||
| 1064 | <event name="OnListColEndDrag"></event> | ||
| 1065 | <event name="OnListColRightClick"></event> | ||
| 1066 | <event name="OnListDeleteAllItems"></event> | ||
| 1067 | <event name="OnListDeleteItem"></event> | ||
| 1068 | <event name="OnListEndLabelEdit"></event> | ||
| 1069 | <event name="OnListInsertItem"></event> | ||
| 1070 | <event name="OnListItemActivated"></event> | ||
| 1071 | <event name="OnListItemDeselected"></event> | ||
| 1072 | <event name="OnListItemFocused"></event> | ||
| 1073 | <event name="OnListItemMiddleClick"></event> | ||
| 1074 | <event name="OnListItemRightClick"></event> | ||
| 1075 | <event name="OnListItemSelected"></event> | ||
| 1076 | <event name="OnListKeyDown"></event> | ||
| 1077 | <event name="OnMiddleDClick"></event> | ||
| 1078 | <event name="OnMiddleDown"></event> | ||
| 1079 | <event name="OnMiddleUp"></event> | ||
| 1080 | <event name="OnMotion"></event> | ||
| 1081 | <event name="OnMouseEvents"></event> | ||
| 1082 | <event name="OnMouseWheel"></event> | ||
| 1083 | <event name="OnPaint"></event> | ||
| 1084 | <event name="OnRightDClick"></event> | ||
| 1085 | <event name="OnRightDown"></event> | ||
| 1086 | <event name="OnRightUp"></event> | ||
| 1087 | <event name="OnSetFocus"></event> | ||
| 1088 | <event name="OnSize"></event> | ||
| 1089 | <event name="OnUpdateUI"></event> | ||
| 1090 | </object> | ||
| 1091 | </object> | ||
| 1092 | </object> | ||
| 1093 | </object> | ||
| 1094 | </object> | ||
| 1095 | <object class="sizeritem" expanded="1"> | ||
| 1096 | <property name="border">5</property> | ||
| 1097 | <property name="flag">wxEXPAND | wxALL</property> | ||
| 1098 | <property name="proportion">1</property> | ||
| 1099 | <object class="wxPanel" expanded="1"> | ||
| 1100 | <property name="bg"></property> | ||
| 1101 | <property name="context_help"></property> | ||
| 1102 | <property name="enabled">1</property> | ||
| 1103 | <property name="fg"></property> | ||
| 1104 | <property name="font"></property> | ||
| 1105 | <property name="hidden">1</property> | ||
| 1106 | <property name="id">wxID_ANY</property> | ||
| 1107 | <property name="maximum_size"></property> | ||
| 1108 | <property name="minimum_size"></property> | ||
| 1109 | <property name="name">m_panel8</property> | ||
| 1110 | <property name="permission">protected</property> | ||
| 1111 | <property name="pos"></property> | ||
| 1112 | <property name="size"></property> | ||
| 1113 | <property name="subclass"></property> | ||
| 1114 | <property name="tooltip"></property> | ||
| 1115 | <property name="window_extra_style"></property> | ||
| 1116 | <property name="window_name"></property> | ||
| 1117 | <property name="window_style">wxTAB_TRAVERSAL</property> | ||
| 1118 | <event name="OnChar"></event> | ||
| 1119 | <event name="OnEnterWindow"></event> | ||
| 1120 | <event name="OnEraseBackground"></event> | ||
| 1121 | <event name="OnKeyDown"></event> | ||
| 1122 | <event name="OnKeyUp"></event> | ||
| 1123 | <event name="OnKillFocus"></event> | ||
| 1124 | <event name="OnLeaveWindow"></event> | ||
| 1125 | <event name="OnLeftDClick"></event> | ||
| 1126 | <event name="OnLeftDown"></event> | ||
| 1127 | <event name="OnLeftUp"></event> | ||
| 1128 | <event name="OnMiddleDClick"></event> | ||
| 1129 | <event name="OnMiddleDown"></event> | ||
| 1130 | <event name="OnMiddleUp"></event> | ||
| 1131 | <event name="OnMotion"></event> | ||
| 1132 | <event name="OnMouseEvents"></event> | ||
| 1133 | <event name="OnMouseWheel"></event> | ||
| 1134 | <event name="OnPaint"></event> | ||
| 1135 | <event name="OnRightDClick"></event> | ||
| 1136 | <event name="OnRightDown"></event> | ||
| 1137 | <event name="OnRightUp"></event> | ||
| 1138 | <event name="OnSetFocus"></event> | ||
| 1139 | <event name="OnSize"></event> | ||
| 1140 | <event name="OnUpdateUI"></event> | ||
| 1141 | <object class="wxBoxSizer" expanded="1"> | ||
| 1142 | <property name="minimum_size"></property> | ||
| 1143 | <property name="name">bSizer158</property> | ||
| 1144 | <property name="orient">wxVERTICAL</property> | ||
| 1145 | <property name="permission">none</property> | ||
| 1146 | <object class="sizeritem" expanded="1"> | ||
| 1147 | <property name="border">5</property> | ||
| 1148 | <property name="flag">wxALL|wxEXPAND</property> | ||
| 1149 | <property name="proportion">1</property> | ||
| 1150 | <object class="wxListCtrl" expanded="1"> | ||
| 1151 | <property name="bg"></property> | ||
| 1152 | <property name="context_help"></property> | ||
| 1153 | <property name="enabled">1</property> | ||
| 1154 | <property name="fg"></property> | ||
| 1155 | <property name="font"></property> | ||
| 1156 | <property name="hidden">0</property> | ||
| 1157 | <property name="id">wxID_ANY</property> | ||
| 1158 | <property name="maximum_size"></property> | ||
| 1159 | <property name="minimum_size"></property> | ||
| 1160 | <property name="name">m_listCtrlOrdersSent</property> | ||
| 1161 | <property name="permission">public</property> | ||
| 1162 | <property name="pos"></property> | ||
| 1163 | <property name="size"></property> | ||
| 1164 | <property name="style">wxLC_NO_SORT_HEADER|wxLC_REPORT</property> | ||
| 1165 | <property name="subclass"></property> | ||
| 1166 | <property name="tooltip"></property> | ||
| 1167 | <property name="window_extra_style"></property> | ||
| 1168 | <property name="window_name"></property> | ||
| 1169 | <property name="window_style"></property> | ||
| 1170 | <event name="OnChar"></event> | ||
| 1171 | <event name="OnEnterWindow"></event> | ||
| 1172 | <event name="OnEraseBackground"></event> | ||
| 1173 | <event name="OnKeyDown"></event> | ||
| 1174 | <event name="OnKeyUp"></event> | ||
| 1175 | <event name="OnKillFocus"></event> | ||
| 1176 | <event name="OnLeaveWindow"></event> | ||
| 1177 | <event name="OnLeftDClick"></event> | ||
| 1178 | <event name="OnLeftDown"></event> | ||
| 1179 | <event name="OnLeftUp"></event> | ||
| 1180 | <event name="OnListBeginDrag"></event> | ||
| 1181 | <event name="OnListBeginLabelEdit"></event> | ||
| 1182 | <event name="OnListBeginRDrag"></event> | ||
| 1183 | <event name="OnListCacheHint"></event> | ||
| 1184 | <event name="OnListColBeginDrag"></event> | ||
| 1185 | <event name="OnListColClick"></event> | ||
| 1186 | <event name="OnListColDragging"></event> | ||
| 1187 | <event name="OnListColEndDrag"></event> | ||
| 1188 | <event name="OnListColRightClick"></event> | ||
| 1189 | <event name="OnListDeleteAllItems"></event> | ||
| 1190 | <event name="OnListDeleteItem"></event> | ||
| 1191 | <event name="OnListEndLabelEdit"></event> | ||
| 1192 | <event name="OnListInsertItem"></event> | ||
| 1193 | <event name="OnListItemActivated">OnListItemActivatedOrdersSent</event> | ||
| 1194 | <event name="OnListItemDeselected"></event> | ||
| 1195 | <event name="OnListItemFocused"></event> | ||
| 1196 | <event name="OnListItemMiddleClick"></event> | ||
| 1197 | <event name="OnListItemRightClick"></event> | ||
| 1198 | <event name="OnListItemSelected"></event> | ||
| 1199 | <event name="OnListKeyDown"></event> | ||
| 1200 | <event name="OnMiddleDClick"></event> | ||
| 1201 | <event name="OnMiddleDown"></event> | ||
| 1202 | <event name="OnMiddleUp"></event> | ||
| 1203 | <event name="OnMotion"></event> | ||
| 1204 | <event name="OnMouseEvents"></event> | ||
| 1205 | <event name="OnMouseWheel"></event> | ||
| 1206 | <event name="OnPaint"></event> | ||
| 1207 | <event name="OnRightDClick"></event> | ||
| 1208 | <event name="OnRightDown"></event> | ||
| 1209 | <event name="OnRightUp"></event> | ||
| 1210 | <event name="OnSetFocus"></event> | ||
| 1211 | <event name="OnSize"></event> | ||
| 1212 | <event name="OnUpdateUI"></event> | ||
| 1213 | </object> | ||
| 1214 | </object> | ||
| 1215 | </object> | ||
| 1216 | </object> | ||
| 1217 | </object> | ||
| 1218 | <object class="sizeritem" expanded="1"> | ||
| 1219 | <property name="border">5</property> | ||
| 1220 | <property name="flag">wxEXPAND | wxALL</property> | ||
| 1221 | <property name="proportion">1</property> | ||
| 1222 | <object class="wxPanel" expanded="1"> | ||
| 1223 | <property name="bg"></property> | ||
| 1224 | <property name="context_help"></property> | ||
| 1225 | <property name="enabled">1</property> | ||
| 1226 | <property name="fg"></property> | ||
| 1227 | <property name="font"></property> | ||
| 1228 | <property name="hidden">1</property> | ||
| 1229 | <property name="id">wxID_ANY</property> | ||
| 1230 | <property name="maximum_size"></property> | ||
| 1231 | <property name="minimum_size"></property> | ||
| 1232 | <property name="name">m_panel10</property> | ||
| 1233 | <property name="permission">protected</property> | ||
| 1234 | <property name="pos"></property> | ||
| 1235 | <property name="size"></property> | ||
| 1236 | <property name="subclass"></property> | ||
| 1237 | <property name="tooltip"></property> | ||
| 1238 | <property name="window_extra_style"></property> | ||
| 1239 | <property name="window_name"></property> | ||
| 1240 | <property name="window_style">wxTAB_TRAVERSAL</property> | ||
| 1241 | <event name="OnChar"></event> | ||
| 1242 | <event name="OnEnterWindow"></event> | ||
| 1243 | <event name="OnEraseBackground"></event> | ||
| 1244 | <event name="OnKeyDown"></event> | ||
| 1245 | <event name="OnKeyUp"></event> | ||
| 1246 | <event name="OnKillFocus"></event> | ||
| 1247 | <event name="OnLeaveWindow"></event> | ||
| 1248 | <event name="OnLeftDClick"></event> | ||
| 1249 | <event name="OnLeftDown"></event> | ||
| 1250 | <event name="OnLeftUp"></event> | ||
| 1251 | <event name="OnMiddleDClick"></event> | ||
| 1252 | <event name="OnMiddleDown"></event> | ||
| 1253 | <event name="OnMiddleUp"></event> | ||
| 1254 | <event name="OnMotion"></event> | ||
| 1255 | <event name="OnMouseEvents"></event> | ||
| 1256 | <event name="OnMouseWheel"></event> | ||
| 1257 | <event name="OnPaint"></event> | ||
| 1258 | <event name="OnRightDClick"></event> | ||
| 1259 | <event name="OnRightDown"></event> | ||
| 1260 | <event name="OnRightUp"></event> | ||
| 1261 | <event name="OnSetFocus"></event> | ||
| 1262 | <event name="OnSize"></event> | ||
| 1263 | <event name="OnUpdateUI"></event> | ||
| 1264 | <object class="wxBoxSizer" expanded="1"> | ||
| 1265 | <property name="minimum_size"></property> | ||
| 1266 | <property name="name">bSizer160</property> | ||
| 1267 | <property name="orient">wxVERTICAL</property> | ||
| 1268 | <property name="permission">none</property> | ||
| 1269 | <object class="sizeritem" expanded="1"> | ||
| 1270 | <property name="border">5</property> | ||
| 1271 | <property name="flag">wxALL|wxEXPAND</property> | ||
| 1272 | <property name="proportion">1</property> | ||
| 1273 | <object class="wxListCtrl" expanded="1"> | ||
| 1274 | <property name="bg"></property> | ||
| 1275 | <property name="context_help"></property> | ||
| 1276 | <property name="enabled">1</property> | ||
| 1277 | <property name="fg"></property> | ||
| 1278 | <property name="font"></property> | ||
| 1279 | <property name="hidden">0</property> | ||
| 1280 | <property name="id">wxID_ANY</property> | ||
| 1281 | <property name="maximum_size"></property> | ||
| 1282 | <property name="minimum_size"></property> | ||
| 1283 | <property name="name">m_listCtrlProductsSent</property> | ||
| 1284 | <property name="permission">public</property> | ||
| 1285 | <property name="pos"></property> | ||
| 1286 | <property name="size"></property> | ||
| 1287 | <property name="style">wxLC_NO_SORT_HEADER|wxLC_REPORT</property> | ||
| 1288 | <property name="subclass"></property> | ||
| 1289 | <property name="tooltip"></property> | ||
| 1290 | <property name="window_extra_style"></property> | ||
| 1291 | <property name="window_name"></property> | ||
| 1292 | <property name="window_style"></property> | ||
| 1293 | <event name="OnChar"></event> | ||
| 1294 | <event name="OnEnterWindow"></event> | ||
| 1295 | <event name="OnEraseBackground"></event> | ||
| 1296 | <event name="OnKeyDown"></event> | ||
| 1297 | <event name="OnKeyUp"></event> | ||
| 1298 | <event name="OnKillFocus"></event> | ||
| 1299 | <event name="OnLeaveWindow"></event> | ||
| 1300 | <event name="OnLeftDClick"></event> | ||
| 1301 | <event name="OnLeftDown"></event> | ||
| 1302 | <event name="OnLeftUp"></event> | ||
| 1303 | <event name="OnListBeginDrag"></event> | ||
| 1304 | <event name="OnListBeginLabelEdit"></event> | ||
| 1305 | <event name="OnListBeginRDrag"></event> | ||
| 1306 | <event name="OnListCacheHint"></event> | ||
| 1307 | <event name="OnListColBeginDrag"></event> | ||
| 1308 | <event name="OnListColClick"></event> | ||
| 1309 | <event name="OnListColDragging"></event> | ||
| 1310 | <event name="OnListColEndDrag"></event> | ||
| 1311 | <event name="OnListColRightClick"></event> | ||
| 1312 | <event name="OnListDeleteAllItems"></event> | ||
| 1313 | <event name="OnListDeleteItem"></event> | ||
| 1314 | <event name="OnListEndLabelEdit"></event> | ||
| 1315 | <event name="OnListInsertItem"></event> | ||
| 1316 | <event name="OnListItemActivated">OnListItemActivatedProductsSent</event> | ||
| 1317 | <event name="OnListItemDeselected"></event> | ||
| 1318 | <event name="OnListItemFocused"></event> | ||
| 1319 | <event name="OnListItemMiddleClick"></event> | ||
| 1320 | <event name="OnListItemRightClick"></event> | ||
| 1321 | <event name="OnListItemSelected"></event> | ||
| 1322 | <event name="OnListKeyDown"></event> | ||
| 1323 | <event name="OnMiddleDClick"></event> | ||
| 1324 | <event name="OnMiddleDown"></event> | ||
| 1325 | <event name="OnMiddleUp"></event> | ||
| 1326 | <event name="OnMotion"></event> | ||
| 1327 | <event name="OnMouseEvents"></event> | ||
| 1328 | <event name="OnMouseWheel"></event> | ||
| 1329 | <event name="OnPaint"></event> | ||
| 1330 | <event name="OnRightDClick"></event> | ||
| 1331 | <event name="OnRightDown"></event> | ||
| 1332 | <event name="OnRightUp"></event> | ||
| 1333 | <event name="OnSetFocus"></event> | ||
| 1334 | <event name="OnSize"></event> | ||
| 1335 | <event name="OnUpdateUI"></event> | ||
| 1336 | </object> | ||
| 1337 | </object> | ||
| 1338 | </object> | ||
| 1339 | </object> | ||
| 1340 | </object> | ||
| 1341 | <object class="sizeritem" expanded="1"> | ||
| 1342 | <property name="border">5</property> | ||
| 1343 | <property name="flag">wxEXPAND | wxALL</property> | ||
| 1344 | <property name="proportion">1</property> | ||
| 1345 | <object class="wxPanel" expanded="1"> | ||
| 1346 | <property name="bg"></property> | ||
| 1347 | <property name="context_help"></property> | ||
| 1348 | <property name="enabled">1</property> | ||
| 1349 | <property name="fg"></property> | ||
| 1350 | <property name="font"></property> | ||
| 1351 | <property name="hidden">1</property> | ||
| 1352 | <property name="id">wxID_ANY</property> | ||
| 1353 | <property name="maximum_size"></property> | ||
| 1354 | <property name="minimum_size"></property> | ||
| 1355 | <property name="name">m_panel11</property> | ||
| 1356 | <property name="permission">protected</property> | ||
| 1357 | <property name="pos"></property> | ||
| 1358 | <property name="size"></property> | ||
| 1359 | <property name="subclass"></property> | ||
| 1360 | <property name="tooltip"></property> | ||
| 1361 | <property name="window_extra_style"></property> | ||
| 1362 | <property name="window_name"></property> | ||
| 1363 | <property name="window_style">wxTAB_TRAVERSAL</property> | ||
| 1364 | <event name="OnChar"></event> | ||
| 1365 | <event name="OnEnterWindow"></event> | ||
| 1366 | <event name="OnEraseBackground"></event> | ||
| 1367 | <event name="OnKeyDown"></event> | ||
| 1368 | <event name="OnKeyUp"></event> | ||
| 1369 | <event name="OnKillFocus"></event> | ||
| 1370 | <event name="OnLeaveWindow"></event> | ||
| 1371 | <event name="OnLeftDClick"></event> | ||
| 1372 | <event name="OnLeftDown"></event> | ||
| 1373 | <event name="OnLeftUp"></event> | ||
| 1374 | <event name="OnMiddleDClick"></event> | ||
| 1375 | <event name="OnMiddleDown"></event> | ||
| 1376 | <event name="OnMiddleUp"></event> | ||
| 1377 | <event name="OnMotion"></event> | ||
| 1378 | <event name="OnMouseEvents"></event> | ||
| 1379 | <event name="OnMouseWheel"></event> | ||
| 1380 | <event name="OnPaint"></event> | ||
| 1381 | <event name="OnRightDClick"></event> | ||
| 1382 | <event name="OnRightDown"></event> | ||
| 1383 | <event name="OnRightUp"></event> | ||
| 1384 | <event name="OnSetFocus"></event> | ||
| 1385 | <event name="OnSize"></event> | ||
| 1386 | <event name="OnUpdateUI"></event> | ||
| 1387 | <object class="wxBoxSizer" expanded="1"> | ||
| 1388 | <property name="minimum_size"></property> | ||
| 1389 | <property name="name">bSizer161</property> | ||
| 1390 | <property name="orient">wxVERTICAL</property> | ||
| 1391 | <property name="permission">none</property> | ||
| 1392 | <object class="sizeritem" expanded="1"> | ||
| 1393 | <property name="border">5</property> | ||
| 1394 | <property name="flag">wxALL|wxEXPAND</property> | ||
| 1395 | <property name="proportion">1</property> | ||
| 1396 | <object class="wxListCtrl" expanded="1"> | ||
| 1397 | <property name="bg"></property> | ||
| 1398 | <property name="context_help"></property> | ||
| 1399 | <property name="enabled">1</property> | ||
| 1400 | <property name="fg"></property> | ||
| 1401 | <property name="font"></property> | ||
| 1402 | <property name="hidden">0</property> | ||
| 1403 | <property name="id">wxID_ANY</property> | ||
| 1404 | <property name="maximum_size"></property> | ||
| 1405 | <property name="minimum_size"></property> | ||
| 1406 | <property name="name">m_listCtrlOrdersReceived</property> | ||
| 1407 | <property name="permission">public</property> | ||
| 1408 | <property name="pos"></property> | ||
| 1409 | <property name="size"></property> | ||
| 1410 | <property name="style">wxLC_NO_SORT_HEADER|wxLC_REPORT</property> | ||
| 1411 | <property name="subclass"></property> | ||
| 1412 | <property name="tooltip"></property> | ||
| 1413 | <property name="window_extra_style"></property> | ||
| 1414 | <property name="window_name"></property> | ||
| 1415 | <property name="window_style"></property> | ||
| 1416 | <event name="OnChar"></event> | ||
| 1417 | <event name="OnEnterWindow"></event> | ||
| 1418 | <event name="OnEraseBackground"></event> | ||
| 1419 | <event name="OnKeyDown"></event> | ||
| 1420 | <event name="OnKeyUp"></event> | ||
| 1421 | <event name="OnKillFocus"></event> | ||
| 1422 | <event name="OnLeaveWindow"></event> | ||
| 1423 | <event name="OnLeftDClick"></event> | ||
| 1424 | <event name="OnLeftDown"></event> | ||
| 1425 | <event name="OnLeftUp"></event> | ||
| 1426 | <event name="OnListBeginDrag"></event> | ||
| 1427 | <event name="OnListBeginLabelEdit"></event> | ||
| 1428 | <event name="OnListBeginRDrag"></event> | ||
| 1429 | <event name="OnListCacheHint"></event> | ||
| 1430 | <event name="OnListColBeginDrag"></event> | ||
| 1431 | <event name="OnListColClick"></event> | ||
| 1432 | <event name="OnListColDragging"></event> | ||
| 1433 | <event name="OnListColEndDrag"></event> | ||
| 1434 | <event name="OnListColRightClick"></event> | ||
| 1435 | <event name="OnListDeleteAllItems"></event> | ||
| 1436 | <event name="OnListDeleteItem"></event> | ||
| 1437 | <event name="OnListEndLabelEdit"></event> | ||
| 1438 | <event name="OnListInsertItem"></event> | ||
| 1439 | <event name="OnListItemActivated">OnListItemActivatedOrdersReceived</event> | ||
| 1440 | <event name="OnListItemDeselected"></event> | ||
| 1441 | <event name="OnListItemFocused"></event> | ||
| 1442 | <event name="OnListItemMiddleClick"></event> | ||
| 1443 | <event name="OnListItemRightClick"></event> | ||
| 1444 | <event name="OnListItemSelected"></event> | ||
| 1445 | <event name="OnListKeyDown"></event> | ||
| 1446 | <event name="OnMiddleDClick"></event> | ||
| 1447 | <event name="OnMiddleDown"></event> | ||
| 1448 | <event name="OnMiddleUp"></event> | ||
| 1449 | <event name="OnMotion"></event> | ||
| 1450 | <event name="OnMouseEvents"></event> | ||
| 1451 | <event name="OnMouseWheel"></event> | ||
| 1452 | <event name="OnPaint"></event> | ||
| 1453 | <event name="OnRightDClick"></event> | ||
| 1454 | <event name="OnRightDown"></event> | ||
| 1455 | <event name="OnRightUp"></event> | ||
| 1456 | <event name="OnSetFocus"></event> | ||
| 1457 | <event name="OnSize"></event> | ||
| 1458 | <event name="OnUpdateUI"></event> | ||
| 1459 | </object> | ||
| 1460 | </object> | ||
| 1461 | </object> | ||
| 1462 | </object> | ||
| 1463 | </object> | ||
| 1464 | </object> | ||
| 1465 | </object> | ||
| 1466 | </object> | ||
| 1467 | </object> | ||
| 1468 | <object class="Dialog" expanded="0"> | ||
| 1469 | <property name="bg"></property> | ||
| 1470 | <property name="center"></property> | ||
| 1471 | <property name="context_help"></property> | ||
| 1472 | <property name="enabled">1</property> | ||
| 1473 | <property name="extra_style"></property> | ||
| 1474 | <property name="fg"></property> | ||
| 1475 | <property name="font"></property> | ||
| 1476 | <property name="hidden">0</property> | ||
| 1477 | <property name="id">wxID_ANY</property> | ||
| 1478 | <property name="maximum_size"></property> | ||
| 1479 | <property name="minimum_size"></property> | ||
| 1480 | <property name="name">CTxDetailsDialogBase</property> | ||
| 1481 | <property name="pos"></property> | ||
| 1482 | <property name="size">620,450</property> | ||
| 1483 | <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property> | ||
| 1484 | <property name="subclass"></property> | ||
| 1485 | <property name="title">Transaction Details</property> | ||
| 1486 | <property name="tooltip"></property> | ||
| 1487 | <property name="window_extra_style"></property> | ||
| 1488 | <property name="window_name"></property> | ||
| 1489 | <property name="window_style"></property> | ||
| 1490 | <event name="OnActivate"></event> | ||
| 1491 | <event name="OnActivateApp"></event> | ||
| 1492 | <event name="OnChar"></event> | ||
| 1493 | <event name="OnClose"></event> | ||
| 1494 | <event name="OnEnterWindow"></event> | ||
| 1495 | <event name="OnEraseBackground"></event> | ||
| 1496 | <event name="OnHibernate"></event> | ||
| 1497 | <event name="OnIconize"></event> | ||
| 1498 | <event name="OnIdle"></event> | ||
| 1499 | <event name="OnInitDialog"></event> | ||
| 1500 | <event name="OnKeyDown"></event> | ||
| 1501 | <event name="OnKeyUp"></event> | ||
| 1502 | <event name="OnKillFocus"></event> | ||
| 1503 | <event name="OnLeaveWindow"></event> | ||
| 1504 | <event name="OnLeftDClick"></event> | ||
| 1505 | <event name="OnLeftDown"></event> | ||
| 1506 | <event name="OnLeftUp"></event> | ||
| 1507 | <event name="OnMiddleDClick"></event> | ||
| 1508 | <event name="OnMiddleDown"></event> | ||
| 1509 | <event name="OnMiddleUp"></event> | ||
| 1510 | <event name="OnMotion"></event> | ||
| 1511 | <event name="OnMouseEvents"></event> | ||
| 1512 | <event name="OnMouseWheel"></event> | ||
| 1513 | <event name="OnPaint"></event> | ||
| 1514 | <event name="OnRightDClick"></event> | ||
| 1515 | <event name="OnRightDown"></event> | ||
| 1516 | <event name="OnRightUp"></event> | ||
| 1517 | <event name="OnSetFocus"></event> | ||
| 1518 | <event name="OnSize"></event> | ||
| 1519 | <event name="OnUpdateUI"></event> | ||
| 1520 | <object class="wxBoxSizer" expanded="1"> | ||
| 1521 | <property name="minimum_size"></property> | ||
| 1522 | <property name="name">bSizer64</property> | ||
| 1523 | <property name="orient">wxVERTICAL</property> | ||
| 1524 | <property name="permission">none</property> | ||
| 1525 | <object class="sizeritem" expanded="1"> | ||
| 1526 | <property name="border">5</property> | ||
| 1527 | <property name="flag">wxEXPAND</property> | ||
| 1528 | <property name="proportion">1</property> | ||
| 1529 | <object class="wxBoxSizer" expanded="1"> | ||
| 1530 | <property name="minimum_size"></property> | ||
| 1531 | <property name="name">bSizer66</property> | ||
| 1532 | <property name="orient">wxVERTICAL</property> | ||
| 1533 | <property name="permission">none</property> | ||
| 1534 | <object class="sizeritem" expanded="1"> | ||
| 1535 | <property name="border">5</property> | ||
| 1536 | <property name="flag">wxALL|wxEXPAND</property> | ||
| 1537 | <property name="proportion">1</property> | ||
| 1538 | <object class="wxHtmlWindow" expanded="1"> | ||
| 1539 | <property name="bg"></property> | ||
| 1540 | <property name="context_help"></property> | ||
| 1541 | <property name="enabled">1</property> | ||
| 1542 | <property name="fg"></property> | ||
| 1543 | <property name="font"></property> | ||
| 1544 | <property name="hidden">0</property> | ||
| 1545 | <property name="id">wxID_ANY</property> | ||
| 1546 | <property name="maximum_size"></property> | ||
| 1547 | <property name="minimum_size"></property> | ||
| 1548 | <property name="name">m_htmlWin</property> | ||
| 1549 | <property name="permission">protected</property> | ||
| 1550 | <property name="pos"></property> | ||
| 1551 | <property name="size"></property> | ||
| 1552 | <property name="style">wxHW_SCROLLBAR_AUTO</property> | ||
| 1553 | <property name="subclass"></property> | ||
| 1554 | <property name="tooltip"></property> | ||
| 1555 | <property name="window_extra_style"></property> | ||
| 1556 | <property name="window_name"></property> | ||
| 1557 | <property name="window_style"></property> | ||
| 1558 | <event name="OnChar"></event> | ||
| 1559 | <event name="OnEnterWindow"></event> | ||
| 1560 | <event name="OnEraseBackground"></event> | ||
| 1561 | <event name="OnHtmlCellClicked"></event> | ||
| 1562 | <event name="OnHtmlCellHover"></event> | ||
| 1563 | <event name="OnHtmlLinkClicked"></event> | ||
| 1564 | <event name="OnKeyDown"></event> | ||
| 1565 | <event name="OnKeyUp"></event> | ||
| 1566 | <event name="OnKillFocus"></event> | ||
| 1567 | <event name="OnLeaveWindow"></event> | ||
| 1568 | <event name="OnLeftDClick"></event> | ||
| 1569 | <event name="OnLeftDown"></event> | ||
| 1570 | <event name="OnLeftUp"></event> | ||
| 1571 | <event name="OnMiddleDClick"></event> | ||
| 1572 | <event name="OnMiddleDown"></event> | ||
| 1573 | <event name="OnMiddleUp"></event> | ||
| 1574 | <event name="OnMotion"></event> | ||
| 1575 | <event name="OnMouseEvents"></event> | ||
| 1576 | <event name="OnMouseWheel"></event> | ||
| 1577 | <event name="OnPaint"></event> | ||
| 1578 | <event name="OnRightDClick"></event> | ||
| 1579 | <event name="OnRightDown"></event> | ||
| 1580 | <event name="OnRightUp"></event> | ||
| 1581 | <event name="OnSetFocus"></event> | ||
| 1582 | <event name="OnSize"></event> | ||
| 1583 | <event name="OnUpdateUI"></event> | ||
| 1584 | </object> | ||
| 1585 | </object> | ||
| 1586 | </object> | ||
| 1587 | </object> | ||
| 1588 | <object class="sizeritem" expanded="1"> | ||
| 1589 | <property name="border">5</property> | ||
| 1590 | <property name="flag">wxALIGN_RIGHT</property> | ||
| 1591 | <property name="proportion">0</property> | ||
| 1592 | <object class="wxBoxSizer" expanded="1"> | ||
| 1593 | <property name="minimum_size"></property> | ||
| 1594 | <property name="name">bSizer65</property> | ||
| 1595 | <property name="orient">wxVERTICAL</property> | ||
| 1596 | <property name="permission">none</property> | ||
| 1597 | <object class="sizeritem" expanded="1"> | ||
| 1598 | <property name="border">5</property> | ||
| 1599 | <property name="flag">wxALL</property> | ||
| 1600 | <property name="proportion">0</property> | ||
| 1601 | <object class="wxButton" expanded="1"> | ||
| 1602 | <property name="bg"></property> | ||
| 1603 | <property name="context_help"></property> | ||
| 1604 | <property name="default">0</property> | ||
| 1605 | <property name="enabled">1</property> | ||
| 1606 | <property name="fg"></property> | ||
| 1607 | <property name="font"></property> | ||
| 1608 | <property name="hidden">0</property> | ||
| 1609 | <property name="id">wxID_OK</property> | ||
| 1610 | <property name="label">OK</property> | ||
| 1611 | <property name="maximum_size"></property> | ||
| 1612 | <property name="minimum_size"></property> | ||
| 1613 | <property name="name">m_buttonOK</property> | ||
| 1614 | <property name="permission">protected</property> | ||
| 1615 | <property name="pos"></property> | ||
| 1616 | <property name="size">85,25</property> | ||
| 1617 | <property name="style"></property> | ||
| 1618 | <property name="subclass"></property> | ||
| 1619 | <property name="tooltip"></property> | ||
| 1620 | <property name="window_extra_style"></property> | ||
| 1621 | <property name="window_name"></property> | ||
| 1622 | <property name="window_style"></property> | ||
| 1623 | <event name="OnButtonClick">OnButtonOK</event> | ||
| 1624 | <event name="OnChar"></event> | ||
| 1625 | <event name="OnEnterWindow"></event> | ||
| 1626 | <event name="OnEraseBackground"></event> | ||
| 1627 | <event name="OnKeyDown"></event> | ||
| 1628 | <event name="OnKeyUp"></event> | ||
| 1629 | <event name="OnKillFocus"></event> | ||
| 1630 | <event name="OnLeaveWindow"></event> | ||
| 1631 | <event name="OnLeftDClick"></event> | ||
| 1632 | <event name="OnLeftDown"></event> | ||
| 1633 | <event name="OnLeftUp"></event> | ||
| 1634 | <event name="OnMiddleDClick"></event> | ||
| 1635 | <event name="OnMiddleDown"></event> | ||
| 1636 | <event name="OnMiddleUp"></event> | ||
| 1637 | <event name="OnMotion"></event> | ||
| 1638 | <event name="OnMouseEvents"></event> | ||
| 1639 | <event name="OnMouseWheel"></event> | ||
| 1640 | <event name="OnPaint"></event> | ||
| 1641 | <event name="OnRightDClick"></event> | ||
| 1642 | <event name="OnRightDown"></event> | ||
| 1643 | <event name="OnRightUp"></event> | ||
| 1644 | <event name="OnSetFocus"></event> | ||
| 1645 | <event name="OnSize"></event> | ||
| 1646 | <event name="OnUpdateUI"></event> | ||
| 1647 | </object> | ||
| 1648 | </object> | ||
| 1649 | </object> | ||
| 1650 | </object> | ||
| 1651 | </object> | ||
| 1652 | </object> | ||
| 1653 | <object class="Dialog" expanded="0"> | ||
| 1654 | <property name="bg"></property> | ||
| 1655 | <property name="center"></property> | ||
| 1656 | <property name="context_help"></property> | ||
| 1657 | <property name="enabled">1</property> | ||
| 1658 | <property name="extra_style"></property> | ||
| 1659 | <property name="fg"></property> | ||
| 1660 | <property name="font"></property> | ||
| 1661 | <property name="hidden">0</property> | ||
| 1662 | <property name="id">wxID_ANY</property> | ||
| 1663 | <property name="maximum_size"></property> | ||
| 1664 | <property name="minimum_size"></property> | ||
| 1665 | <property name="name">COptionsDialogBase</property> | ||
| 1666 | <property name="pos"></property> | ||
| 1667 | <property name="size">500,261</property> | ||
| 1668 | <property name="style">wxDEFAULT_DIALOG_STYLE</property> | ||
| 1669 | <property name="subclass"></property> | ||
| 1670 | <property name="title">Options</property> | ||
| 1671 | <property name="tooltip"></property> | ||
| 1672 | <property name="window_extra_style"></property> | ||
| 1673 | <property name="window_name"></property> | ||
| 1674 | <property name="window_style"></property> | ||
| 1675 | <event name="OnActivate"></event> | ||
| 1676 | <event name="OnActivateApp"></event> | ||
| 1677 | <event name="OnChar"></event> | ||
| 1678 | <event name="OnClose"></event> | ||
| 1679 | <event name="OnEnterWindow"></event> | ||
| 1680 | <event name="OnEraseBackground"></event> | ||
| 1681 | <event name="OnHibernate"></event> | ||
| 1682 | <event name="OnIconize"></event> | ||
| 1683 | <event name="OnIdle"></event> | ||
| 1684 | <event name="OnInitDialog"></event> | ||
| 1685 | <event name="OnKeyDown"></event> | ||
| 1686 | <event name="OnKeyUp"></event> | ||
| 1687 | <event name="OnKillFocus"></event> | ||
| 1688 | <event name="OnLeaveWindow"></event> | ||
| 1689 | <event name="OnLeftDClick"></event> | ||
| 1690 | <event name="OnLeftDown"></event> | ||
| 1691 | <event name="OnLeftUp"></event> | ||
| 1692 | <event name="OnMiddleDClick"></event> | ||
| 1693 | <event name="OnMiddleDown"></event> | ||
| 1694 | <event name="OnMiddleUp"></event> | ||
| 1695 | <event name="OnMotion"></event> | ||
| 1696 | <event name="OnMouseEvents"></event> | ||
| 1697 | <event name="OnMouseWheel"></event> | ||
| 1698 | <event name="OnPaint"></event> | ||
| 1699 | <event name="OnRightDClick"></event> | ||
| 1700 | <event name="OnRightDown"></event> | ||
| 1701 | <event name="OnRightUp"></event> | ||
| 1702 | <event name="OnSetFocus"></event> | ||
| 1703 | <event name="OnSize"></event> | ||
| 1704 | <event name="OnUpdateUI"></event> | ||
| 1705 | <object class="wxBoxSizer" expanded="1"> | ||
| 1706 | <property name="minimum_size"></property> | ||
| 1707 | <property name="name">bSizer55</property> | ||
| 1708 | <property name="orient">wxVERTICAL</property> | ||
| 1709 | <property name="permission">none</property> | ||
| 1710 | <object class="sizeritem" expanded="1"> | ||
| 1711 | <property name="border">5</property> | ||
| 1712 | <property name="flag">wxEXPAND|wxLEFT</property> | ||
| 1713 | <property name="proportion">1</property> | ||
| 1714 | <object class="wxBoxSizer" expanded="1"> | ||
| 1715 | <property name="minimum_size"></property> | ||
| 1716 | <property name="name">bSizer57</property> | ||
| 1717 | <property name="orient">wxVERTICAL</property> | ||
| 1718 | <property name="permission">none</property> | ||
| 1719 | <object class="sizeritem" expanded="1"> | ||
| 1720 | <property name="border">5</property> | ||
| 1721 | <property name="flag">wxEXPAND</property> | ||
| 1722 | <property name="proportion">0</property> | ||
| 1723 | <object class="spacer" expanded="1"> | ||
| 1724 | <property name="height">20</property> | ||
| 1725 | <property name="permission">protected</property> | ||
| 1726 | <property name="width">0</property> | ||
| 1727 | </object> | ||
| 1728 | </object> | ||
| 1729 | <object class="sizeritem" expanded="1"> | ||
| 1730 | <property name="border">5</property> | ||
| 1731 | <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property> | ||
| 1732 | <property name="proportion">0</property> | ||
| 1733 | <object class="wxStaticText" expanded="1"> | ||
| 1734 | <property name="bg"></property> | ||
| 1735 | <property name="context_help"></property> | ||
| 1736 | <property name="enabled">1</property> | ||
| 1737 | <property name="fg"></property> | ||
| 1738 | <property name="font"></property> | ||
| 1739 | <property name="hidden">0</property> | ||
| 1740 | <property name="id">wxID_ANY</property> | ||
| 1741 | <property name="label">Optional transaction fee you give to the nodes that process your transactions.</property> | ||
| 1742 | <property name="maximum_size"></property> | ||
| 1743 | <property name="minimum_size"></property> | ||
| 1744 | <property name="name">m_staticText32</property> | ||
| 1745 | <property name="permission">protected</property> | ||
| 1746 | <property name="pos"></property> | ||
| 1747 | <property name="size"></property> | ||
| 1748 | <property name="style"></property> | ||
| 1749 | <property name="subclass"></property> | ||
| 1750 | <property name="tooltip"></property> | ||
| 1751 | <property name="window_extra_style"></property> | ||
| 1752 | <property name="window_name"></property> | ||
| 1753 | <property name="window_style"></property> | ||
| 1754 | <property name="wrap">-1</property> | ||
| 1755 | <event name="OnChar"></event> | ||
| 1756 | <event name="OnEnterWindow"></event> | ||
| 1757 | <event name="OnEraseBackground"></event> | ||
| 1758 | <event name="OnKeyDown"></event> | ||
| 1759 | <event name="OnKeyUp"></event> | ||
| 1760 | <event name="OnKillFocus"></event> | ||
| 1761 | <event name="OnLeaveWindow"></event> | ||
| 1762 | <event name="OnLeftDClick"></event> | ||
| 1763 | <event name="OnLeftDown"></event> | ||
| 1764 | <event name="OnLeftUp"></event> | ||
| 1765 | <event name="OnMiddleDClick"></event> | ||
| 1766 | <event name="OnMiddleDown"></event> | ||
| 1767 | <event name="OnMiddleUp"></event> | ||
| 1768 | <event name="OnMotion"></event> | ||
| 1769 | <event name="OnMouseEvents"></event> | ||
| 1770 | <event name="OnMouseWheel"></event> | ||
| 1771 | <event name="OnPaint"></event> | ||
| 1772 | <event name="OnRightDClick"></event> | ||
| 1773 | <event name="OnRightDown"></event> | ||
| 1774 | <event name="OnRightUp"></event> | ||
| 1775 | <event name="OnSetFocus"></event> | ||
| 1776 | <event name="OnSize"></event> | ||
| 1777 | <event name="OnUpdateUI"></event> | ||
| 1778 | </object> | ||
| 1779 | </object> | ||
| 1780 | <object class="sizeritem" expanded="1"> | ||
| 1781 | <property name="border">5</property> | ||
| 1782 | <property name="flag">wxEXPAND</property> | ||
| 1783 | <property name="proportion">0</property> | ||
| 1784 | <object class="wxBoxSizer" expanded="1"> | ||
| 1785 | <property name="minimum_size"></property> | ||
| 1786 | <property name="name">bSizer56</property> | ||
| 1787 | <property name="orient">wxHORIZONTAL</property> | ||
| 1788 | <property name="permission">none</property> | ||
| 1789 | <object class="sizeritem" expanded="1"> | ||
| 1790 | <property name="border">5</property> | ||
| 1791 | <property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT</property> | ||
| 1792 | <property name="proportion">0</property> | ||
| 1793 | <object class="wxStaticText" expanded="1"> | ||
| 1794 | <property name="bg"></property> | ||
| 1795 | <property name="context_help"></property> | ||
| 1796 | <property name="enabled">1</property> | ||
| 1797 | <property name="fg"></property> | ||
| 1798 | <property name="font"></property> | ||
| 1799 | <property name="hidden">0</property> | ||
| 1800 | <property name="id">wxID_ANY</property> | ||
| 1801 | <property name="label">Transaction fee:</property> | ||
| 1802 | <property name="maximum_size"></property> | ||
| 1803 | <property name="minimum_size"></property> | ||
| 1804 | <property name="name">m_staticText31</property> | ||
| 1805 | <property name="permission">protected</property> | ||
| 1806 | <property name="pos"></property> | ||
| 1807 | <property name="size"></property> | ||
| 1808 | <property name="style"></property> | ||
| 1809 | <property name="subclass"></property> | ||
| 1810 | <property name="tooltip"></property> | ||
| 1811 | <property name="window_extra_style"></property> | ||
| 1812 | <property name="window_name"></property> | ||
| 1813 | <property name="window_style"></property> | ||
| 1814 | <property name="wrap">-1</property> | ||
| 1815 | <event name="OnChar"></event> | ||
| 1816 | <event name="OnEnterWindow"></event> | ||
| 1817 | <event name="OnEraseBackground"></event> | ||
| 1818 | <event name="OnKeyDown"></event> | ||
| 1819 | <event name="OnKeyUp"></event> | ||
| 1820 | <event name="OnKillFocus"></event> | ||
| 1821 | <event name="OnLeaveWindow"></event> | ||
| 1822 | <event name="OnLeftDClick"></event> | ||
| 1823 | <event name="OnLeftDown"></event> | ||
| 1824 | <event name="OnLeftUp"></event> | ||
| 1825 | <event name="OnMiddleDClick"></event> | ||
| 1826 | <event name="OnMiddleDown"></event> | ||
| 1827 | <event name="OnMiddleUp"></event> | ||
| 1828 | <event name="OnMotion"></event> | ||
| 1829 | <event name="OnMouseEvents"></event> | ||
| 1830 | <event name="OnMouseWheel"></event> | ||
| 1831 | <event name="OnPaint"></event> | ||
| 1832 | <event name="OnRightDClick"></event> | ||
| 1833 | <event name="OnRightDown"></event> | ||
| 1834 | <event name="OnRightUp"></event> | ||
| 1835 | <event name="OnSetFocus"></event> | ||
| 1836 | <event name="OnSize"></event> | ||
| 1837 | <event name="OnUpdateUI"></event> | ||
| 1838 | </object> | ||
| 1839 | </object> | ||
| 1840 | <object class="sizeritem" expanded="1"> | ||
| 1841 | <property name="border">5</property> | ||
| 1842 | <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property> | ||
| 1843 | <property name="proportion">0</property> | ||
| 1844 | <object class="wxTextCtrl" expanded="1"> | ||
| 1845 | <property name="bg"></property> | ||
| 1846 | <property name="context_help"></property> | ||
| 1847 | <property name="enabled">1</property> | ||
| 1848 | <property name="fg"></property> | ||
| 1849 | <property name="font"></property> | ||
| 1850 | <property name="hidden">0</property> | ||
| 1851 | <property name="id">wxID_TRANSACTIONFEE</property> | ||
| 1852 | <property name="maximum_size"></property> | ||
| 1853 | <property name="maxlength">0</property> | ||
| 1854 | <property name="minimum_size"></property> | ||
| 1855 | <property name="name">m_textCtrlTransactionFee</property> | ||
| 1856 | <property name="permission">protected</property> | ||
| 1857 | <property name="pos"></property> | ||
| 1858 | <property name="size">70,-1</property> | ||
| 1859 | <property name="style"></property> | ||
| 1860 | <property name="subclass"></property> | ||
| 1861 | <property name="tooltip"></property> | ||
| 1862 | <property name="value"></property> | ||
| 1863 | <property name="window_extra_style"></property> | ||
| 1864 | <property name="window_name"></property> | ||
| 1865 | <property name="window_style"></property> | ||
| 1866 | <event name="OnChar"></event> | ||
| 1867 | <event name="OnEnterWindow"></event> | ||
| 1868 | <event name="OnEraseBackground"></event> | ||
| 1869 | <event name="OnKeyDown"></event> | ||
| 1870 | <event name="OnKeyUp"></event> | ||
| 1871 | <event name="OnKillFocus">OnKillFocusTransactionFee</event> | ||
| 1872 | <event name="OnLeaveWindow"></event> | ||
| 1873 | <event name="OnLeftDClick"></event> | ||
| 1874 | <event name="OnLeftDown"></event> | ||
| 1875 | <event name="OnLeftUp"></event> | ||
| 1876 | <event name="OnMiddleDClick"></event> | ||
| 1877 | <event name="OnMiddleDown"></event> | ||
| 1878 | <event name="OnMiddleUp"></event> | ||
| 1879 | <event name="OnMotion"></event> | ||
| 1880 | <event name="OnMouseEvents"></event> | ||
| 1881 | <event name="OnMouseWheel"></event> | ||
| 1882 | <event name="OnPaint"></event> | ||
| 1883 | <event name="OnRightDClick"></event> | ||
| 1884 | <event name="OnRightDown"></event> | ||
| 1885 | <event name="OnRightUp"></event> | ||
| 1886 | <event name="OnSetFocus"></event> | ||
| 1887 | <event name="OnSize"></event> | ||
| 1888 | <event name="OnText"></event> | ||
| 1889 | <event name="OnTextEnter"></event> | ||
| 1890 | <event name="OnTextMaxLen"></event> | ||
| 1891 | <event name="OnTextURL"></event> | ||
| 1892 | <event name="OnUpdateUI"></event> | ||
| 1893 | </object> | ||
| 1894 | </object> | ||
| 1895 | </object> | ||
| 1896 | </object> | ||
| 1897 | </object> | ||
| 1898 | </object> | ||
| 1899 | <object class="sizeritem" expanded="1"> | ||
| 1900 | <property name="border">5</property> | ||
| 1901 | <property name="flag">wxALIGN_RIGHT</property> | ||
| 1902 | <property name="proportion">0</property> | ||
| 1903 | <object class="wxBoxSizer" expanded="1"> | ||
| 1904 | <property name="minimum_size"></property> | ||
| 1905 | <property name="name">bSizer58</property> | ||
| 1906 | <property name="orient">wxHORIZONTAL</property> | ||
| 1907 | <property name="permission">none</property> | ||
| 1908 | <object class="sizeritem" expanded="1"> | ||
| 1909 | <property name="border">5</property> | ||
| 1910 | <property name="flag">wxALL</property> | ||
| 1911 | <property name="proportion">0</property> | ||
| 1912 | <object class="wxButton" expanded="1"> | ||
| 1913 | <property name="bg"></property> | ||
| 1914 | <property name="context_help"></property> | ||
| 1915 | <property name="default">0</property> | ||
| 1916 | <property name="enabled">1</property> | ||
| 1917 | <property name="fg"></property> | ||
| 1918 | <property name="font"></property> | ||
| 1919 | <property name="hidden">0</property> | ||
| 1920 | <property name="id">wxID_OK</property> | ||
| 1921 | <property name="label">OK</property> | ||
| 1922 | <property name="maximum_size"></property> | ||
| 1923 | <property name="minimum_size"></property> | ||
| 1924 | <property name="name">m_buttonOK</property> | ||
| 1925 | <property name="permission">protected</property> | ||
| 1926 | <property name="pos"></property> | ||
| 1927 | <property name="size">85,25</property> | ||
| 1928 | <property name="style"></property> | ||
| 1929 | <property name="subclass"></property> | ||
| 1930 | <property name="tooltip"></property> | ||
| 1931 | <property name="window_extra_style"></property> | ||
| 1932 | <property name="window_name"></property> | ||
| 1933 | <property name="window_style"></property> | ||
| 1934 | <event name="OnButtonClick">OnButtonOK</event> | ||
| 1935 | <event name="OnChar"></event> | ||
| 1936 | <event name="OnEnterWindow"></event> | ||
| 1937 | <event name="OnEraseBackground"></event> | ||
| 1938 | <event name="OnKeyDown"></event> | ||
| 1939 | <event name="OnKeyUp"></event> | ||
| 1940 | <event name="OnKillFocus"></event> | ||
| 1941 | <event name="OnLeaveWindow"></event> | ||
| 1942 | <event name="OnLeftDClick"></event> | ||
| 1943 | <event name="OnLeftDown"></event> | ||
| 1944 | <event name="OnLeftUp"></event> | ||
| 1945 | <event name="OnMiddleDClick"></event> | ||
| 1946 | <event name="OnMiddleDown"></event> | ||
| 1947 | <event name="OnMiddleUp"></event> | ||
| 1948 | <event name="OnMotion"></event> | ||
| 1949 | <event name="OnMouseEvents"></event> | ||
| 1950 | <event name="OnMouseWheel"></event> | ||
| 1951 | <event name="OnPaint"></event> | ||
| 1952 | <event name="OnRightDClick"></event> | ||
| 1953 | <event name="OnRightDown"></event> | ||
| 1954 | <event name="OnRightUp"></event> | ||
| 1955 | <event name="OnSetFocus"></event> | ||
| 1956 | <event name="OnSize"></event> | ||
| 1957 | <event name="OnUpdateUI"></event> | ||
| 1958 | </object> | ||
| 1959 | </object> | ||
| 1960 | <object class="sizeritem" expanded="1"> | ||
| 1961 | <property name="border">5</property> | ||
| 1962 | <property name="flag">wxALL</property> | ||
| 1963 | <property name="proportion">0</property> | ||
| 1964 | <object class="wxButton" expanded="1"> | ||
| 1965 | <property name="bg"></property> | ||
| 1966 | <property name="context_help"></property> | ||
| 1967 | <property name="default">0</property> | ||
| 1968 | <property name="enabled">1</property> | ||
| 1969 | <property name="fg"></property> | ||
| 1970 | <property name="font"></property> | ||
| 1971 | <property name="hidden">0</property> | ||
| 1972 | <property name="id">wxID_CANCEL</property> | ||
| 1973 | <property name="label">Cancel</property> | ||
| 1974 | <property name="maximum_size"></property> | ||
| 1975 | <property name="minimum_size">85,25</property> | ||
| 1976 | <property name="name">m_buttonCancel</property> | ||
| 1977 | <property name="permission">protected</property> | ||
| 1978 | <property name="pos"></property> | ||
| 1979 | <property name="size">-1,-1</property> | ||
| 1980 | <property name="style"></property> | ||
| 1981 | <property name="subclass"></property> | ||
| 1982 | <property name="tooltip"></property> | ||
| 1983 | <property name="window_extra_style"></property> | ||
| 1984 | <property name="window_name"></property> | ||
| 1985 | <property name="window_style"></property> | ||
| 1986 | <event name="OnButtonClick">OnButtonCancel</event> | ||
| 1987 | <event name="OnChar"></event> | ||
| 1988 | <event name="OnEnterWindow"></event> | ||
| 1989 | <event name="OnEraseBackground"></event> | ||
| 1990 | <event name="OnKeyDown"></event> | ||
| 1991 | <event name="OnKeyUp"></event> | ||
| 1992 | <event name="OnKillFocus"></event> | ||
| 1993 | <event name="OnLeaveWindow"></event> | ||
| 1994 | <event name="OnLeftDClick"></event> | ||
| 1995 | <event name="OnLeftDown"></event> | ||
| 1996 | <event name="OnLeftUp"></event> | ||
| 1997 | <event name="OnMiddleDClick"></event> | ||
| 1998 | <event name="OnMiddleDown"></event> | ||
| 1999 | <event name="OnMiddleUp"></event> | ||
| 2000 | <event name="OnMotion"></event> | ||
| 2001 | <event name="OnMouseEvents"></event> | ||
| 2002 | <event name="OnMouseWheel"></event> | ||
| 2003 | <event name="OnPaint"></event> | ||
| 2004 | <event name="OnRightDClick"></event> | ||
| 2005 | <event name="OnRightDown"></event> | ||
| 2006 | <event name="OnRightUp"></event> | ||
| 2007 | <event name="OnSetFocus"></event> | ||
| 2008 | <event name="OnSize"></event> | ||
| 2009 | <event name="OnUpdateUI"></event> | ||
| 2010 | </object> | ||
| 2011 | </object> | ||
| 2012 | </object> | ||
| 2013 | </object> | ||
| 2014 | </object> | ||
| 2015 | </object> | ||
| 2016 | <object class="Dialog" expanded="0"> | ||
| 2017 | <property name="bg"></property> | ||
| 2018 | <property name="center"></property> | ||
| 2019 | <property name="context_help"></property> | ||
| 2020 | <property name="enabled">1</property> | ||
| 2021 | <property name="extra_style"></property> | ||
| 2022 | <property name="fg"></property> | ||
| 2023 | <property name="font"></property> | ||
| 2024 | <property name="hidden">0</property> | ||
| 2025 | <property name="id">wxID_ANY</property> | ||
| 2026 | <property name="maximum_size"></property> | ||
| 2027 | <property name="minimum_size"></property> | ||
| 2028 | <property name="name">CAboutDialogBase</property> | ||
| 2029 | <property name="pos"></property> | ||
| 2030 | <property name="size">507,298</property> | ||
| 2031 | <property name="style">wxDEFAULT_DIALOG_STYLE</property> | ||
| 2032 | <property name="subclass"></property> | ||
| 2033 | <property name="title">About Bitcoin</property> | ||
| 2034 | <property name="tooltip"></property> | ||
| 2035 | <property name="window_extra_style"></property> | ||
| 2036 | <property name="window_name"></property> | ||
| 2037 | <property name="window_style"></property> | ||
| 2038 | <event name="OnActivate"></event> | ||
| 2039 | <event name="OnActivateApp"></event> | ||
| 2040 | <event name="OnChar"></event> | ||
| 2041 | <event name="OnClose"></event> | ||
| 2042 | <event name="OnEnterWindow"></event> | ||
| 2043 | <event name="OnEraseBackground"></event> | ||
| 2044 | <event name="OnHibernate"></event> | ||
| 2045 | <event name="OnIconize"></event> | ||
| 2046 | <event name="OnIdle"></event> | ||
| 2047 | <event name="OnInitDialog"></event> | ||
| 2048 | <event name="OnKeyDown"></event> | ||
| 2049 | <event name="OnKeyUp"></event> | ||
| 2050 | <event name="OnKillFocus"></event> | ||
| 2051 | <event name="OnLeaveWindow"></event> | ||
| 2052 | <event name="OnLeftDClick"></event> | ||
| 2053 | <event name="OnLeftDown"></event> | ||
| 2054 | <event name="OnLeftUp"></event> | ||
| 2055 | <event name="OnMiddleDClick"></event> | ||
| 2056 | <event name="OnMiddleDown"></event> | ||
| 2057 | <event name="OnMiddleUp"></event> | ||
| 2058 | <event name="OnMotion"></event> | ||
| 2059 | <event name="OnMouseEvents"></event> | ||
| 2060 | <event name="OnMouseWheel"></event> | ||
| 2061 | <event name="OnPaint"></event> | ||
| 2062 | <event name="OnRightDClick"></event> | ||
| 2063 | <event name="OnRightDown"></event> | ||
| 2064 | <event name="OnRightUp"></event> | ||
| 2065 | <event name="OnSetFocus"></event> | ||
| 2066 | <event name="OnSize"></event> | ||
| 2067 | <event name="OnUpdateUI"></event> | ||
| 2068 | <object class="wxBoxSizer" expanded="0"> | ||
| 2069 | <property name="minimum_size"></property> | ||
| 2070 | <property name="name">bSizer60</property> | ||
| 2071 | <property name="orient">wxVERTICAL</property> | ||
| 2072 | <property name="permission">none</property> | ||
| 2073 | <object class="sizeritem" expanded="1"> | ||
| 2074 | <property name="border">5</property> | ||
| 2075 | <property name="flag">wxEXPAND</property> | ||
| 2076 | <property name="proportion">1</property> | ||
| 2077 | <object class="wxBoxSizer" expanded="1"> | ||
| 2078 | <property name="minimum_size"></property> | ||
| 2079 | <property name="name">bSizer62</property> | ||
| 2080 | <property name="orient">wxHORIZONTAL</property> | ||
| 2081 | <property name="permission">none</property> | ||
| 2082 | <object class="sizeritem" expanded="1"> | ||
| 2083 | <property name="border">5</property> | ||
| 2084 | <property name="flag">wxEXPAND</property> | ||
| 2085 | <property name="proportion">0</property> | ||
| 2086 | <object class="spacer" expanded="1"> | ||
| 2087 | <property name="height">0</property> | ||
| 2088 | <property name="permission">protected</property> | ||
| 2089 | <property name="width">60</property> | ||
| 2090 | </object> | ||
| 2091 | </object> | ||
| 2092 | <object class="sizeritem" expanded="1"> | ||
| 2093 | <property name="border">5</property> | ||
| 2094 | <property name="flag">wxEXPAND</property> | ||
| 2095 | <property name="proportion">1</property> | ||
| 2096 | <object class="wxBoxSizer" expanded="1"> | ||
| 2097 | <property name="minimum_size"></property> | ||
| 2098 | <property name="name">bSizer63</property> | ||
| 2099 | <property name="orient">wxVERTICAL</property> | ||
| 2100 | <property name="permission">none</property> | ||
| 2101 | <object class="sizeritem" expanded="1"> | ||
| 2102 | <property name="border">5</property> | ||
| 2103 | <property name="flag">wxEXPAND</property> | ||
| 2104 | <property name="proportion">0</property> | ||
| 2105 | <object class="spacer" expanded="1"> | ||
| 2106 | <property name="height">50</property> | ||
| 2107 | <property name="permission">protected</property> | ||
| 2108 | <property name="width">0</property> | ||
| 2109 | </object> | ||
| 2110 | </object> | ||
| 2111 | <object class="sizeritem" expanded="1"> | ||
| 2112 | <property name="border">5</property> | ||
| 2113 | <property name="flag">wxEXPAND</property> | ||
| 2114 | <property name="proportion">0</property> | ||
| 2115 | <object class="wxBoxSizer" expanded="1"> | ||
| 2116 | <property name="minimum_size"></property> | ||
| 2117 | <property name="name">bSizer64</property> | ||
| 2118 | <property name="orient">wxHORIZONTAL</property> | ||
| 2119 | <property name="permission">none</property> | ||
| 2120 | <object class="sizeritem" expanded="1"> | ||
| 2121 | <property name="border">5</property> | ||
| 2122 | <property name="flag">wxALIGN_BOTTOM|wxTOP|wxBOTTOM|wxLEFT</property> | ||
| 2123 | <property name="proportion">0</property> | ||
| 2124 | <object class="wxStaticText" expanded="1"> | ||
| 2125 | <property name="bg"></property> | ||
| 2126 | <property name="context_help"></property> | ||
| 2127 | <property name="enabled">1</property> | ||
| 2128 | <property name="fg"></property> | ||
| 2129 | <property name="font">Tahoma,90,92,10,74,0</property> | ||
| 2130 | <property name="hidden">0</property> | ||
| 2131 | <property name="id">wxID_ANY</property> | ||
| 2132 | <property name="label">Bitcoin </property> | ||
| 2133 | <property name="maximum_size"></property> | ||
| 2134 | <property name="minimum_size"></property> | ||
| 2135 | <property name="name">m_staticText40</property> | ||
| 2136 | <property name="permission">protected</property> | ||
| 2137 | <property name="pos"></property> | ||
| 2138 | <property name="size"></property> | ||
| 2139 | <property name="style"></property> | ||
| 2140 | <property name="subclass"></property> | ||
| 2141 | <property name="tooltip"></property> | ||
| 2142 | <property name="window_extra_style"></property> | ||
| 2143 | <property name="window_name"></property> | ||
| 2144 | <property name="window_style"></property> | ||
| 2145 | <property name="wrap">-1</property> | ||
| 2146 | <event name="OnChar"></event> | ||
| 2147 | <event name="OnEnterWindow"></event> | ||
| 2148 | <event name="OnEraseBackground"></event> | ||
| 2149 | <event name="OnKeyDown"></event> | ||
| 2150 | <event name="OnKeyUp"></event> | ||
| 2151 | <event name="OnKillFocus"></event> | ||
| 2152 | <event name="OnLeaveWindow"></event> | ||
| 2153 | <event name="OnLeftDClick"></event> | ||
| 2154 | <event name="OnLeftDown"></event> | ||
| 2155 | <event name="OnLeftUp"></event> | ||
| 2156 | <event name="OnMiddleDClick"></event> | ||
| 2157 | <event name="OnMiddleDown"></event> | ||
| 2158 | <event name="OnMiddleUp"></event> | ||
| 2159 | <event name="OnMotion"></event> | ||
| 2160 | <event name="OnMouseEvents"></event> | ||
| 2161 | <event name="OnMouseWheel"></event> | ||
| 2162 | <event name="OnPaint"></event> | ||
| 2163 | <event name="OnRightDClick"></event> | ||
| 2164 | <event name="OnRightDown"></event> | ||
| 2165 | <event name="OnRightUp"></event> | ||
| 2166 | <event name="OnSetFocus"></event> | ||
| 2167 | <event name="OnSize"></event> | ||
| 2168 | <event name="OnUpdateUI"></event> | ||
| 2169 | </object> | ||
| 2170 | </object> | ||
| 2171 | <object class="sizeritem" expanded="1"> | ||
| 2172 | <property name="border">5</property> | ||
| 2173 | <property name="flag">wxALIGN_BOTTOM|wxTOP|wxBOTTOM|wxRIGHT</property> | ||
| 2174 | <property name="proportion">0</property> | ||
| 2175 | <object class="wxStaticText" expanded="1"> | ||
| 2176 | <property name="bg"></property> | ||
| 2177 | <property name="context_help"></property> | ||
| 2178 | <property name="enabled">1</property> | ||
| 2179 | <property name="fg"></property> | ||
| 2180 | <property name="font">Tahoma,90,90,10,74,0</property> | ||
| 2181 | <property name="hidden">0</property> | ||
| 2182 | <property name="id">wxID_ANY</property> | ||
| 2183 | <property name="label">version</property> | ||
| 2184 | <property name="maximum_size"></property> | ||
| 2185 | <property name="minimum_size"></property> | ||
| 2186 | <property name="name">m_staticTextVersion</property> | ||
| 2187 | <property name="permission">public</property> | ||
| 2188 | <property name="pos"></property> | ||
| 2189 | <property name="size"></property> | ||
| 2190 | <property name="style"></property> | ||
| 2191 | <property name="subclass"></property> | ||
| 2192 | <property name="tooltip"></property> | ||
| 2193 | <property name="window_extra_style"></property> | ||
| 2194 | <property name="window_name"></property> | ||
| 2195 | <property name="window_style"></property> | ||
| 2196 | <property name="wrap">-1</property> | ||
| 2197 | <event name="OnChar"></event> | ||
| 2198 | <event name="OnEnterWindow"></event> | ||
| 2199 | <event name="OnEraseBackground"></event> | ||
| 2200 | <event name="OnKeyDown"></event> | ||
| 2201 | <event name="OnKeyUp"></event> | ||
| 2202 | <event name="OnKillFocus"></event> | ||
| 2203 | <event name="OnLeaveWindow"></event> | ||
| 2204 | <event name="OnLeftDClick"></event> | ||
| 2205 | <event name="OnLeftDown"></event> | ||
| 2206 | <event name="OnLeftUp"></event> | ||
| 2207 | <event name="OnMiddleDClick"></event> | ||
| 2208 | <event name="OnMiddleDown"></event> | ||
| 2209 | <event name="OnMiddleUp"></event> | ||
| 2210 | <event name="OnMotion"></event> | ||
| 2211 | <event name="OnMouseEvents"></event> | ||
| 2212 | <event name="OnMouseWheel"></event> | ||
| 2213 | <event name="OnPaint"></event> | ||
| 2214 | <event name="OnRightDClick"></event> | ||
| 2215 | <event name="OnRightDown"></event> | ||
| 2216 | <event name="OnRightUp"></event> | ||
| 2217 | <event name="OnSetFocus"></event> | ||
| 2218 | <event name="OnSize"></event> | ||
| 2219 | <event name="OnUpdateUI"></event> | ||
| 2220 | </object> | ||
| 2221 | </object> | ||
| 2222 | </object> | ||
| 2223 | </object> | ||
| 2224 | <object class="sizeritem" expanded="1"> | ||
| 2225 | <property name="border">5</property> | ||
| 2226 | <property name="flag">wxEXPAND</property> | ||
| 2227 | <property name="proportion">0</property> | ||
| 2228 | <object class="spacer" expanded="1"> | ||
| 2229 | <property name="height">4</property> | ||
| 2230 | <property name="permission">protected</property> | ||
| 2231 | <property name="width">0</property> | ||
| 2232 | </object> | ||
| 2233 | </object> | ||
| 2234 | <object class="sizeritem" expanded="1"> | ||
| 2235 | <property name="border">5</property> | ||
| 2236 | <property name="flag">wxALL</property> | ||
| 2237 | <property name="proportion">0</property> | ||
| 2238 | <object class="wxStaticText" expanded="1"> | ||
| 2239 | <property name="bg"></property> | ||
| 2240 | <property name="context_help"></property> | ||
| 2241 | <property name="enabled">1</property> | ||
| 2242 | <property name="fg"></property> | ||
| 2243 | <property name="font"></property> | ||
| 2244 | <property name="hidden">0</property> | ||
| 2245 | <property name="id">wxID_ANY</property> | ||
| 2246 | <property name="label">Copyright © 2009 Satoshi Nakamoto.

This is experimental software. Do not rely on it for actual financial transactions.

Distributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php.

This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by Eric Young (eay@cryptsoft.com).</property> | ||
| 2247 | <property name="maximum_size"></property> | ||
| 2248 | <property name="minimum_size"></property> | ||
| 2249 | <property name="name">m_staticTextMain</property> | ||
| 2250 | <property name="permission">protected</property> | ||
| 2251 | <property name="pos"></property> | ||
| 2252 | <property name="size"></property> | ||
| 2253 | <property name="style"></property> | ||
| 2254 | <property name="subclass"></property> | ||
| 2255 | <property name="tooltip"></property> | ||
| 2256 | <property name="window_extra_style"></property> | ||
| 2257 | <property name="window_name"></property> | ||
| 2258 | <property name="window_style"></property> | ||
| 2259 | <property name="wrap">400</property> | ||
| 2260 | <event name="OnChar"></event> | ||
| 2261 | <event name="OnEnterWindow"></event> | ||
| 2262 | <event name="OnEraseBackground"></event> | ||
| 2263 | <event name="OnKeyDown"></event> | ||
| 2264 | <event name="OnKeyUp"></event> | ||
| 2265 | <event name="OnKillFocus"></event> | ||
| 2266 | <event name="OnLeaveWindow"></event> | ||
| 2267 | <event name="OnLeftDClick"></event> | ||
| 2268 | <event name="OnLeftDown"></event> | ||
| 2269 | <event name="OnLeftUp"></event> | ||
| 2270 | <event name="OnMiddleDClick"></event> | ||
| 2271 | <event name="OnMiddleDown"></event> | ||
| 2272 | <event name="OnMiddleUp"></event> | ||
| 2273 | <event name="OnMotion"></event> | ||
| 2274 | <event name="OnMouseEvents"></event> | ||
| 2275 | <event name="OnMouseWheel"></event> | ||
| 2276 | <event name="OnPaint"></event> | ||
| 2277 | <event name="OnRightDClick"></event> | ||
| 2278 | <event name="OnRightDown"></event> | ||
| 2279 | <event name="OnRightUp"></event> | ||
| 2280 | <event name="OnSetFocus"></event> | ||
| 2281 | <event name="OnSize"></event> | ||
| 2282 | <event name="OnUpdateUI"></event> | ||
| 2283 | </object> | ||
| 2284 | </object> | ||
| 2285 | <object class="sizeritem" expanded="1"> | ||
| 2286 | <property name="border">5</property> | ||
| 2287 | <property name="flag">wxEXPAND</property> | ||
| 2288 | <property name="proportion">1</property> | ||
| 2289 | <object class="spacer" expanded="1"> | ||
| 2290 | <property name="height">0</property> | ||
| 2291 | <property name="permission">protected</property> | ||
| 2292 | <property name="width">0</property> | ||
| 2293 | </object> | ||
| 2294 | </object> | ||
| 2295 | </object> | ||
| 2296 | </object> | ||
| 2297 | </object> | ||
| 2298 | </object> | ||
| 2299 | <object class="sizeritem" expanded="1"> | ||
| 2300 | <property name="border">5</property> | ||
| 2301 | <property name="flag">wxALIGN_RIGHT|wxEXPAND</property> | ||
| 2302 | <property name="proportion">0</property> | ||
| 2303 | <object class="wxBoxSizer" expanded="1"> | ||
| 2304 | <property name="minimum_size"></property> | ||
| 2305 | <property name="name">bSizer61</property> | ||
| 2306 | <property name="orient">wxHORIZONTAL</property> | ||
| 2307 | <property name="permission">none</property> | ||
| 2308 | <object class="sizeritem" expanded="1"> | ||
| 2309 | <property name="border">5</property> | ||
| 2310 | <property name="flag">wxEXPAND</property> | ||
| 2311 | <property name="proportion">1</property> | ||
| 2312 | <object class="spacer" expanded="1"> | ||
| 2313 | <property name="height">0</property> | ||
| 2314 | <property name="permission">protected</property> | ||
| 2315 | <property name="width">0</property> | ||
| 2316 | </object> | ||
| 2317 | </object> | ||
| 2318 | <object class="sizeritem" expanded="1"> | ||
| 2319 | <property name="border">5</property> | ||
| 2320 | <property name="flag">wxALL</property> | ||
| 2321 | <property name="proportion">0</property> | ||
| 2322 | <object class="wxButton" expanded="1"> | ||
| 2323 | <property name="bg"></property> | ||
| 2324 | <property name="context_help"></property> | ||
| 2325 | <property name="default">0</property> | ||
| 2326 | <property name="enabled">1</property> | ||
| 2327 | <property name="fg"></property> | ||
| 2328 | <property name="font"></property> | ||
| 2329 | <property name="hidden">0</property> | ||
| 2330 | <property name="id">wxID_OK</property> | ||
| 2331 | <property name="label">OK</property> | ||
| 2332 | <property name="maximum_size"></property> | ||
| 2333 | <property name="minimum_size"></property> | ||
| 2334 | <property name="name">m_buttonOK</property> | ||
| 2335 | <property name="permission">protected</property> | ||
| 2336 | <property name="pos"></property> | ||
| 2337 | <property name="size">85,25</property> | ||
| 2338 | <property name="style"></property> | ||
| 2339 | <property name="subclass"></property> | ||
| 2340 | <property name="tooltip"></property> | ||
| 2341 | <property name="window_extra_style"></property> | ||
| 2342 | <property name="window_name"></property> | ||
| 2343 | <property name="window_style"></property> | ||
| 2344 | <event name="OnButtonClick">OnButtonOK</event> | ||
| 2345 | <event name="OnChar"></event> | ||
| 2346 | <event name="OnEnterWindow"></event> | ||
| 2347 | <event name="OnEraseBackground"></event> | ||
| 2348 | <event name="OnKeyDown"></event> | ||
| 2349 | <event name="OnKeyUp"></event> | ||
| 2350 | <event name="OnKillFocus"></event> | ||
| 2351 | <event name="OnLeaveWindow"></event> | ||
| 2352 | <event name="OnLeftDClick"></event> | ||
| 2353 | <event name="OnLeftDown"></event> | ||
| 2354 | <event name="OnLeftUp"></event> | ||
| 2355 | <event name="OnMiddleDClick"></event> | ||
| 2356 | <event name="OnMiddleDown"></event> | ||
| 2357 | <event name="OnMiddleUp"></event> | ||
| 2358 | <event name="OnMotion"></event> | ||
| 2359 | <event name="OnMouseEvents"></event> | ||
| 2360 | <event name="OnMouseWheel"></event> | ||
| 2361 | <event name="OnPaint"></event> | ||
| 2362 | <event name="OnRightDClick"></event> | ||
| 2363 | <event name="OnRightDown"></event> | ||
| 2364 | <event name="OnRightUp"></event> | ||
| 2365 | <event name="OnSetFocus"></event> | ||
| 2366 | <event name="OnSize"></event> | ||
| 2367 | <event name="OnUpdateUI"></event> | ||
| 2368 | </object> | ||
| 2369 | </object> | ||
| 2370 | </object> | ||
| 2371 | </object> | ||
| 2372 | </object> | ||
| 2373 | </object> | ||
| 2374 | <object class="Dialog" expanded="0"> | ||
| 2375 | <property name="bg"></property> | ||
| 2376 | <property name="center"></property> | ||
| 2377 | <property name="context_help"></property> | ||
| 2378 | <property name="enabled">1</property> | ||
| 2379 | <property name="extra_style"></property> | ||
| 2380 | <property name="fg"></property> | ||
| 2381 | <property name="font"></property> | ||
| 2382 | <property name="hidden">0</property> | ||
| 2383 | <property name="id">wxID_ANY</property> | ||
| 2384 | <property name="maximum_size"></property> | ||
| 2385 | <property name="minimum_size"></property> | ||
| 2386 | <property name="name">CSendDialogBase</property> | ||
| 2387 | <property name="pos"></property> | ||
| 2388 | <property name="size">675,338</property> | ||
| 2389 | <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property> | ||
| 2390 | <property name="subclass"></property> | ||
| 2391 | <property name="title">Send Coins</property> | ||
| 2392 | <property name="tooltip"></property> | ||
| 2393 | <property name="window_extra_style"></property> | ||
| 2394 | <property name="window_name"></property> | ||
| 2395 | <property name="window_style"></property> | ||
| 2396 | <event name="OnActivate"></event> | ||
| 2397 | <event name="OnActivateApp"></event> | ||
| 2398 | <event name="OnChar"></event> | ||
| 2399 | <event name="OnClose"></event> | ||
| 2400 | <event name="OnEnterWindow"></event> | ||
| 2401 | <event name="OnEraseBackground"></event> | ||
| 2402 | <event name="OnHibernate"></event> | ||
| 2403 | <event name="OnIconize"></event> | ||
| 2404 | <event name="OnIdle"></event> | ||
| 2405 | <event name="OnInitDialog"></event> | ||
| 2406 | <event name="OnKeyDown"></event> | ||
| 2407 | <event name="OnKeyUp"></event> | ||
| 2408 | <event name="OnKillFocus"></event> | ||
| 2409 | <event name="OnLeaveWindow"></event> | ||
| 2410 | <event name="OnLeftDClick"></event> | ||
| 2411 | <event name="OnLeftDown"></event> | ||
| 2412 | <event name="OnLeftUp"></event> | ||
| 2413 | <event name="OnMiddleDClick"></event> | ||
| 2414 | <event name="OnMiddleDown"></event> | ||
| 2415 | <event name="OnMiddleUp"></event> | ||
| 2416 | <event name="OnMotion"></event> | ||
| 2417 | <event name="OnMouseEvents"></event> | ||
| 2418 | <event name="OnMouseWheel"></event> | ||
| 2419 | <event name="OnPaint"></event> | ||
| 2420 | <event name="OnRightDClick"></event> | ||
| 2421 | <event name="OnRightDown"></event> | ||
| 2422 | <event name="OnRightUp"></event> | ||
| 2423 | <event name="OnSetFocus"></event> | ||
| 2424 | <event name="OnSize"></event> | ||
| 2425 | <event name="OnUpdateUI"></event> | ||
| 2426 | <object class="wxBoxSizer" expanded="1"> | ||
| 2427 | <property name="minimum_size"></property> | ||
| 2428 | <property name="name">bSizer21</property> | ||
| 2429 | <property name="orient">wxVERTICAL</property> | ||
| 2430 | <property name="permission">none</property> | ||
| 2431 | <object class="sizeritem" expanded="1"> | ||
| 2432 | <property name="border">5</property> | ||
| 2433 | <property name="flag">wxEXPAND</property> | ||
| 2434 | <property name="proportion">0</property> | ||
| 2435 | <object class="spacer" expanded="1"> | ||
| 2436 | <property name="height">5</property> | ||
| 2437 | <property name="permission">protected</property> | ||
| 2438 | <property name="width">0</property> | ||
| 2439 | </object> | ||
| 2440 | </object> | ||
| 2441 | <object class="sizeritem" expanded="1"> | ||
| 2442 | <property name="border">5</property> | ||
| 2443 | <property name="flag">wxEXPAND|wxLEFT</property> | ||
| 2444 | <property name="proportion">0</property> | ||
| 2445 | <object class="wxFlexGridSizer" expanded="0"> | ||
| 2446 | <property name="cols">2</property> | ||
| 2447 | <property name="flexible_direction">wxBOTH</property> | ||
| 2448 | <property name="growablecols">1</property> | ||
| 2449 | <property name="growablerows"></property> | ||
| 2450 | <property name="hgap">0</property> | ||
| 2451 | <property name="minimum_size"></property> | ||
| 2452 | <property name="name">fgSizer1</property> | ||
| 2453 | <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property> | ||
| 2454 | <property name="permission">none</property> | ||
| 2455 | <property name="rows">3</property> | ||
| 2456 | <property name="vgap">0</property> | ||
| 2457 | <object class="sizeritem" expanded="1"> | ||
| 2458 | <property name="border">5</property> | ||
| 2459 | <property name="flag">wxEXPAND</property> | ||
| 2460 | <property name="proportion">0</property> | ||
| 2461 | <object class="spacer" expanded="1"> | ||
| 2462 | <property name="height">0</property> | ||
| 2463 | <property name="permission">protected</property> | ||
| 2464 | <property name="width">0</property> | ||
| 2465 | </object> | ||
| 2466 | </object> | ||
| 2467 | <object class="sizeritem" expanded="1"> | ||
| 2468 | <property name="border">5</property> | ||
| 2469 | <property name="flag">wxTOP|wxRIGHT|wxLEFT</property> | ||
| 2470 | <property name="proportion">0</property> | ||
| 2471 | <object class="wxStaticText" expanded="1"> | ||
| 2472 | <property name="bg"></property> | ||
| 2473 | <property name="context_help"></property> | ||
| 2474 | <property name="enabled">1</property> | ||
| 2475 | <property name="fg"></property> | ||
| 2476 | <property name="font"></property> | ||
| 2477 | <property name="hidden">0</property> | ||
| 2478 | <property name="id">wxID_ANY</property> | ||
| 2479 | <property name="label">Enter the recipient's IP address (e.g. 123.45.6.7) for online transfer with comments and confirmation, 
or bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJED9L) if recipient is not online.</property> | ||
| 2480 | <property name="maximum_size"></property> | ||
| 2481 | <property name="minimum_size"></property> | ||
| 2482 | <property name="name">m_staticText14</property> | ||
| 2483 | <property name="permission">protected</property> | ||
| 2484 | <property name="pos"></property> | ||
| 2485 | <property name="size"></property> | ||
| 2486 | <property name="style"></property> | ||
| 2487 | <property name="subclass"></property> | ||
| 2488 | <property name="tooltip"></property> | ||
| 2489 | <property name="window_extra_style"></property> | ||
| 2490 | <property name="window_name"></property> | ||
| 2491 | <property name="window_style"></property> | ||
| 2492 | <property name="wrap">-1</property> | ||
| 2493 | <event name="OnChar"></event> | ||
| 2494 | <event name="OnEnterWindow"></event> | ||
| 2495 | <event name="OnEraseBackground"></event> | ||
| 2496 | <event name="OnKeyDown"></event> | ||
| 2497 | <event name="OnKeyUp"></event> | ||
| 2498 | <event name="OnKillFocus"></event> | ||
| 2499 | <event name="OnLeaveWindow"></event> | ||
| 2500 | <event name="OnLeftDClick"></event> | ||
| 2501 | <event name="OnLeftDown"></event> | ||
| 2502 | <event name="OnLeftUp"></event> | ||
| 2503 | <event name="OnMiddleDClick"></event> | ||
| 2504 | <event name="OnMiddleDown"></event> | ||
| 2505 | <event name="OnMiddleUp"></event> | ||
| 2506 | <event name="OnMotion"></event> | ||
| 2507 | <event name="OnMouseEvents"></event> | ||
| 2508 | <event name="OnMouseWheel"></event> | ||
| 2509 | <event name="OnPaint"></event> | ||
| 2510 | <event name="OnRightDClick"></event> | ||
| 2511 | <event name="OnRightDown"></event> | ||
| 2512 | <event name="OnRightUp"></event> | ||
| 2513 | <event name="OnSetFocus"></event> | ||
| 2514 | <event name="OnSize"></event> | ||
| 2515 | <event name="OnUpdateUI"></event> | ||
| 2516 | </object> | ||
| 2517 | </object> | ||
| 2518 | <object class="sizeritem" expanded="1"> | ||
| 2519 | <property name="border">5</property> | ||
| 2520 | <property name="flag">wxEXPAND|wxLEFT</property> | ||
| 2521 | <property name="proportion">1</property> | ||
| 2522 | <object class="wxBoxSizer" expanded="1"> | ||
| 2523 | <property name="minimum_size">70,-1</property> | ||
| 2524 | <property name="name">bSizer47</property> | ||
| 2525 | <property name="orient">wxHORIZONTAL</property> | ||
| 2526 | <property name="permission">none</property> | ||
| 2527 | <object class="sizeritem" expanded="1"> | ||
| 2528 | <property name="border">5</property> | ||
| 2529 | <property name="flag">wxEXPAND</property> | ||
| 2530 | <property name="proportion">1</property> | ||
| 2531 | <object class="spacer" expanded="1"> | ||
| 2532 | <property name="height">0</property> | ||
| 2533 | <property name="permission">protected</property> | ||
| 2534 | <property name="width">0</property> | ||
| 2535 | </object> | ||
| 2536 | </object> | ||
| 2537 | <object class="sizeritem" expanded="1"> | ||
| 2538 | <property name="border">5</property> | ||
| 2539 | <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property> | ||
| 2540 | <property name="proportion">0</property> | ||
| 2541 | <object class="wxStaticBitmap" expanded="1"> | ||
| 2542 | <property name="bg"></property> | ||
| 2543 | <property name="bitmap">check; Load From Icon Resource [-1; -1]</property> | ||
| 2544 | <property name="context_help"></property> | ||
| 2545 | <property name="enabled">1</property> | ||
| 2546 | <property name="fg"></property> | ||
| 2547 | <property name="font"></property> | ||
| 2548 | <property name="hidden">0</property> | ||
| 2549 | <property name="id">wxID_ANY</property> | ||
| 2550 | <property name="maximum_size"></property> | ||
| 2551 | <property name="minimum_size"></property> | ||
| 2552 | <property name="name">m_bitmapCheckMark</property> | ||
| 2553 | <property name="permission">protected</property> | ||
| 2554 | <property name="pos"></property> | ||
| 2555 | <property name="size">16,16</property> | ||
| 2556 | <property name="subclass"></property> | ||
| 2557 | <property name="tooltip"></property> | ||
| 2558 | <property name="window_extra_style"></property> | ||
| 2559 | <property name="window_name"></property> | ||
| 2560 | <property name="window_style"></property> | ||
| 2561 | <event name="OnChar"></event> | ||
| 2562 | <event name="OnEnterWindow"></event> | ||
| 2563 | <event name="OnEraseBackground"></event> | ||
| 2564 | <event name="OnKeyDown"></event> | ||
| 2565 | <event name="OnKeyUp"></event> | ||
| 2566 | <event name="OnKillFocus"></event> | ||
| 2567 | <event name="OnLeaveWindow"></event> | ||
| 2568 | <event name="OnLeftDClick"></event> | ||
| 2569 | <event name="OnLeftDown"></event> | ||
| 2570 | <event name="OnLeftUp"></event> | ||
| 2571 | <event name="OnMiddleDClick"></event> | ||
| 2572 | <event name="OnMiddleDown"></event> | ||
| 2573 | <event name="OnMiddleUp"></event> | ||
| 2574 | <event name="OnMotion"></event> | ||
| 2575 | <event name="OnMouseEvents"></event> | ||
| 2576 | <event name="OnMouseWheel"></event> | ||
| 2577 | <event name="OnPaint"></event> | ||
| 2578 | <event name="OnRightDClick"></event> | ||
| 2579 | <event name="OnRightDown"></event> | ||
| 2580 | <event name="OnRightUp"></event> | ||
| 2581 | <event name="OnSetFocus"></event> | ||
| 2582 | <event name="OnSize"></event> | ||
| 2583 | <event name="OnUpdateUI"></event> | ||
| 2584 | </object> | ||
| 2585 | </object> | ||
| 2586 | <object class="sizeritem" expanded="1"> | ||
| 2587 | <property name="border">5</property> | ||
| 2588 | <property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT</property> | ||
| 2589 | <property name="proportion">0</property> | ||
| 2590 | <object class="wxStaticText" expanded="1"> | ||
| 2591 | <property name="bg"></property> | ||
| 2592 | <property name="context_help"></property> | ||
| 2593 | <property name="enabled">1</property> | ||
| 2594 | <property name="fg"></property> | ||
| 2595 | <property name="font"></property> | ||
| 2596 | <property name="hidden">0</property> | ||
| 2597 | <property name="id">wxID_ANY</property> | ||
| 2598 | <property name="label">Pay &To:</property> | ||
| 2599 | <property name="maximum_size"></property> | ||
| 2600 | <property name="minimum_size"></property> | ||
| 2601 | <property name="name">m_staticText36</property> | ||
| 2602 | <property name="permission">protected</property> | ||
| 2603 | <property name="pos"></property> | ||
| 2604 | <property name="size">-1,-1</property> | ||
| 2605 | <property name="style">wxALIGN_RIGHT</property> | ||
| 2606 | <property name="subclass"></property> | ||
| 2607 | <property name="tooltip"></property> | ||
| 2608 | <property name="window_extra_style"></property> | ||
| 2609 | <property name="window_name"></property> | ||
| 2610 | <property name="window_style"></property> | ||
| 2611 | <property name="wrap">-1</property> | ||
| 2612 | <event name="OnChar"></event> | ||
| 2613 | <event name="OnEnterWindow"></event> | ||
| 2614 | <event name="OnEraseBackground"></event> | ||
| 2615 | <event name="OnKeyDown"></event> | ||
| 2616 | <event name="OnKeyUp"></event> | ||
| 2617 | <event name="OnKillFocus"></event> | ||
| 2618 | <event name="OnLeaveWindow"></event> | ||
| 2619 | <event name="OnLeftDClick"></event> | ||
| 2620 | <event name="OnLeftDown"></event> | ||
| 2621 | <event name="OnLeftUp"></event> | ||
| 2622 | <event name="OnMiddleDClick"></event> | ||
| 2623 | <event name="OnMiddleDown"></event> | ||
| 2624 | <event name="OnMiddleUp"></event> | ||
| 2625 | <event name="OnMotion"></event> | ||
| 2626 | <event name="OnMouseEvents"></event> | ||
| 2627 | <event name="OnMouseWheel"></event> | ||
| 2628 | <event name="OnPaint"></event> | ||
| 2629 | <event name="OnRightDClick"></event> | ||
| 2630 | <event name="OnRightDown"></event> | ||
| 2631 | <event name="OnRightUp"></event> | ||
| 2632 | <event name="OnSetFocus"></event> | ||
| 2633 | <event name="OnSize"></event> | ||
| 2634 | <event name="OnUpdateUI"></event> | ||
| 2635 | </object> | ||
| 2636 | </object> | ||
| 2637 | </object> | ||
| 2638 | </object> | ||
| 2639 | <object class="sizeritem" expanded="1"> | ||
| 2640 | <property name="border">5</property> | ||
| 2641 | <property name="flag">wxEXPAND|wxRIGHT</property> | ||
| 2642 | <property name="proportion">1</property> | ||
| 2643 | <object class="wxBoxSizer" expanded="1"> | ||
| 2644 | <property name="minimum_size"></property> | ||
| 2645 | <property name="name">bSizer19</property> | ||
| 2646 | <property name="orient">wxHORIZONTAL</property> | ||
| 2647 | <property name="permission">none</property> | ||
| 2648 | <object class="sizeritem" expanded="1"> | ||
| 2649 | <property name="border">5</property> | ||
| 2650 | <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property> | ||
| 2651 | <property name="proportion">1</property> | ||
| 2652 | <object class="wxTextCtrl" expanded="1"> | ||
| 2653 | <property name="bg"></property> | ||
| 2654 | <property name="context_help"></property> | ||
| 2655 | <property name="enabled">1</property> | ||
| 2656 | <property name="fg"></property> | ||
| 2657 | <property name="font"></property> | ||
| 2658 | <property name="hidden">0</property> | ||
| 2659 | <property name="id">wxID_TEXTCTRLPAYTO</property> | ||
| 2660 | <property name="maximum_size"></property> | ||
| 2661 | <property name="maxlength">0</property> | ||
| 2662 | <property name="minimum_size"></property> | ||
| 2663 | <property name="name">m_textCtrlAddress</property> | ||
| 2664 | <property name="permission">protected</property> | ||
| 2665 | <property name="pos"></property> | ||
| 2666 | <property name="size"></property> | ||
| 2667 | <property name="style"></property> | ||
| 2668 | <property name="subclass"></property> | ||
| 2669 | <property name="tooltip"></property> | ||
| 2670 | <property name="value"></property> | ||
| 2671 | <property name="window_extra_style"></property> | ||
| 2672 | <property name="window_name"></property> | ||
| 2673 | <property name="window_style"></property> | ||
| 2674 | <event name="OnChar"></event> | ||
| 2675 | <event name="OnEnterWindow"></event> | ||
| 2676 | <event name="OnEraseBackground"></event> | ||
| 2677 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 2678 | <event name="OnKeyUp"></event> | ||
| 2679 | <event name="OnKillFocus"></event> | ||
| 2680 | <event name="OnLeaveWindow"></event> | ||
| 2681 | <event name="OnLeftDClick"></event> | ||
| 2682 | <event name="OnLeftDown"></event> | ||
| 2683 | <event name="OnLeftUp"></event> | ||
| 2684 | <event name="OnMiddleDClick"></event> | ||
| 2685 | <event name="OnMiddleDown"></event> | ||
| 2686 | <event name="OnMiddleUp"></event> | ||
| 2687 | <event name="OnMotion"></event> | ||
| 2688 | <event name="OnMouseEvents"></event> | ||
| 2689 | <event name="OnMouseWheel"></event> | ||
| 2690 | <event name="OnPaint"></event> | ||
| 2691 | <event name="OnRightDClick"></event> | ||
| 2692 | <event name="OnRightDown"></event> | ||
| 2693 | <event name="OnRightUp"></event> | ||
| 2694 | <event name="OnSetFocus"></event> | ||
| 2695 | <event name="OnSize"></event> | ||
| 2696 | <event name="OnText">OnTextAddress</event> | ||
| 2697 | <event name="OnTextEnter"></event> | ||
| 2698 | <event name="OnTextMaxLen"></event> | ||
| 2699 | <event name="OnTextURL"></event> | ||
| 2700 | <event name="OnUpdateUI"></event> | ||
| 2701 | </object> | ||
| 2702 | </object> | ||
| 2703 | <object class="sizeritem" expanded="1"> | ||
| 2704 | <property name="border">5</property> | ||
| 2705 | <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT</property> | ||
| 2706 | <property name="proportion">0</property> | ||
| 2707 | <object class="wxButton" expanded="1"> | ||
| 2708 | <property name="bg"></property> | ||
| 2709 | <property name="context_help"></property> | ||
| 2710 | <property name="default">0</property> | ||
| 2711 | <property name="enabled">1</property> | ||
| 2712 | <property name="fg"></property> | ||
| 2713 | <property name="font"></property> | ||
| 2714 | <property name="hidden">0</property> | ||
| 2715 | <property name="id">wxID_BUTTONPASTE</property> | ||
| 2716 | <property name="label">&Paste</property> | ||
| 2717 | <property name="maximum_size"></property> | ||
| 2718 | <property name="minimum_size"></property> | ||
| 2719 | <property name="name">m_buttonPaste</property> | ||
| 2720 | <property name="permission">protected</property> | ||
| 2721 | <property name="pos"></property> | ||
| 2722 | <property name="size">-1,-1</property> | ||
| 2723 | <property name="style">wxBU_EXACTFIT</property> | ||
| 2724 | <property name="subclass"></property> | ||
| 2725 | <property name="tooltip"></property> | ||
| 2726 | <property name="window_extra_style"></property> | ||
| 2727 | <property name="window_name"></property> | ||
| 2728 | <property name="window_style"></property> | ||
| 2729 | <event name="OnButtonClick">OnButtonPaste</event> | ||
| 2730 | <event name="OnChar"></event> | ||
| 2731 | <event name="OnEnterWindow"></event> | ||
| 2732 | <event name="OnEraseBackground"></event> | ||
| 2733 | <event name="OnKeyDown"></event> | ||
| 2734 | <event name="OnKeyUp"></event> | ||
| 2735 | <event name="OnKillFocus"></event> | ||
| 2736 | <event name="OnLeaveWindow"></event> | ||
| 2737 | <event name="OnLeftDClick"></event> | ||
| 2738 | <event name="OnLeftDown"></event> | ||
| 2739 | <event name="OnLeftUp"></event> | ||
| 2740 | <event name="OnMiddleDClick"></event> | ||
| 2741 | <event name="OnMiddleDown"></event> | ||
| 2742 | <event name="OnMiddleUp"></event> | ||
| 2743 | <event name="OnMotion"></event> | ||
| 2744 | <event name="OnMouseEvents"></event> | ||
| 2745 | <event name="OnMouseWheel"></event> | ||
| 2746 | <event name="OnPaint"></event> | ||
| 2747 | <event name="OnRightDClick"></event> | ||
| 2748 | <event name="OnRightDown"></event> | ||
| 2749 | <event name="OnRightUp"></event> | ||
| 2750 | <event name="OnSetFocus"></event> | ||
| 2751 | <event name="OnSize"></event> | ||
| 2752 | <event name="OnUpdateUI"></event> | ||
| 2753 | </object> | ||
| 2754 | </object> | ||
| 2755 | <object class="sizeritem" expanded="1"> | ||
| 2756 | <property name="border">5</property> | ||
| 2757 | <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT</property> | ||
| 2758 | <property name="proportion">0</property> | ||
| 2759 | <object class="wxButton" expanded="1"> | ||
| 2760 | <property name="bg"></property> | ||
| 2761 | <property name="context_help"></property> | ||
| 2762 | <property name="default">0</property> | ||
| 2763 | <property name="enabled">1</property> | ||
| 2764 | <property name="fg"></property> | ||
| 2765 | <property name="font"></property> | ||
| 2766 | <property name="hidden">0</property> | ||
| 2767 | <property name="id">wxID_BUTTONADDRESSBOOK</property> | ||
| 2768 | <property name="label"> Address &Book...</property> | ||
| 2769 | <property name="maximum_size"></property> | ||
| 2770 | <property name="minimum_size"></property> | ||
| 2771 | <property name="name">m_buttonAddress</property> | ||
| 2772 | <property name="permission">protected</property> | ||
| 2773 | <property name="pos"></property> | ||
| 2774 | <property name="size"></property> | ||
| 2775 | <property name="style"></property> | ||
| 2776 | <property name="subclass"></property> | ||
| 2777 | <property name="tooltip"></property> | ||
| 2778 | <property name="window_extra_style"></property> | ||
| 2779 | <property name="window_name"></property> | ||
| 2780 | <property name="window_style"></property> | ||
| 2781 | <event name="OnButtonClick">OnButtonAddressBook</event> | ||
| 2782 | <event name="OnChar"></event> | ||
| 2783 | <event name="OnEnterWindow"></event> | ||
| 2784 | <event name="OnEraseBackground"></event> | ||
| 2785 | <event name="OnKeyDown"></event> | ||
| 2786 | <event name="OnKeyUp"></event> | ||
| 2787 | <event name="OnKillFocus"></event> | ||
| 2788 | <event name="OnLeaveWindow"></event> | ||
| 2789 | <event name="OnLeftDClick"></event> | ||
| 2790 | <event name="OnLeftDown"></event> | ||
| 2791 | <event name="OnLeftUp"></event> | ||
| 2792 | <event name="OnMiddleDClick"></event> | ||
| 2793 | <event name="OnMiddleDown"></event> | ||
| 2794 | <event name="OnMiddleUp"></event> | ||
| 2795 | <event name="OnMotion"></event> | ||
| 2796 | <event name="OnMouseEvents"></event> | ||
| 2797 | <event name="OnMouseWheel"></event> | ||
| 2798 | <event name="OnPaint"></event> | ||
| 2799 | <event name="OnRightDClick"></event> | ||
| 2800 | <event name="OnRightDown"></event> | ||
| 2801 | <event name="OnRightUp"></event> | ||
| 2802 | <event name="OnSetFocus"></event> | ||
| 2803 | <event name="OnSize"></event> | ||
| 2804 | <event name="OnUpdateUI"></event> | ||
| 2805 | </object> | ||
| 2806 | </object> | ||
| 2807 | </object> | ||
| 2808 | </object> | ||
| 2809 | <object class="sizeritem" expanded="1"> | ||
| 2810 | <property name="border">5</property> | ||
| 2811 | <property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT|wxALIGN_RIGHT</property> | ||
| 2812 | <property name="proportion">0</property> | ||
| 2813 | <object class="wxStaticText" expanded="1"> | ||
| 2814 | <property name="bg"></property> | ||
| 2815 | <property name="context_help"></property> | ||
| 2816 | <property name="enabled">1</property> | ||
| 2817 | <property name="fg"></property> | ||
| 2818 | <property name="font"></property> | ||
| 2819 | <property name="hidden">0</property> | ||
| 2820 | <property name="id">wxID_ANY</property> | ||
| 2821 | <property name="label">&Amount:</property> | ||
| 2822 | <property name="maximum_size"></property> | ||
| 2823 | <property name="minimum_size"></property> | ||
| 2824 | <property name="name">m_staticText19</property> | ||
| 2825 | <property name="permission">protected</property> | ||
| 2826 | <property name="pos"></property> | ||
| 2827 | <property name="size">-1,-1</property> | ||
| 2828 | <property name="style">wxALIGN_RIGHT</property> | ||
| 2829 | <property name="subclass"></property> | ||
| 2830 | <property name="tooltip"></property> | ||
| 2831 | <property name="window_extra_style"></property> | ||
| 2832 | <property name="window_name"></property> | ||
| 2833 | <property name="window_style"></property> | ||
| 2834 | <property name="wrap">-1</property> | ||
| 2835 | <event name="OnChar"></event> | ||
| 2836 | <event name="OnEnterWindow"></event> | ||
| 2837 | <event name="OnEraseBackground"></event> | ||
| 2838 | <event name="OnKeyDown"></event> | ||
| 2839 | <event name="OnKeyUp"></event> | ||
| 2840 | <event name="OnKillFocus"></event> | ||
| 2841 | <event name="OnLeaveWindow"></event> | ||
| 2842 | <event name="OnLeftDClick"></event> | ||
| 2843 | <event name="OnLeftDown"></event> | ||
| 2844 | <event name="OnLeftUp"></event> | ||
| 2845 | <event name="OnMiddleDClick"></event> | ||
| 2846 | <event name="OnMiddleDown"></event> | ||
| 2847 | <event name="OnMiddleUp"></event> | ||
| 2848 | <event name="OnMotion"></event> | ||
| 2849 | <event name="OnMouseEvents"></event> | ||
| 2850 | <event name="OnMouseWheel"></event> | ||
| 2851 | <event name="OnPaint"></event> | ||
| 2852 | <event name="OnRightDClick"></event> | ||
| 2853 | <event name="OnRightDown"></event> | ||
| 2854 | <event name="OnRightUp"></event> | ||
| 2855 | <event name="OnSetFocus"></event> | ||
| 2856 | <event name="OnSize"></event> | ||
| 2857 | <event name="OnUpdateUI"></event> | ||
| 2858 | </object> | ||
| 2859 | </object> | ||
| 2860 | <object class="sizeritem" expanded="1"> | ||
| 2861 | <property name="border">5</property> | ||
| 2862 | <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property> | ||
| 2863 | <property name="proportion">0</property> | ||
| 2864 | <object class="wxTextCtrl" expanded="1"> | ||
| 2865 | <property name="bg"></property> | ||
| 2866 | <property name="context_help"></property> | ||
| 2867 | <property name="enabled">1</property> | ||
| 2868 | <property name="fg"></property> | ||
| 2869 | <property name="font">,90,90,-1,70,0</property> | ||
| 2870 | <property name="hidden">0</property> | ||
| 2871 | <property name="id">wxID_TEXTCTRLAMOUNT</property> | ||
| 2872 | <property name="maximum_size"></property> | ||
| 2873 | <property name="maxlength">20</property> | ||
| 2874 | <property name="minimum_size"></property> | ||
| 2875 | <property name="name">m_textCtrlAmount</property> | ||
| 2876 | <property name="permission">protected</property> | ||
| 2877 | <property name="pos"></property> | ||
| 2878 | <property name="size">145,-1</property> | ||
| 2879 | <property name="style"></property> | ||
| 2880 | <property name="subclass"></property> | ||
| 2881 | <property name="tooltip"></property> | ||
| 2882 | <property name="value"></property> | ||
| 2883 | <property name="window_extra_style"></property> | ||
| 2884 | <property name="window_name"></property> | ||
| 2885 | <property name="window_style"></property> | ||
| 2886 | <event name="OnChar"></event> | ||
| 2887 | <event name="OnEnterWindow"></event> | ||
| 2888 | <event name="OnEraseBackground"></event> | ||
| 2889 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 2890 | <event name="OnKeyUp"></event> | ||
| 2891 | <event name="OnKillFocus">OnKillFocusAmount</event> | ||
| 2892 | <event name="OnLeaveWindow"></event> | ||
| 2893 | <event name="OnLeftDClick"></event> | ||
| 2894 | <event name="OnLeftDown"></event> | ||
| 2895 | <event name="OnLeftUp"></event> | ||
| 2896 | <event name="OnMiddleDClick"></event> | ||
| 2897 | <event name="OnMiddleDown"></event> | ||
| 2898 | <event name="OnMiddleUp"></event> | ||
| 2899 | <event name="OnMotion"></event> | ||
| 2900 | <event name="OnMouseEvents"></event> | ||
| 2901 | <event name="OnMouseWheel"></event> | ||
| 2902 | <event name="OnPaint"></event> | ||
| 2903 | <event name="OnRightDClick"></event> | ||
| 2904 | <event name="OnRightDown"></event> | ||
| 2905 | <event name="OnRightUp"></event> | ||
| 2906 | <event name="OnSetFocus"></event> | ||
| 2907 | <event name="OnSize"></event> | ||
| 2908 | <event name="OnText"></event> | ||
| 2909 | <event name="OnTextEnter"></event> | ||
| 2910 | <event name="OnTextMaxLen"></event> | ||
| 2911 | <event name="OnTextURL"></event> | ||
| 2912 | <event name="OnUpdateUI"></event> | ||
| 2913 | </object> | ||
| 2914 | </object> | ||
| 2915 | <object class="sizeritem" expanded="1"> | ||
| 2916 | <property name="border">5</property> | ||
| 2917 | <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT</property> | ||
| 2918 | <property name="proportion">0</property> | ||
| 2919 | <object class="wxStaticText" expanded="1"> | ||
| 2920 | <property name="bg"></property> | ||
| 2921 | <property name="context_help"></property> | ||
| 2922 | <property name="enabled">1</property> | ||
| 2923 | <property name="fg"></property> | ||
| 2924 | <property name="font"></property> | ||
| 2925 | <property name="hidden">0</property> | ||
| 2926 | <property name="id">wxID_ANY</property> | ||
| 2927 | <property name="label">T&ransfer:</property> | ||
| 2928 | <property name="maximum_size"></property> | ||
| 2929 | <property name="minimum_size"></property> | ||
| 2930 | <property name="name">m_staticText20</property> | ||
| 2931 | <property name="permission">protected</property> | ||
| 2932 | <property name="pos"></property> | ||
| 2933 | <property name="size">-1,-1</property> | ||
| 2934 | <property name="style">wxALIGN_RIGHT</property> | ||
| 2935 | <property name="subclass"></property> | ||
| 2936 | <property name="tooltip"></property> | ||
| 2937 | <property name="window_extra_style"></property> | ||
| 2938 | <property name="window_name"></property> | ||
| 2939 | <property name="window_style"></property> | ||
| 2940 | <property name="wrap">-1</property> | ||
| 2941 | <event name="OnChar"></event> | ||
| 2942 | <event name="OnEnterWindow"></event> | ||
| 2943 | <event name="OnEraseBackground"></event> | ||
| 2944 | <event name="OnKeyDown"></event> | ||
| 2945 | <event name="OnKeyUp"></event> | ||
| 2946 | <event name="OnKillFocus"></event> | ||
| 2947 | <event name="OnLeaveWindow"></event> | ||
| 2948 | <event name="OnLeftDClick"></event> | ||
| 2949 | <event name="OnLeftDown"></event> | ||
| 2950 | <event name="OnLeftUp"></event> | ||
| 2951 | <event name="OnMiddleDClick"></event> | ||
| 2952 | <event name="OnMiddleDown"></event> | ||
| 2953 | <event name="OnMiddleUp"></event> | ||
| 2954 | <event name="OnMotion"></event> | ||
| 2955 | <event name="OnMouseEvents"></event> | ||
| 2956 | <event name="OnMouseWheel"></event> | ||
| 2957 | <event name="OnPaint"></event> | ||
| 2958 | <event name="OnRightDClick"></event> | ||
| 2959 | <event name="OnRightDown"></event> | ||
| 2960 | <event name="OnRightUp"></event> | ||
| 2961 | <event name="OnSetFocus"></event> | ||
| 2962 | <event name="OnSize"></event> | ||
| 2963 | <event name="OnUpdateUI"></event> | ||
| 2964 | </object> | ||
| 2965 | </object> | ||
| 2966 | <object class="sizeritem" expanded="1"> | ||
| 2967 | <property name="border">5</property> | ||
| 2968 | <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property> | ||
| 2969 | <property name="proportion">0</property> | ||
| 2970 | <object class="wxChoice" expanded="1"> | ||
| 2971 | <property name="bg"></property> | ||
| 2972 | <property name="choices">" Standard"</property> | ||
| 2973 | <property name="context_help"></property> | ||
| 2974 | <property name="enabled">1</property> | ||
| 2975 | <property name="fg"></property> | ||
| 2976 | <property name="font"></property> | ||
| 2977 | <property name="hidden">0</property> | ||
| 2978 | <property name="id">wxID_CHOICETRANSFERTYPE</property> | ||
| 2979 | <property name="maximum_size"></property> | ||
| 2980 | <property name="minimum_size"></property> | ||
| 2981 | <property name="name">m_choiceTransferType</property> | ||
| 2982 | <property name="permission">protected</property> | ||
| 2983 | <property name="pos"></property> | ||
| 2984 | <property name="selection">0</property> | ||
| 2985 | <property name="size"></property> | ||
| 2986 | <property name="subclass"></property> | ||
| 2987 | <property name="tooltip"></property> | ||
| 2988 | <property name="window_extra_style"></property> | ||
| 2989 | <property name="window_name"></property> | ||
| 2990 | <property name="window_style"></property> | ||
| 2991 | <event name="OnChar"></event> | ||
| 2992 | <event name="OnChoice"></event> | ||
| 2993 | <event name="OnEnterWindow"></event> | ||
| 2994 | <event name="OnEraseBackground"></event> | ||
| 2995 | <event name="OnKeyDown"></event> | ||
| 2996 | <event name="OnKeyUp"></event> | ||
| 2997 | <event name="OnKillFocus"></event> | ||
| 2998 | <event name="OnLeaveWindow"></event> | ||
| 2999 | <event name="OnLeftDClick"></event> | ||
| 3000 | <event name="OnLeftDown"></event> | ||
| 3001 | <event name="OnLeftUp"></event> | ||
| 3002 | <event name="OnMiddleDClick"></event> | ||
| 3003 | <event name="OnMiddleDown"></event> | ||
| 3004 | <event name="OnMiddleUp"></event> | ||
| 3005 | <event name="OnMotion"></event> | ||
| 3006 | <event name="OnMouseEvents"></event> | ||
| 3007 | <event name="OnMouseWheel"></event> | ||
| 3008 | <event name="OnPaint"></event> | ||
| 3009 | <event name="OnRightDClick"></event> | ||
| 3010 | <event name="OnRightDown"></event> | ||
| 3011 | <event name="OnRightUp"></event> | ||
| 3012 | <event name="OnSetFocus"></event> | ||
| 3013 | <event name="OnSize"></event> | ||
| 3014 | <event name="OnUpdateUI"></event> | ||
| 3015 | </object> | ||
| 3016 | </object> | ||
| 3017 | </object> | ||
| 3018 | </object> | ||
| 3019 | <object class="sizeritem" expanded="1"> | ||
| 3020 | <property name="border">5</property> | ||
| 3021 | <property name="flag">wxEXPAND</property> | ||
| 3022 | <property name="proportion">0</property> | ||
| 3023 | <object class="wxBoxSizer" expanded="1"> | ||
| 3024 | <property name="minimum_size"></property> | ||
| 3025 | <property name="name">bSizer672</property> | ||
| 3026 | <property name="orient">wxHORIZONTAL</property> | ||
| 3027 | <property name="permission">none</property> | ||
| 3028 | <object class="sizeritem" expanded="1"> | ||
| 3029 | <property name="border">5</property> | ||
| 3030 | <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property> | ||
| 3031 | <property name="proportion">1</property> | ||
| 3032 | <object class="wxBoxSizer" expanded="1"> | ||
| 3033 | <property name="minimum_size"></property> | ||
| 3034 | <property name="name">bSizer681</property> | ||
| 3035 | <property name="orient">wxVERTICAL</property> | ||
| 3036 | <property name="permission">none</property> | ||
| 3037 | <object class="sizeritem" expanded="1"> | ||
| 3038 | <property name="border">5</property> | ||
| 3039 | <property name="flag">wxBOTTOM|wxLEFT</property> | ||
| 3040 | <property name="proportion">0</property> | ||
| 3041 | <object class="wxStaticText" expanded="1"> | ||
| 3042 | <property name="bg"></property> | ||
| 3043 | <property name="context_help"></property> | ||
| 3044 | <property name="enabled">1</property> | ||
| 3045 | <property name="fg"></property> | ||
| 3046 | <property name="font"></property> | ||
| 3047 | <property name="hidden">0</property> | ||
| 3048 | <property name="id">wxID_ANY</property> | ||
| 3049 | <property name="label">&From:</property> | ||
| 3050 | <property name="maximum_size"></property> | ||
| 3051 | <property name="minimum_size"></property> | ||
| 3052 | <property name="name">m_staticTextFrom</property> | ||
| 3053 | <property name="permission">protected</property> | ||
| 3054 | <property name="pos"></property> | ||
| 3055 | <property name="size"></property> | ||
| 3056 | <property name="style"></property> | ||
| 3057 | <property name="subclass"></property> | ||
| 3058 | <property name="tooltip"></property> | ||
| 3059 | <property name="window_extra_style"></property> | ||
| 3060 | <property name="window_name"></property> | ||
| 3061 | <property name="window_style"></property> | ||
| 3062 | <property name="wrap">-1</property> | ||
| 3063 | <event name="OnChar"></event> | ||
| 3064 | <event name="OnEnterWindow"></event> | ||
| 3065 | <event name="OnEraseBackground"></event> | ||
| 3066 | <event name="OnKeyDown"></event> | ||
| 3067 | <event name="OnKeyUp"></event> | ||
| 3068 | <event name="OnKillFocus"></event> | ||
| 3069 | <event name="OnLeaveWindow"></event> | ||
| 3070 | <event name="OnLeftDClick"></event> | ||
| 3071 | <event name="OnLeftDown"></event> | ||
| 3072 | <event name="OnLeftUp"></event> | ||
| 3073 | <event name="OnMiddleDClick"></event> | ||
| 3074 | <event name="OnMiddleDown"></event> | ||
| 3075 | <event name="OnMiddleUp"></event> | ||
| 3076 | <event name="OnMotion"></event> | ||
| 3077 | <event name="OnMouseEvents"></event> | ||
| 3078 | <event name="OnMouseWheel"></event> | ||
| 3079 | <event name="OnPaint"></event> | ||
| 3080 | <event name="OnRightDClick"></event> | ||
| 3081 | <event name="OnRightDown"></event> | ||
| 3082 | <event name="OnRightUp"></event> | ||
| 3083 | <event name="OnSetFocus"></event> | ||
| 3084 | <event name="OnSize"></event> | ||
| 3085 | <event name="OnUpdateUI"></event> | ||
| 3086 | </object> | ||
| 3087 | </object> | ||
| 3088 | <object class="sizeritem" expanded="1"> | ||
| 3089 | <property name="border">5</property> | ||
| 3090 | <property name="flag">wxLEFT|wxEXPAND</property> | ||
| 3091 | <property name="proportion">0</property> | ||
| 3092 | <object class="wxTextCtrl" expanded="1"> | ||
| 3093 | <property name="bg"></property> | ||
| 3094 | <property name="context_help"></property> | ||
| 3095 | <property name="enabled">1</property> | ||
| 3096 | <property name="fg"></property> | ||
| 3097 | <property name="font"></property> | ||
| 3098 | <property name="hidden">0</property> | ||
| 3099 | <property name="id">wxID_ANY</property> | ||
| 3100 | <property name="maximum_size"></property> | ||
| 3101 | <property name="maxlength">0</property> | ||
| 3102 | <property name="minimum_size"></property> | ||
| 3103 | <property name="name">m_textCtrlFrom</property> | ||
| 3104 | <property name="permission">protected</property> | ||
| 3105 | <property name="pos"></property> | ||
| 3106 | <property name="size">-1,-1</property> | ||
| 3107 | <property name="style"></property> | ||
| 3108 | <property name="subclass"></property> | ||
| 3109 | <property name="tooltip"></property> | ||
| 3110 | <property name="value"></property> | ||
| 3111 | <property name="window_extra_style"></property> | ||
| 3112 | <property name="window_name"></property> | ||
| 3113 | <property name="window_style"></property> | ||
| 3114 | <event name="OnChar"></event> | ||
| 3115 | <event name="OnEnterWindow"></event> | ||
| 3116 | <event name="OnEraseBackground"></event> | ||
| 3117 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 3118 | <event name="OnKeyUp"></event> | ||
| 3119 | <event name="OnKillFocus"></event> | ||
| 3120 | <event name="OnLeaveWindow"></event> | ||
| 3121 | <event name="OnLeftDClick"></event> | ||
| 3122 | <event name="OnLeftDown"></event> | ||
| 3123 | <event name="OnLeftUp"></event> | ||
| 3124 | <event name="OnMiddleDClick"></event> | ||
| 3125 | <event name="OnMiddleDown"></event> | ||
| 3126 | <event name="OnMiddleUp"></event> | ||
| 3127 | <event name="OnMotion"></event> | ||
| 3128 | <event name="OnMouseEvents"></event> | ||
| 3129 | <event name="OnMouseWheel"></event> | ||
| 3130 | <event name="OnPaint"></event> | ||
| 3131 | <event name="OnRightDClick"></event> | ||
| 3132 | <event name="OnRightDown"></event> | ||
| 3133 | <event name="OnRightUp"></event> | ||
| 3134 | <event name="OnSetFocus"></event> | ||
| 3135 | <event name="OnSize"></event> | ||
| 3136 | <event name="OnText"></event> | ||
| 3137 | <event name="OnTextEnter"></event> | ||
| 3138 | <event name="OnTextMaxLen"></event> | ||
| 3139 | <event name="OnTextURL"></event> | ||
| 3140 | <event name="OnUpdateUI"></event> | ||
| 3141 | </object> | ||
| 3142 | </object> | ||
| 3143 | </object> | ||
| 3144 | </object> | ||
| 3145 | </object> | ||
| 3146 | </object> | ||
| 3147 | <object class="sizeritem" expanded="1"> | ||
| 3148 | <property name="border">5</property> | ||
| 3149 | <property name="flag">wxEXPAND</property> | ||
| 3150 | <property name="proportion">1</property> | ||
| 3151 | <object class="wxBoxSizer" expanded="1"> | ||
| 3152 | <property name="minimum_size"></property> | ||
| 3153 | <property name="name">bSizer67</property> | ||
| 3154 | <property name="orient">wxHORIZONTAL</property> | ||
| 3155 | <property name="permission">none</property> | ||
| 3156 | <object class="sizeritem" expanded="1"> | ||
| 3157 | <property name="border">5</property> | ||
| 3158 | <property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property> | ||
| 3159 | <property name="proportion">1</property> | ||
| 3160 | <object class="wxBoxSizer" expanded="1"> | ||
| 3161 | <property name="minimum_size"></property> | ||
| 3162 | <property name="name">bSizer68</property> | ||
| 3163 | <property name="orient">wxVERTICAL</property> | ||
| 3164 | <property name="permission">none</property> | ||
| 3165 | <object class="sizeritem" expanded="1"> | ||
| 3166 | <property name="border">5</property> | ||
| 3167 | <property name="flag">wxTOP|wxBOTTOM|wxLEFT</property> | ||
| 3168 | <property name="proportion">0</property> | ||
| 3169 | <object class="wxStaticText" expanded="1"> | ||
| 3170 | <property name="bg"></property> | ||
| 3171 | <property name="context_help"></property> | ||
| 3172 | <property name="enabled">1</property> | ||
| 3173 | <property name="fg"></property> | ||
| 3174 | <property name="font"></property> | ||
| 3175 | <property name="hidden">0</property> | ||
| 3176 | <property name="id">wxID_ANY</property> | ||
| 3177 | <property name="label">&Message:</property> | ||
| 3178 | <property name="maximum_size"></property> | ||
| 3179 | <property name="minimum_size"></property> | ||
| 3180 | <property name="name">m_staticTextMessage</property> | ||
| 3181 | <property name="permission">protected</property> | ||
| 3182 | <property name="pos"></property> | ||
| 3183 | <property name="size"></property> | ||
| 3184 | <property name="style"></property> | ||
| 3185 | <property name="subclass"></property> | ||
| 3186 | <property name="tooltip"></property> | ||
| 3187 | <property name="window_extra_style"></property> | ||
| 3188 | <property name="window_name"></property> | ||
| 3189 | <property name="window_style"></property> | ||
| 3190 | <property name="wrap">-1</property> | ||
| 3191 | <event name="OnChar"></event> | ||
| 3192 | <event name="OnEnterWindow"></event> | ||
| 3193 | <event name="OnEraseBackground"></event> | ||
| 3194 | <event name="OnKeyDown"></event> | ||
| 3195 | <event name="OnKeyUp"></event> | ||
| 3196 | <event name="OnKillFocus"></event> | ||
| 3197 | <event name="OnLeaveWindow"></event> | ||
| 3198 | <event name="OnLeftDClick"></event> | ||
| 3199 | <event name="OnLeftDown"></event> | ||
| 3200 | <event name="OnLeftUp"></event> | ||
| 3201 | <event name="OnMiddleDClick"></event> | ||
| 3202 | <event name="OnMiddleDown"></event> | ||
| 3203 | <event name="OnMiddleUp"></event> | ||
| 3204 | <event name="OnMotion"></event> | ||
| 3205 | <event name="OnMouseEvents"></event> | ||
| 3206 | <event name="OnMouseWheel"></event> | ||
| 3207 | <event name="OnPaint"></event> | ||
| 3208 | <event name="OnRightDClick"></event> | ||
| 3209 | <event name="OnRightDown"></event> | ||
| 3210 | <event name="OnRightUp"></event> | ||
| 3211 | <event name="OnSetFocus"></event> | ||
| 3212 | <event name="OnSize"></event> | ||
| 3213 | <event name="OnUpdateUI"></event> | ||
| 3214 | </object> | ||
| 3215 | </object> | ||
| 3216 | <object class="sizeritem" expanded="1"> | ||
| 3217 | <property name="border">5</property> | ||
| 3218 | <property name="flag">wxEXPAND|wxLEFT</property> | ||
| 3219 | <property name="proportion">1</property> | ||
| 3220 | <object class="wxTextCtrl" expanded="1"> | ||
| 3221 | <property name="bg"></property> | ||
| 3222 | <property name="context_help"></property> | ||
| 3223 | <property name="enabled">1</property> | ||
| 3224 | <property name="fg"></property> | ||
| 3225 | <property name="font"></property> | ||
| 3226 | <property name="hidden">0</property> | ||
| 3227 | <property name="id">wxID_ANY</property> | ||
| 3228 | <property name="maximum_size"></property> | ||
| 3229 | <property name="maxlength">0</property> | ||
| 3230 | <property name="minimum_size"></property> | ||
| 3231 | <property name="name">m_textCtrlMessage</property> | ||
| 3232 | <property name="permission">protected</property> | ||
| 3233 | <property name="pos"></property> | ||
| 3234 | <property name="size"></property> | ||
| 3235 | <property name="style">wxTE_MULTILINE</property> | ||
| 3236 | <property name="subclass"></property> | ||
| 3237 | <property name="tooltip"></property> | ||
| 3238 | <property name="value"></property> | ||
| 3239 | <property name="window_extra_style"></property> | ||
| 3240 | <property name="window_name"></property> | ||
| 3241 | <property name="window_style"></property> | ||
| 3242 | <event name="OnChar"></event> | ||
| 3243 | <event name="OnEnterWindow"></event> | ||
| 3244 | <event name="OnEraseBackground"></event> | ||
| 3245 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 3246 | <event name="OnKeyUp"></event> | ||
| 3247 | <event name="OnKillFocus"></event> | ||
| 3248 | <event name="OnLeaveWindow"></event> | ||
| 3249 | <event name="OnLeftDClick"></event> | ||
| 3250 | <event name="OnLeftDown"></event> | ||
| 3251 | <event name="OnLeftUp"></event> | ||
| 3252 | <event name="OnMiddleDClick"></event> | ||
| 3253 | <event name="OnMiddleDown"></event> | ||
| 3254 | <event name="OnMiddleUp"></event> | ||
| 3255 | <event name="OnMotion"></event> | ||
| 3256 | <event name="OnMouseEvents"></event> | ||
| 3257 | <event name="OnMouseWheel"></event> | ||
| 3258 | <event name="OnPaint"></event> | ||
| 3259 | <event name="OnRightDClick"></event> | ||
| 3260 | <event name="OnRightDown"></event> | ||
| 3261 | <event name="OnRightUp"></event> | ||
| 3262 | <event name="OnSetFocus"></event> | ||
| 3263 | <event name="OnSize"></event> | ||
| 3264 | <event name="OnText"></event> | ||
| 3265 | <event name="OnTextEnter"></event> | ||
| 3266 | <event name="OnTextMaxLen"></event> | ||
| 3267 | <event name="OnTextURL"></event> | ||
| 3268 | <event name="OnUpdateUI"></event> | ||
| 3269 | </object> | ||
| 3270 | </object> | ||
| 3271 | </object> | ||
| 3272 | </object> | ||
| 3273 | </object> | ||
| 3274 | </object> | ||
| 3275 | <object class="sizeritem" expanded="1"> | ||
| 3276 | <property name="border">5</property> | ||
| 3277 | <property name="flag">wxEXPAND</property> | ||
| 3278 | <property name="proportion">0</property> | ||
| 3279 | <object class="wxBoxSizer" expanded="1"> | ||
| 3280 | <property name="minimum_size"></property> | ||
| 3281 | <property name="name">bSizer23</property> | ||
| 3282 | <property name="orient">wxHORIZONTAL</property> | ||
| 3283 | <property name="permission">none</property> | ||
| 3284 | <object class="sizeritem" expanded="1"> | ||
| 3285 | <property name="border">5</property> | ||
| 3286 | <property name="flag">wxEXPAND</property> | ||
| 3287 | <property name="proportion">1</property> | ||
| 3288 | <object class="spacer" expanded="1"> | ||
| 3289 | <property name="height">0</property> | ||
| 3290 | <property name="permission">protected</property> | ||
| 3291 | <property name="width">0</property> | ||
| 3292 | </object> | ||
| 3293 | </object> | ||
| 3294 | <object class="sizeritem" expanded="1"> | ||
| 3295 | <property name="border">5</property> | ||
| 3296 | <property name="flag">wxALL</property> | ||
| 3297 | <property name="proportion">0</property> | ||
| 3298 | <object class="wxButton" expanded="1"> | ||
| 3299 | <property name="bg"></property> | ||
| 3300 | <property name="context_help"></property> | ||
| 3301 | <property name="default">0</property> | ||
| 3302 | <property name="enabled">1</property> | ||
| 3303 | <property name="fg"></property> | ||
| 3304 | <property name="font">,90,90,-1,70,0</property> | ||
| 3305 | <property name="hidden">0</property> | ||
| 3306 | <property name="id">wxID_BUTTONSEND</property> | ||
| 3307 | <property name="label">&Send</property> | ||
| 3308 | <property name="maximum_size"></property> | ||
| 3309 | <property name="minimum_size">85,25</property> | ||
| 3310 | <property name="name">m_buttonSend</property> | ||
| 3311 | <property name="permission">protected</property> | ||
| 3312 | <property name="pos"></property> | ||
| 3313 | <property name="size">-1,-1</property> | ||
| 3314 | <property name="style"></property> | ||
| 3315 | <property name="subclass"></property> | ||
| 3316 | <property name="tooltip"></property> | ||
| 3317 | <property name="window_extra_style"></property> | ||
| 3318 | <property name="window_name"></property> | ||
| 3319 | <property name="window_style"></property> | ||
| 3320 | <event name="OnButtonClick">OnButtonSend</event> | ||
| 3321 | <event name="OnChar"></event> | ||
| 3322 | <event name="OnEnterWindow"></event> | ||
| 3323 | <event name="OnEraseBackground"></event> | ||
| 3324 | <event name="OnKeyDown"></event> | ||
| 3325 | <event name="OnKeyUp"></event> | ||
| 3326 | <event name="OnKillFocus"></event> | ||
| 3327 | <event name="OnLeaveWindow"></event> | ||
| 3328 | <event name="OnLeftDClick"></event> | ||
| 3329 | <event name="OnLeftDown"></event> | ||
| 3330 | <event name="OnLeftUp"></event> | ||
| 3331 | <event name="OnMiddleDClick"></event> | ||
| 3332 | <event name="OnMiddleDown"></event> | ||
| 3333 | <event name="OnMiddleUp"></event> | ||
| 3334 | <event name="OnMotion"></event> | ||
| 3335 | <event name="OnMouseEvents"></event> | ||
| 3336 | <event name="OnMouseWheel"></event> | ||
| 3337 | <event name="OnPaint"></event> | ||
| 3338 | <event name="OnRightDClick"></event> | ||
| 3339 | <event name="OnRightDown"></event> | ||
| 3340 | <event name="OnRightUp"></event> | ||
| 3341 | <event name="OnSetFocus"></event> | ||
| 3342 | <event name="OnSize"></event> | ||
| 3343 | <event name="OnUpdateUI"></event> | ||
| 3344 | </object> | ||
| 3345 | </object> | ||
| 3346 | <object class="sizeritem" expanded="1"> | ||
| 3347 | <property name="border">5</property> | ||
| 3348 | <property name="flag">wxALL</property> | ||
| 3349 | <property name="proportion">0</property> | ||
| 3350 | <object class="wxButton" expanded="1"> | ||
| 3351 | <property name="bg"></property> | ||
| 3352 | <property name="context_help"></property> | ||
| 3353 | <property name="default">0</property> | ||
| 3354 | <property name="enabled">1</property> | ||
| 3355 | <property name="fg"></property> | ||
| 3356 | <property name="font"></property> | ||
| 3357 | <property name="hidden">0</property> | ||
| 3358 | <property name="id">wxID_CANCEL</property> | ||
| 3359 | <property name="label">Cancel</property> | ||
| 3360 | <property name="maximum_size"></property> | ||
| 3361 | <property name="minimum_size">85,25</property> | ||
| 3362 | <property name="name">m_buttonCancel</property> | ||
| 3363 | <property name="permission">protected</property> | ||
| 3364 | <property name="pos"></property> | ||
| 3365 | <property name="size">-1,-1</property> | ||
| 3366 | <property name="style"></property> | ||
| 3367 | <property name="subclass"></property> | ||
| 3368 | <property name="tooltip"></property> | ||
| 3369 | <property name="window_extra_style"></property> | ||
| 3370 | <property name="window_name"></property> | ||
| 3371 | <property name="window_style"></property> | ||
| 3372 | <event name="OnButtonClick">OnButtonCancel</event> | ||
| 3373 | <event name="OnChar"></event> | ||
| 3374 | <event name="OnEnterWindow"></event> | ||
| 3375 | <event name="OnEraseBackground"></event> | ||
| 3376 | <event name="OnKeyDown"></event> | ||
| 3377 | <event name="OnKeyUp"></event> | ||
| 3378 | <event name="OnKillFocus"></event> | ||
| 3379 | <event name="OnLeaveWindow"></event> | ||
| 3380 | <event name="OnLeftDClick"></event> | ||
| 3381 | <event name="OnLeftDown"></event> | ||
| 3382 | <event name="OnLeftUp"></event> | ||
| 3383 | <event name="OnMiddleDClick"></event> | ||
| 3384 | <event name="OnMiddleDown"></event> | ||
| 3385 | <event name="OnMiddleUp"></event> | ||
| 3386 | <event name="OnMotion"></event> | ||
| 3387 | <event name="OnMouseEvents"></event> | ||
| 3388 | <event name="OnMouseWheel"></event> | ||
| 3389 | <event name="OnPaint"></event> | ||
| 3390 | <event name="OnRightDClick"></event> | ||
| 3391 | <event name="OnRightDown"></event> | ||
| 3392 | <event name="OnRightUp"></event> | ||
| 3393 | <event name="OnSetFocus"></event> | ||
| 3394 | <event name="OnSize"></event> | ||
| 3395 | <event name="OnUpdateUI"></event> | ||
| 3396 | </object> | ||
| 3397 | </object> | ||
| 3398 | </object> | ||
| 3399 | </object> | ||
| 3400 | </object> | ||
| 3401 | </object> | ||
| 3402 | <object class="Dialog" expanded="1"> | ||
| 3403 | <property name="bg"></property> | ||
| 3404 | <property name="center"></property> | ||
| 3405 | <property name="context_help"></property> | ||
| 3406 | <property name="enabled">1</property> | ||
| 3407 | <property name="extra_style"></property> | ||
| 3408 | <property name="fg"></property> | ||
| 3409 | <property name="font"></property> | ||
| 3410 | <property name="hidden">0</property> | ||
| 3411 | <property name="id">wxID_ANY</property> | ||
| 3412 | <property name="maximum_size"></property> | ||
| 3413 | <property name="minimum_size"></property> | ||
| 3414 | <property name="name">CSendingDialogBase</property> | ||
| 3415 | <property name="pos"></property> | ||
| 3416 | <property name="size">442,151</property> | ||
| 3417 | <property name="style">wxDEFAULT_DIALOG_STYLE</property> | ||
| 3418 | <property name="subclass"></property> | ||
| 3419 | <property name="title">Sending...</property> | ||
| 3420 | <property name="tooltip"></property> | ||
| 3421 | <property name="window_extra_style"></property> | ||
| 3422 | <property name="window_name"></property> | ||
| 3423 | <property name="window_style"></property> | ||
| 3424 | <event name="OnActivate"></event> | ||
| 3425 | <event name="OnActivateApp"></event> | ||
| 3426 | <event name="OnChar"></event> | ||
| 3427 | <event name="OnClose">OnClose</event> | ||
| 3428 | <event name="OnEnterWindow"></event> | ||
| 3429 | <event name="OnEraseBackground"></event> | ||
| 3430 | <event name="OnHibernate"></event> | ||
| 3431 | <event name="OnIconize"></event> | ||
| 3432 | <event name="OnIdle"></event> | ||
| 3433 | <event name="OnInitDialog"></event> | ||
| 3434 | <event name="OnKeyDown"></event> | ||
| 3435 | <event name="OnKeyUp"></event> | ||
| 3436 | <event name="OnKillFocus"></event> | ||
| 3437 | <event name="OnLeaveWindow"></event> | ||
| 3438 | <event name="OnLeftDClick"></event> | ||
| 3439 | <event name="OnLeftDown"></event> | ||
| 3440 | <event name="OnLeftUp"></event> | ||
| 3441 | <event name="OnMiddleDClick"></event> | ||
| 3442 | <event name="OnMiddleDown"></event> | ||
| 3443 | <event name="OnMiddleUp"></event> | ||
| 3444 | <event name="OnMotion"></event> | ||
| 3445 | <event name="OnMouseEvents"></event> | ||
| 3446 | <event name="OnMouseWheel"></event> | ||
| 3447 | <event name="OnPaint">OnPaint</event> | ||
| 3448 | <event name="OnRightDClick"></event> | ||
| 3449 | <event name="OnRightDown"></event> | ||
| 3450 | <event name="OnRightUp"></event> | ||
| 3451 | <event name="OnSetFocus"></event> | ||
| 3452 | <event name="OnSize"></event> | ||
| 3453 | <event name="OnUpdateUI"></event> | ||
| 3454 | <object class="wxBoxSizer" expanded="1"> | ||
| 3455 | <property name="minimum_size"></property> | ||
| 3456 | <property name="name">bSizer68</property> | ||
| 3457 | <property name="orient">wxVERTICAL</property> | ||
| 3458 | <property name="permission">none</property> | ||
| 3459 | <object class="sizeritem" expanded="1"> | ||
| 3460 | <property name="border">8</property> | ||
| 3461 | <property name="flag">wxALIGN_CENTER_VERTICAL|wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property> | ||
| 3462 | <property name="proportion">0</property> | ||
| 3463 | <object class="wxStaticText" expanded="1"> | ||
| 3464 | <property name="bg"></property> | ||
| 3465 | <property name="context_help"></property> | ||
| 3466 | <property name="enabled">1</property> | ||
| 3467 | <property name="fg"></property> | ||
| 3468 | <property name="font"></property> | ||
| 3469 | <property name="hidden">0</property> | ||
| 3470 | <property name="id">wxID_ANY</property> | ||
| 3471 | <property name="label"></property> | ||
| 3472 | <property name="maximum_size"></property> | ||
| 3473 | <property name="minimum_size"></property> | ||
| 3474 | <property name="name">m_staticTextSending</property> | ||
| 3475 | <property name="permission">protected</property> | ||
| 3476 | <property name="pos"></property> | ||
| 3477 | <property name="size">-1,14</property> | ||
| 3478 | <property name="style"></property> | ||
| 3479 | <property name="subclass"></property> | ||
| 3480 | <property name="tooltip"></property> | ||
| 3481 | <property name="window_extra_style"></property> | ||
| 3482 | <property name="window_name"></property> | ||
| 3483 | <property name="window_style"></property> | ||
| 3484 | <property name="wrap">-1</property> | ||
| 3485 | <event name="OnChar"></event> | ||
| 3486 | <event name="OnEnterWindow"></event> | ||
| 3487 | <event name="OnEraseBackground"></event> | ||
| 3488 | <event name="OnKeyDown"></event> | ||
| 3489 | <event name="OnKeyUp"></event> | ||
| 3490 | <event name="OnKillFocus"></event> | ||
| 3491 | <event name="OnLeaveWindow"></event> | ||
| 3492 | <event name="OnLeftDClick"></event> | ||
| 3493 | <event name="OnLeftDown"></event> | ||
| 3494 | <event name="OnLeftUp"></event> | ||
| 3495 | <event name="OnMiddleDClick"></event> | ||
| 3496 | <event name="OnMiddleDown"></event> | ||
| 3497 | <event name="OnMiddleUp"></event> | ||
| 3498 | <event name="OnMotion"></event> | ||
| 3499 | <event name="OnMouseEvents"></event> | ||
| 3500 | <event name="OnMouseWheel"></event> | ||
| 3501 | <event name="OnPaint"></event> | ||
| 3502 | <event name="OnRightDClick"></event> | ||
| 3503 | <event name="OnRightDown"></event> | ||
| 3504 | <event name="OnRightUp"></event> | ||
| 3505 | <event name="OnSetFocus"></event> | ||
| 3506 | <event name="OnSize"></event> | ||
| 3507 | <event name="OnUpdateUI"></event> | ||
| 3508 | </object> | ||
| 3509 | </object> | ||
| 3510 | <object class="sizeritem" expanded="1"> | ||
| 3511 | <property name="border">10</property> | ||
| 3512 | <property name="flag">wxEXPAND|wxRIGHT|wxLEFT</property> | ||
| 3513 | <property name="proportion">1</property> | ||
| 3514 | <object class="wxTextCtrl" expanded="1"> | ||
| 3515 | <property name="bg">wxSYS_COLOUR_BTNFACE</property> | ||
| 3516 | <property name="context_help"></property> | ||
| 3517 | <property name="enabled">1</property> | ||
| 3518 | <property name="fg"></property> | ||
| 3519 | <property name="font"></property> | ||
| 3520 | <property name="hidden">0</property> | ||
| 3521 | <property name="id">wxID_ANY</property> | ||
| 3522 | <property name="maximum_size"></property> | ||
| 3523 | <property name="maxlength">0</property> | ||
| 3524 | <property name="minimum_size"></property> | ||
| 3525 | <property name="name">m_textCtrlStatus</property> | ||
| 3526 | <property name="permission">protected</property> | ||
| 3527 | <property name="pos"></property> | ||
| 3528 | <property name="size"></property> | ||
| 3529 | <property name="style">wxTE_CENTRE|wxTE_MULTILINE|wxTE_NO_VSCROLL|wxTE_READONLY</property> | ||
| 3530 | <property name="subclass"></property> | ||
| 3531 | <property name="tooltip"></property> | ||
| 3532 | <property name="value">

Connecting...</property> | ||
| 3533 | <property name="window_extra_style"></property> | ||
| 3534 | <property name="window_name"></property> | ||
| 3535 | <property name="window_style">wxNO_BORDER</property> | ||
| 3536 | <event name="OnChar"></event> | ||
| 3537 | <event name="OnEnterWindow"></event> | ||
| 3538 | <event name="OnEraseBackground"></event> | ||
| 3539 | <event name="OnKeyDown"></event> | ||
| 3540 | <event name="OnKeyUp"></event> | ||
| 3541 | <event name="OnKillFocus"></event> | ||
| 3542 | <event name="OnLeaveWindow"></event> | ||
| 3543 | <event name="OnLeftDClick"></event> | ||
| 3544 | <event name="OnLeftDown"></event> | ||
| 3545 | <event name="OnLeftUp"></event> | ||
| 3546 | <event name="OnMiddleDClick"></event> | ||
| 3547 | <event name="OnMiddleDown"></event> | ||
| 3548 | <event name="OnMiddleUp"></event> | ||
| 3549 | <event name="OnMotion"></event> | ||
| 3550 | <event name="OnMouseEvents"></event> | ||
| 3551 | <event name="OnMouseWheel"></event> | ||
| 3552 | <event name="OnPaint"></event> | ||
| 3553 | <event name="OnRightDClick"></event> | ||
| 3554 | <event name="OnRightDown"></event> | ||
| 3555 | <event name="OnRightUp"></event> | ||
| 3556 | <event name="OnSetFocus"></event> | ||
| 3557 | <event name="OnSize"></event> | ||
| 3558 | <event name="OnText"></event> | ||
| 3559 | <event name="OnTextEnter"></event> | ||
| 3560 | <event name="OnTextMaxLen"></event> | ||
| 3561 | <event name="OnTextURL"></event> | ||
| 3562 | <event name="OnUpdateUI"></event> | ||
| 3563 | </object> | ||
| 3564 | </object> | ||
| 3565 | <object class="sizeritem" expanded="1"> | ||
| 3566 | <property name="border">5</property> | ||
| 3567 | <property name="flag">wxEXPAND</property> | ||
| 3568 | <property name="proportion">0</property> | ||
| 3569 | <object class="wxBoxSizer" expanded="1"> | ||
| 3570 | <property name="minimum_size"></property> | ||
| 3571 | <property name="name">bSizer69</property> | ||
| 3572 | <property name="orient">wxHORIZONTAL</property> | ||
| 3573 | <property name="permission">none</property> | ||
| 3574 | <object class="sizeritem" expanded="1"> | ||
| 3575 | <property name="border">5</property> | ||
| 3576 | <property name="flag">wxEXPAND</property> | ||
| 3577 | <property name="proportion">1</property> | ||
| 3578 | <object class="spacer" expanded="1"> | ||
| 3579 | <property name="height">0</property> | ||
| 3580 | <property name="permission">protected</property> | ||
| 3581 | <property name="width">0</property> | ||
| 3582 | </object> | ||
| 3583 | </object> | ||
| 3584 | <object class="sizeritem" expanded="1"> | ||
| 3585 | <property name="border">5</property> | ||
| 3586 | <property name="flag">wxALL</property> | ||
| 3587 | <property name="proportion">0</property> | ||
| 3588 | <object class="wxButton" expanded="1"> | ||
| 3589 | <property name="bg"></property> | ||
| 3590 | <property name="context_help"></property> | ||
| 3591 | <property name="default">0</property> | ||
| 3592 | <property name="enabled">0</property> | ||
| 3593 | <property name="fg"></property> | ||
| 3594 | <property name="font"></property> | ||
| 3595 | <property name="hidden">0</property> | ||
| 3596 | <property name="id">wxID_ANY</property> | ||
| 3597 | <property name="label">OK</property> | ||
| 3598 | <property name="maximum_size"></property> | ||
| 3599 | <property name="minimum_size">85,25</property> | ||
| 3600 | <property name="name">m_buttonOK</property> | ||
| 3601 | <property name="permission">protected</property> | ||
| 3602 | <property name="pos"></property> | ||
| 3603 | <property name="size"></property> | ||
| 3604 | <property name="style"></property> | ||
| 3605 | <property name="subclass"></property> | ||
| 3606 | <property name="tooltip"></property> | ||
| 3607 | <property name="window_extra_style"></property> | ||
| 3608 | <property name="window_name"></property> | ||
| 3609 | <property name="window_style"></property> | ||
| 3610 | <event name="OnButtonClick">OnButtonOK</event> | ||
| 3611 | <event name="OnChar"></event> | ||
| 3612 | <event name="OnEnterWindow"></event> | ||
| 3613 | <event name="OnEraseBackground"></event> | ||
| 3614 | <event name="OnKeyDown"></event> | ||
| 3615 | <event name="OnKeyUp"></event> | ||
| 3616 | <event name="OnKillFocus"></event> | ||
| 3617 | <event name="OnLeaveWindow"></event> | ||
| 3618 | <event name="OnLeftDClick"></event> | ||
| 3619 | <event name="OnLeftDown"></event> | ||
| 3620 | <event name="OnLeftUp"></event> | ||
| 3621 | <event name="OnMiddleDClick"></event> | ||
| 3622 | <event name="OnMiddleDown"></event> | ||
| 3623 | <event name="OnMiddleUp"></event> | ||
| 3624 | <event name="OnMotion"></event> | ||
| 3625 | <event name="OnMouseEvents"></event> | ||
| 3626 | <event name="OnMouseWheel"></event> | ||
| 3627 | <event name="OnPaint"></event> | ||
| 3628 | <event name="OnRightDClick"></event> | ||
| 3629 | <event name="OnRightDown"></event> | ||
| 3630 | <event name="OnRightUp"></event> | ||
| 3631 | <event name="OnSetFocus"></event> | ||
| 3632 | <event name="OnSize"></event> | ||
| 3633 | <event name="OnUpdateUI"></event> | ||
| 3634 | </object> | ||
| 3635 | </object> | ||
| 3636 | <object class="sizeritem" expanded="1"> | ||
| 3637 | <property name="border">5</property> | ||
| 3638 | <property name="flag">wxALL</property> | ||
| 3639 | <property name="proportion">0</property> | ||
| 3640 | <object class="wxButton" expanded="1"> | ||
| 3641 | <property name="bg"></property> | ||
| 3642 | <property name="context_help"></property> | ||
| 3643 | <property name="default">0</property> | ||
| 3644 | <property name="enabled">1</property> | ||
| 3645 | <property name="fg"></property> | ||
| 3646 | <property name="font"></property> | ||
| 3647 | <property name="hidden">0</property> | ||
| 3648 | <property name="id">wxID_CANCEL</property> | ||
| 3649 | <property name="label">Cancel</property> | ||
| 3650 | <property name="maximum_size"></property> | ||
| 3651 | <property name="minimum_size">85,25</property> | ||
| 3652 | <property name="name">m_buttonCancel</property> | ||
| 3653 | <property name="permission">protected</property> | ||
| 3654 | <property name="pos"></property> | ||
| 3655 | <property name="size">-1,-1</property> | ||
| 3656 | <property name="style"></property> | ||
| 3657 | <property name="subclass"></property> | ||
| 3658 | <property name="tooltip"></property> | ||
| 3659 | <property name="window_extra_style"></property> | ||
| 3660 | <property name="window_name"></property> | ||
| 3661 | <property name="window_style"></property> | ||
| 3662 | <event name="OnButtonClick">OnButtonCancel</event> | ||
| 3663 | <event name="OnChar"></event> | ||
| 3664 | <event name="OnEnterWindow"></event> | ||
| 3665 | <event name="OnEraseBackground"></event> | ||
| 3666 | <event name="OnKeyDown"></event> | ||
| 3667 | <event name="OnKeyUp"></event> | ||
| 3668 | <event name="OnKillFocus"></event> | ||
| 3669 | <event name="OnLeaveWindow"></event> | ||
| 3670 | <event name="OnLeftDClick"></event> | ||
| 3671 | <event name="OnLeftDown"></event> | ||
| 3672 | <event name="OnLeftUp"></event> | ||
| 3673 | <event name="OnMiddleDClick"></event> | ||
| 3674 | <event name="OnMiddleDown"></event> | ||
| 3675 | <event name="OnMiddleUp"></event> | ||
| 3676 | <event name="OnMotion"></event> | ||
| 3677 | <event name="OnMouseEvents"></event> | ||
| 3678 | <event name="OnMouseWheel"></event> | ||
| 3679 | <event name="OnPaint"></event> | ||
| 3680 | <event name="OnRightDClick"></event> | ||
| 3681 | <event name="OnRightDown"></event> | ||
| 3682 | <event name="OnRightUp"></event> | ||
| 3683 | <event name="OnSetFocus"></event> | ||
| 3684 | <event name="OnSize"></event> | ||
| 3685 | <event name="OnUpdateUI"></event> | ||
| 3686 | </object> | ||
| 3687 | </object> | ||
| 3688 | </object> | ||
| 3689 | </object> | ||
| 3690 | </object> | ||
| 3691 | </object> | ||
| 3692 | <object class="Dialog" expanded="0"> | ||
| 3693 | <property name="bg"></property> | ||
| 3694 | <property name="center"></property> | ||
| 3695 | <property name="context_help"></property> | ||
| 3696 | <property name="enabled">1</property> | ||
| 3697 | <property name="extra_style"></property> | ||
| 3698 | <property name="fg"></property> | ||
| 3699 | <property name="font"></property> | ||
| 3700 | <property name="hidden">0</property> | ||
| 3701 | <property name="id">wxID_ANY</property> | ||
| 3702 | <property name="maximum_size"></property> | ||
| 3703 | <property name="minimum_size"></property> | ||
| 3704 | <property name="name">CYourAddressDialogBase</property> | ||
| 3705 | <property name="pos"></property> | ||
| 3706 | <property name="size">610,390</property> | ||
| 3707 | <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property> | ||
| 3708 | <property name="subclass"></property> | ||
| 3709 | <property name="title">Your Bitcoin Address</property> | ||
| 3710 | <property name="tooltip"></property> | ||
| 3711 | <property name="window_extra_style"></property> | ||
| 3712 | <property name="window_name"></property> | ||
| 3713 | <property name="window_style"></property> | ||
| 3714 | <event name="OnActivate"></event> | ||
| 3715 | <event name="OnActivateApp"></event> | ||
| 3716 | <event name="OnChar"></event> | ||
| 3717 | <event name="OnClose">OnClose</event> | ||
| 3718 | <event name="OnEnterWindow"></event> | ||
| 3719 | <event name="OnEraseBackground"></event> | ||
| 3720 | <event name="OnHibernate"></event> | ||
| 3721 | <event name="OnIconize"></event> | ||
| 3722 | <event name="OnIdle"></event> | ||
| 3723 | <event name="OnInitDialog"></event> | ||
| 3724 | <event name="OnKeyDown"></event> | ||
| 3725 | <event name="OnKeyUp"></event> | ||
| 3726 | <event name="OnKillFocus"></event> | ||
| 3727 | <event name="OnLeaveWindow"></event> | ||
| 3728 | <event name="OnLeftDClick"></event> | ||
| 3729 | <event name="OnLeftDown"></event> | ||
| 3730 | <event name="OnLeftUp"></event> | ||
| 3731 | <event name="OnMiddleDClick"></event> | ||
| 3732 | <event name="OnMiddleDown"></event> | ||
| 3733 | <event name="OnMiddleUp"></event> | ||
| 3734 | <event name="OnMotion"></event> | ||
| 3735 | <event name="OnMouseEvents"></event> | ||
| 3736 | <event name="OnMouseWheel"></event> | ||
| 3737 | <event name="OnPaint"></event> | ||
| 3738 | <event name="OnRightDClick"></event> | ||
| 3739 | <event name="OnRightDown"></event> | ||
| 3740 | <event name="OnRightUp"></event> | ||
| 3741 | <event name="OnSetFocus"></event> | ||
| 3742 | <event name="OnSize"></event> | ||
| 3743 | <event name="OnUpdateUI"></event> | ||
| 3744 | <object class="wxBoxSizer" expanded="1"> | ||
| 3745 | <property name="minimum_size"></property> | ||
| 3746 | <property name="name">bSizer68</property> | ||
| 3747 | <property name="orient">wxVERTICAL</property> | ||
| 3748 | <property name="permission">none</property> | ||
| 3749 | <object class="sizeritem" expanded="1"> | ||
| 3750 | <property name="border">5</property> | ||
| 3751 | <property name="flag">wxEXPAND</property> | ||
| 3752 | <property name="proportion">0</property> | ||
| 3753 | <object class="spacer" expanded="1"> | ||
| 3754 | <property name="height">5</property> | ||
| 3755 | <property name="permission">protected</property> | ||
| 3756 | <property name="width">0</property> | ||
| 3757 | </object> | ||
| 3758 | </object> | ||
| 3759 | <object class="sizeritem" expanded="1"> | ||
| 3760 | <property name="border">5</property> | ||
| 3761 | <property name="flag">wxALL</property> | ||
| 3762 | <property name="proportion">0</property> | ||
| 3763 | <object class="wxStaticText" expanded="1"> | ||
| 3764 | <property name="bg"></property> | ||
| 3765 | <property name="context_help"></property> | ||
| 3766 | <property name="enabled">1</property> | ||
| 3767 | <property name="fg"></property> | ||
| 3768 | <property name="font"></property> | ||
| 3769 | <property name="hidden">0</property> | ||
| 3770 | <property name="id">wxID_ANY</property> | ||
| 3771 | <property name="label">These are your Bitcoin addresses for receiving payments.
You may want to give a different one to each sender so you can keep track of who is paying you.</property> | ||
| 3772 | <property name="maximum_size"></property> | ||
| 3773 | <property name="minimum_size"></property> | ||
| 3774 | <property name="name">m_staticText45</property> | ||
| 3775 | <property name="permission">protected</property> | ||
| 3776 | <property name="pos"></property> | ||
| 3777 | <property name="size"></property> | ||
| 3778 | <property name="style"></property> | ||
| 3779 | <property name="subclass"></property> | ||
| 3780 | <property name="tooltip"></property> | ||
| 3781 | <property name="window_extra_style"></property> | ||
| 3782 | <property name="window_name"></property> | ||
| 3783 | <property name="window_style"></property> | ||
| 3784 | <property name="wrap">600</property> | ||
| 3785 | <event name="OnChar"></event> | ||
| 3786 | <event name="OnEnterWindow"></event> | ||
| 3787 | <event name="OnEraseBackground"></event> | ||
| 3788 | <event name="OnKeyDown"></event> | ||
| 3789 | <event name="OnKeyUp"></event> | ||
| 3790 | <event name="OnKillFocus"></event> | ||
| 3791 | <event name="OnLeaveWindow"></event> | ||
| 3792 | <event name="OnLeftDClick"></event> | ||
| 3793 | <event name="OnLeftDown"></event> | ||
| 3794 | <event name="OnLeftUp"></event> | ||
| 3795 | <event name="OnMiddleDClick"></event> | ||
| 3796 | <event name="OnMiddleDown"></event> | ||
| 3797 | <event name="OnMiddleUp"></event> | ||
| 3798 | <event name="OnMotion"></event> | ||
| 3799 | <event name="OnMouseEvents"></event> | ||
| 3800 | <event name="OnMouseWheel"></event> | ||
| 3801 | <event name="OnPaint"></event> | ||
| 3802 | <event name="OnRightDClick"></event> | ||
| 3803 | <event name="OnRightDown"></event> | ||
| 3804 | <event name="OnRightUp"></event> | ||
| 3805 | <event name="OnSetFocus"></event> | ||
| 3806 | <event name="OnSize"></event> | ||
| 3807 | <event name="OnUpdateUI"></event> | ||
| 3808 | </object> | ||
| 3809 | </object> | ||
| 3810 | <object class="sizeritem" expanded="1"> | ||
| 3811 | <property name="border">5</property> | ||
| 3812 | <property name="flag">wxALL|wxEXPAND</property> | ||
| 3813 | <property name="proportion">1</property> | ||
| 3814 | <object class="wxListCtrl" expanded="1"> | ||
| 3815 | <property name="bg"></property> | ||
| 3816 | <property name="context_help"></property> | ||
| 3817 | <property name="enabled">1</property> | ||
| 3818 | <property name="fg"></property> | ||
| 3819 | <property name="font"></property> | ||
| 3820 | <property name="hidden">0</property> | ||
| 3821 | <property name="id">wxID_LISTCTRL</property> | ||
| 3822 | <property name="maximum_size"></property> | ||
| 3823 | <property name="minimum_size"></property> | ||
| 3824 | <property name="name">m_listCtrl</property> | ||
| 3825 | <property name="permission">protected</property> | ||
| 3826 | <property name="pos"></property> | ||
| 3827 | <property name="size"></property> | ||
| 3828 | <property name="style">wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_ASCENDING</property> | ||
| 3829 | <property name="subclass"></property> | ||
| 3830 | <property name="tooltip"></property> | ||
| 3831 | <property name="window_extra_style"></property> | ||
| 3832 | <property name="window_name"></property> | ||
| 3833 | <property name="window_style"></property> | ||
| 3834 | <event name="OnChar"></event> | ||
| 3835 | <event name="OnEnterWindow"></event> | ||
| 3836 | <event name="OnEraseBackground"></event> | ||
| 3837 | <event name="OnKeyDown"></event> | ||
| 3838 | <event name="OnKeyUp"></event> | ||
| 3839 | <event name="OnKillFocus"></event> | ||
| 3840 | <event name="OnLeaveWindow"></event> | ||
| 3841 | <event name="OnLeftDClick"></event> | ||
| 3842 | <event name="OnLeftDown"></event> | ||
| 3843 | <event name="OnLeftUp"></event> | ||
| 3844 | <event name="OnListBeginDrag"></event> | ||
| 3845 | <event name="OnListBeginLabelEdit"></event> | ||
| 3846 | <event name="OnListBeginRDrag"></event> | ||
| 3847 | <event name="OnListCacheHint"></event> | ||
| 3848 | <event name="OnListColBeginDrag"></event> | ||
| 3849 | <event name="OnListColClick"></event> | ||
| 3850 | <event name="OnListColDragging"></event> | ||
| 3851 | <event name="OnListColEndDrag"></event> | ||
| 3852 | <event name="OnListColRightClick"></event> | ||
| 3853 | <event name="OnListDeleteAllItems"></event> | ||
| 3854 | <event name="OnListDeleteItem"></event> | ||
| 3855 | <event name="OnListEndLabelEdit">OnListEndLabelEdit</event> | ||
| 3856 | <event name="OnListInsertItem"></event> | ||
| 3857 | <event name="OnListItemActivated">OnListItemActivated</event> | ||
| 3858 | <event name="OnListItemDeselected"></event> | ||
| 3859 | <event name="OnListItemFocused"></event> | ||
| 3860 | <event name="OnListItemMiddleClick"></event> | ||
| 3861 | <event name="OnListItemRightClick"></event> | ||
| 3862 | <event name="OnListItemSelected">OnListItemSelected</event> | ||
| 3863 | <event name="OnListKeyDown"></event> | ||
| 3864 | <event name="OnMiddleDClick"></event> | ||
| 3865 | <event name="OnMiddleDown"></event> | ||
| 3866 | <event name="OnMiddleUp"></event> | ||
| 3867 | <event name="OnMotion"></event> | ||
| 3868 | <event name="OnMouseEvents"></event> | ||
| 3869 | <event name="OnMouseWheel"></event> | ||
| 3870 | <event name="OnPaint"></event> | ||
| 3871 | <event name="OnRightDClick"></event> | ||
| 3872 | <event name="OnRightDown"></event> | ||
| 3873 | <event name="OnRightUp"></event> | ||
| 3874 | <event name="OnSetFocus"></event> | ||
| 3875 | <event name="OnSize"></event> | ||
| 3876 | <event name="OnUpdateUI"></event> | ||
| 3877 | </object> | ||
| 3878 | </object> | ||
| 3879 | <object class="sizeritem" expanded="1"> | ||
| 3880 | <property name="border">5</property> | ||
| 3881 | <property name="flag">wxEXPAND</property> | ||
| 3882 | <property name="proportion">0</property> | ||
| 3883 | <object class="wxBoxSizer" expanded="1"> | ||
| 3884 | <property name="minimum_size"></property> | ||
| 3885 | <property name="name">bSizer69</property> | ||
| 3886 | <property name="orient">wxHORIZONTAL</property> | ||
| 3887 | <property name="permission">none</property> | ||
| 3888 | <object class="sizeritem" expanded="1"> | ||
| 3889 | <property name="border">5</property> | ||
| 3890 | <property name="flag">wxEXPAND</property> | ||
| 3891 | <property name="proportion">1</property> | ||
| 3892 | <object class="spacer" expanded="1"> | ||
| 3893 | <property name="height">0</property> | ||
| 3894 | <property name="permission">protected</property> | ||
| 3895 | <property name="width">0</property> | ||
| 3896 | </object> | ||
| 3897 | </object> | ||
| 3898 | <object class="sizeritem" expanded="1"> | ||
| 3899 | <property name="border">5</property> | ||
| 3900 | <property name="flag">wxALL</property> | ||
| 3901 | <property name="proportion">0</property> | ||
| 3902 | <object class="wxButton" expanded="1"> | ||
| 3903 | <property name="bg"></property> | ||
| 3904 | <property name="context_help"></property> | ||
| 3905 | <property name="default">0</property> | ||
| 3906 | <property name="enabled">1</property> | ||
| 3907 | <property name="fg"></property> | ||
| 3908 | <property name="font"></property> | ||
| 3909 | <property name="hidden">0</property> | ||
| 3910 | <property name="id">wxID_BUTTONRENAME</property> | ||
| 3911 | <property name="label">&Rename...</property> | ||
| 3912 | <property name="maximum_size"></property> | ||
| 3913 | <property name="minimum_size">85,25</property> | ||
| 3914 | <property name="name">m_buttonRename</property> | ||
| 3915 | <property name="permission">protected</property> | ||
| 3916 | <property name="pos"></property> | ||
| 3917 | <property name="size"></property> | ||
| 3918 | <property name="style"></property> | ||
| 3919 | <property name="subclass"></property> | ||
| 3920 | <property name="tooltip"></property> | ||
| 3921 | <property name="window_extra_style"></property> | ||
| 3922 | <property name="window_name"></property> | ||
| 3923 | <property name="window_style"></property> | ||
| 3924 | <event name="OnButtonClick">OnButtonRename</event> | ||
| 3925 | <event name="OnChar"></event> | ||
| 3926 | <event name="OnEnterWindow"></event> | ||
| 3927 | <event name="OnEraseBackground"></event> | ||
| 3928 | <event name="OnKeyDown"></event> | ||
| 3929 | <event name="OnKeyUp"></event> | ||
| 3930 | <event name="OnKillFocus"></event> | ||
| 3931 | <event name="OnLeaveWindow"></event> | ||
| 3932 | <event name="OnLeftDClick"></event> | ||
| 3933 | <event name="OnLeftDown"></event> | ||
| 3934 | <event name="OnLeftUp"></event> | ||
| 3935 | <event name="OnMiddleDClick"></event> | ||
| 3936 | <event name="OnMiddleDown"></event> | ||
| 3937 | <event name="OnMiddleUp"></event> | ||
| 3938 | <event name="OnMotion"></event> | ||
| 3939 | <event name="OnMouseEvents"></event> | ||
| 3940 | <event name="OnMouseWheel"></event> | ||
| 3941 | <event name="OnPaint"></event> | ||
| 3942 | <event name="OnRightDClick"></event> | ||
| 3943 | <event name="OnRightDown"></event> | ||
| 3944 | <event name="OnRightUp"></event> | ||
| 3945 | <event name="OnSetFocus"></event> | ||
| 3946 | <event name="OnSize"></event> | ||
| 3947 | <event name="OnUpdateUI"></event> | ||
| 3948 | </object> | ||
| 3949 | </object> | ||
| 3950 | <object class="sizeritem" expanded="1"> | ||
| 3951 | <property name="border">5</property> | ||
| 3952 | <property name="flag">wxALL</property> | ||
| 3953 | <property name="proportion">0</property> | ||
| 3954 | <object class="wxButton" expanded="1"> | ||
| 3955 | <property name="bg"></property> | ||
| 3956 | <property name="context_help"></property> | ||
| 3957 | <property name="default">0</property> | ||
| 3958 | <property name="enabled">1</property> | ||
| 3959 | <property name="fg"></property> | ||
| 3960 | <property name="font"></property> | ||
| 3961 | <property name="hidden">0</property> | ||
| 3962 | <property name="id">wxID_BUTTONNEW</property> | ||
| 3963 | <property name="label">&New Address...</property> | ||
| 3964 | <property name="maximum_size"></property> | ||
| 3965 | <property name="minimum_size">110,25</property> | ||
| 3966 | <property name="name">m_buttonNew</property> | ||
| 3967 | <property name="permission">protected</property> | ||
| 3968 | <property name="pos"></property> | ||
| 3969 | <property name="size">-1,-1</property> | ||
| 3970 | <property name="style"></property> | ||
| 3971 | <property name="subclass"></property> | ||
| 3972 | <property name="tooltip"></property> | ||
| 3973 | <property name="window_extra_style"></property> | ||
| 3974 | <property name="window_name"></property> | ||
| 3975 | <property name="window_style"></property> | ||
| 3976 | <event name="OnButtonClick">OnButtonNew</event> | ||
| 3977 | <event name="OnChar"></event> | ||
| 3978 | <event name="OnEnterWindow"></event> | ||
| 3979 | <event name="OnEraseBackground"></event> | ||
| 3980 | <event name="OnKeyDown"></event> | ||
| 3981 | <event name="OnKeyUp"></event> | ||
| 3982 | <event name="OnKillFocus"></event> | ||
| 3983 | <event name="OnLeaveWindow"></event> | ||
| 3984 | <event name="OnLeftDClick"></event> | ||
| 3985 | <event name="OnLeftDown"></event> | ||
| 3986 | <event name="OnLeftUp"></event> | ||
| 3987 | <event name="OnMiddleDClick"></event> | ||
| 3988 | <event name="OnMiddleDown"></event> | ||
| 3989 | <event name="OnMiddleUp"></event> | ||
| 3990 | <event name="OnMotion"></event> | ||
| 3991 | <event name="OnMouseEvents"></event> | ||
| 3992 | <event name="OnMouseWheel"></event> | ||
| 3993 | <event name="OnPaint"></event> | ||
| 3994 | <event name="OnRightDClick"></event> | ||
| 3995 | <event name="OnRightDown"></event> | ||
| 3996 | <event name="OnRightUp"></event> | ||
| 3997 | <event name="OnSetFocus"></event> | ||
| 3998 | <event name="OnSize"></event> | ||
| 3999 | <event name="OnUpdateUI"></event> | ||
| 4000 | </object> | ||
| 4001 | </object> | ||
| 4002 | <object class="sizeritem" expanded="1"> | ||
| 4003 | <property name="border">5</property> | ||
| 4004 | <property name="flag">wxALL</property> | ||
| 4005 | <property name="proportion">0</property> | ||
| 4006 | <object class="wxButton" expanded="1"> | ||
| 4007 | <property name="bg"></property> | ||
| 4008 | <property name="context_help"></property> | ||
| 4009 | <property name="default">0</property> | ||
| 4010 | <property name="enabled">1</property> | ||
| 4011 | <property name="fg"></property> | ||
| 4012 | <property name="font"></property> | ||
| 4013 | <property name="hidden">0</property> | ||
| 4014 | <property name="id">wxID_BUTTONCOPY</property> | ||
| 4015 | <property name="label">&Copy to Clipboard</property> | ||
| 4016 | <property name="maximum_size"></property> | ||
| 4017 | <property name="minimum_size">120,25</property> | ||
| 4018 | <property name="name">m_buttonCopy</property> | ||
| 4019 | <property name="permission">protected</property> | ||
| 4020 | <property name="pos"></property> | ||
| 4021 | <property name="size">-1,-1</property> | ||
| 4022 | <property name="style"></property> | ||
| 4023 | <property name="subclass"></property> | ||
| 4024 | <property name="tooltip"></property> | ||
| 4025 | <property name="window_extra_style"></property> | ||
| 4026 | <property name="window_name"></property> | ||
| 4027 | <property name="window_style"></property> | ||
| 4028 | <event name="OnButtonClick">OnButtonCopy</event> | ||
| 4029 | <event name="OnChar"></event> | ||
| 4030 | <event name="OnEnterWindow"></event> | ||
| 4031 | <event name="OnEraseBackground"></event> | ||
| 4032 | <event name="OnKeyDown"></event> | ||
| 4033 | <event name="OnKeyUp"></event> | ||
| 4034 | <event name="OnKillFocus"></event> | ||
| 4035 | <event name="OnLeaveWindow"></event> | ||
| 4036 | <event name="OnLeftDClick"></event> | ||
| 4037 | <event name="OnLeftDown"></event> | ||
| 4038 | <event name="OnLeftUp"></event> | ||
| 4039 | <event name="OnMiddleDClick"></event> | ||
| 4040 | <event name="OnMiddleDown"></event> | ||
| 4041 | <event name="OnMiddleUp"></event> | ||
| 4042 | <event name="OnMotion"></event> | ||
| 4043 | <event name="OnMouseEvents"></event> | ||
| 4044 | <event name="OnMouseWheel"></event> | ||
| 4045 | <event name="OnPaint"></event> | ||
| 4046 | <event name="OnRightDClick"></event> | ||
| 4047 | <event name="OnRightDown"></event> | ||
| 4048 | <event name="OnRightUp"></event> | ||
| 4049 | <event name="OnSetFocus"></event> | ||
| 4050 | <event name="OnSize"></event> | ||
| 4051 | <event name="OnUpdateUI"></event> | ||
| 4052 | </object> | ||
| 4053 | </object> | ||
| 4054 | <object class="sizeritem" expanded="1"> | ||
| 4055 | <property name="border">5</property> | ||
| 4056 | <property name="flag">wxALL</property> | ||
| 4057 | <property name="proportion">0</property> | ||
| 4058 | <object class="wxButton" expanded="1"> | ||
| 4059 | <property name="bg"></property> | ||
| 4060 | <property name="context_help"></property> | ||
| 4061 | <property name="default">0</property> | ||
| 4062 | <property name="enabled">1</property> | ||
| 4063 | <property name="fg"></property> | ||
| 4064 | <property name="font"></property> | ||
| 4065 | <property name="hidden">0</property> | ||
| 4066 | <property name="id">wxID_OK</property> | ||
| 4067 | <property name="label">OK</property> | ||
| 4068 | <property name="maximum_size"></property> | ||
| 4069 | <property name="minimum_size">85,25</property> | ||
| 4070 | <property name="name">m_buttonOK</property> | ||
| 4071 | <property name="permission">protected</property> | ||
| 4072 | <property name="pos"></property> | ||
| 4073 | <property name="size"></property> | ||
| 4074 | <property name="style"></property> | ||
| 4075 | <property name="subclass"></property> | ||
| 4076 | <property name="tooltip"></property> | ||
| 4077 | <property name="window_extra_style"></property> | ||
| 4078 | <property name="window_name"></property> | ||
| 4079 | <property name="window_style"></property> | ||
| 4080 | <event name="OnButtonClick">OnButtonOK</event> | ||
| 4081 | <event name="OnChar"></event> | ||
| 4082 | <event name="OnEnterWindow"></event> | ||
| 4083 | <event name="OnEraseBackground"></event> | ||
| 4084 | <event name="OnKeyDown"></event> | ||
| 4085 | <event name="OnKeyUp"></event> | ||
| 4086 | <event name="OnKillFocus"></event> | ||
| 4087 | <event name="OnLeaveWindow"></event> | ||
| 4088 | <event name="OnLeftDClick"></event> | ||
| 4089 | <event name="OnLeftDown"></event> | ||
| 4090 | <event name="OnLeftUp"></event> | ||
| 4091 | <event name="OnMiddleDClick"></event> | ||
| 4092 | <event name="OnMiddleDown"></event> | ||
| 4093 | <event name="OnMiddleUp"></event> | ||
| 4094 | <event name="OnMotion"></event> | ||
| 4095 | <event name="OnMouseEvents"></event> | ||
| 4096 | <event name="OnMouseWheel"></event> | ||
| 4097 | <event name="OnPaint"></event> | ||
| 4098 | <event name="OnRightDClick"></event> | ||
| 4099 | <event name="OnRightDown"></event> | ||
| 4100 | <event name="OnRightUp"></event> | ||
| 4101 | <event name="OnSetFocus"></event> | ||
| 4102 | <event name="OnSize"></event> | ||
| 4103 | <event name="OnUpdateUI"></event> | ||
| 4104 | </object> | ||
| 4105 | </object> | ||
| 4106 | <object class="sizeritem" expanded="1"> | ||
| 4107 | <property name="border">5</property> | ||
| 4108 | <property name="flag">wxALL</property> | ||
| 4109 | <property name="proportion">0</property> | ||
| 4110 | <object class="wxButton" expanded="1"> | ||
| 4111 | <property name="bg"></property> | ||
| 4112 | <property name="context_help"></property> | ||
| 4113 | <property name="default">0</property> | ||
| 4114 | <property name="enabled">1</property> | ||
| 4115 | <property name="fg"></property> | ||
| 4116 | <property name="font"></property> | ||
| 4117 | <property name="hidden">0</property> | ||
| 4118 | <property name="id">wxID_CANCEL</property> | ||
| 4119 | <property name="label">Cancel</property> | ||
| 4120 | <property name="maximum_size"></property> | ||
| 4121 | <property name="minimum_size">85,25</property> | ||
| 4122 | <property name="name">m_buttonCancel</property> | ||
| 4123 | <property name="permission">protected</property> | ||
| 4124 | <property name="pos"></property> | ||
| 4125 | <property name="size">-1,-1</property> | ||
| 4126 | <property name="style"></property> | ||
| 4127 | <property name="subclass"></property> | ||
| 4128 | <property name="tooltip"></property> | ||
| 4129 | <property name="window_extra_style"></property> | ||
| 4130 | <property name="window_name"></property> | ||
| 4131 | <property name="window_style"></property> | ||
| 4132 | <event name="OnButtonClick">OnButtonCancel</event> | ||
| 4133 | <event name="OnChar"></event> | ||
| 4134 | <event name="OnEnterWindow"></event> | ||
| 4135 | <event name="OnEraseBackground"></event> | ||
| 4136 | <event name="OnKeyDown"></event> | ||
| 4137 | <event name="OnKeyUp"></event> | ||
| 4138 | <event name="OnKillFocus"></event> | ||
| 4139 | <event name="OnLeaveWindow"></event> | ||
| 4140 | <event name="OnLeftDClick"></event> | ||
| 4141 | <event name="OnLeftDown"></event> | ||
| 4142 | <event name="OnLeftUp"></event> | ||
| 4143 | <event name="OnMiddleDClick"></event> | ||
| 4144 | <event name="OnMiddleDown"></event> | ||
| 4145 | <event name="OnMiddleUp"></event> | ||
| 4146 | <event name="OnMotion"></event> | ||
| 4147 | <event name="OnMouseEvents"></event> | ||
| 4148 | <event name="OnMouseWheel"></event> | ||
| 4149 | <event name="OnPaint"></event> | ||
| 4150 | <event name="OnRightDClick"></event> | ||
| 4151 | <event name="OnRightDown"></event> | ||
| 4152 | <event name="OnRightUp"></event> | ||
| 4153 | <event name="OnSetFocus"></event> | ||
| 4154 | <event name="OnSize"></event> | ||
| 4155 | <event name="OnUpdateUI"></event> | ||
| 4156 | </object> | ||
| 4157 | </object> | ||
| 4158 | </object> | ||
| 4159 | </object> | ||
| 4160 | </object> | ||
| 4161 | </object> | ||
| 4162 | <object class="Dialog" expanded="0"> | ||
| 4163 | <property name="bg"></property> | ||
| 4164 | <property name="center"></property> | ||
| 4165 | <property name="context_help"></property> | ||
| 4166 | <property name="enabled">1</property> | ||
| 4167 | <property name="extra_style"></property> | ||
| 4168 | <property name="fg"></property> | ||
| 4169 | <property name="font"></property> | ||
| 4170 | <property name="hidden">0</property> | ||
| 4171 | <property name="id">wxID_ANY</property> | ||
| 4172 | <property name="maximum_size"></property> | ||
| 4173 | <property name="minimum_size"></property> | ||
| 4174 | <property name="name">CAddressBookDialogBase</property> | ||
| 4175 | <property name="pos"></property> | ||
| 4176 | <property name="size">610,390</property> | ||
| 4177 | <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property> | ||
| 4178 | <property name="subclass"></property> | ||
| 4179 | <property name="title">Address Book</property> | ||
| 4180 | <property name="tooltip"></property> | ||
| 4181 | <property name="window_extra_style"></property> | ||
| 4182 | <property name="window_name"></property> | ||
| 4183 | <property name="window_style"></property> | ||
| 4184 | <event name="OnActivate"></event> | ||
| 4185 | <event name="OnActivateApp"></event> | ||
| 4186 | <event name="OnChar"></event> | ||
| 4187 | <event name="OnClose">OnClose</event> | ||
| 4188 | <event name="OnEnterWindow"></event> | ||
| 4189 | <event name="OnEraseBackground"></event> | ||
| 4190 | <event name="OnHibernate"></event> | ||
| 4191 | <event name="OnIconize"></event> | ||
| 4192 | <event name="OnIdle"></event> | ||
| 4193 | <event name="OnInitDialog"></event> | ||
| 4194 | <event name="OnKeyDown"></event> | ||
| 4195 | <event name="OnKeyUp"></event> | ||
| 4196 | <event name="OnKillFocus"></event> | ||
| 4197 | <event name="OnLeaveWindow"></event> | ||
| 4198 | <event name="OnLeftDClick"></event> | ||
| 4199 | <event name="OnLeftDown"></event> | ||
| 4200 | <event name="OnLeftUp"></event> | ||
| 4201 | <event name="OnMiddleDClick"></event> | ||
| 4202 | <event name="OnMiddleDown"></event> | ||
| 4203 | <event name="OnMiddleUp"></event> | ||
| 4204 | <event name="OnMotion"></event> | ||
| 4205 | <event name="OnMouseEvents"></event> | ||
| 4206 | <event name="OnMouseWheel"></event> | ||
| 4207 | <event name="OnPaint"></event> | ||
| 4208 | <event name="OnRightDClick"></event> | ||
| 4209 | <event name="OnRightDown"></event> | ||
| 4210 | <event name="OnRightUp"></event> | ||
| 4211 | <event name="OnSetFocus"></event> | ||
| 4212 | <event name="OnSize"></event> | ||
| 4213 | <event name="OnUpdateUI"></event> | ||
| 4214 | <object class="wxBoxSizer" expanded="1"> | ||
| 4215 | <property name="minimum_size"></property> | ||
| 4216 | <property name="name">bSizer68</property> | ||
| 4217 | <property name="orient">wxVERTICAL</property> | ||
| 4218 | <property name="permission">none</property> | ||
| 4219 | <object class="sizeritem" expanded="1"> | ||
| 4220 | <property name="border">5</property> | ||
| 4221 | <property name="flag">wxEXPAND</property> | ||
| 4222 | <property name="proportion">0</property> | ||
| 4223 | <object class="spacer" expanded="1"> | ||
| 4224 | <property name="height">5</property> | ||
| 4225 | <property name="permission">protected</property> | ||
| 4226 | <property name="width">0</property> | ||
| 4227 | </object> | ||
| 4228 | </object> | ||
| 4229 | <object class="sizeritem" expanded="1"> | ||
| 4230 | <property name="border">5</property> | ||
| 4231 | <property name="flag">wxTOP|wxRIGHT|wxLEFT</property> | ||
| 4232 | <property name="proportion">0</property> | ||
| 4233 | <object class="wxStaticText" expanded="1"> | ||
| 4234 | <property name="bg"></property> | ||
| 4235 | <property name="context_help"></property> | ||
| 4236 | <property name="enabled">1</property> | ||
| 4237 | <property name="fg"></property> | ||
| 4238 | <property name="font"></property> | ||
| 4239 | <property name="hidden">1</property> | ||
| 4240 | <property name="id">wxID_ANY</property> | ||
| 4241 | <property name="label">Bitcoin Address</property> | ||
| 4242 | <property name="maximum_size"></property> | ||
| 4243 | <property name="minimum_size"></property> | ||
| 4244 | <property name="name">m_staticText55</property> | ||
| 4245 | <property name="permission">protected</property> | ||
| 4246 | <property name="pos"></property> | ||
| 4247 | <property name="size"></property> | ||
| 4248 | <property name="style"></property> | ||
| 4249 | <property name="subclass"></property> | ||
| 4250 | <property name="tooltip"></property> | ||
| 4251 | <property name="window_extra_style"></property> | ||
| 4252 | <property name="window_name"></property> | ||
| 4253 | <property name="window_style"></property> | ||
| 4254 | <property name="wrap">-1</property> | ||
| 4255 | <event name="OnChar"></event> | ||
| 4256 | <event name="OnEnterWindow"></event> | ||
| 4257 | <event name="OnEraseBackground"></event> | ||
| 4258 | <event name="OnKeyDown"></event> | ||
| 4259 | <event name="OnKeyUp"></event> | ||
| 4260 | <event name="OnKillFocus"></event> | ||
| 4261 | <event name="OnLeaveWindow"></event> | ||
| 4262 | <event name="OnLeftDClick"></event> | ||
| 4263 | <event name="OnLeftDown"></event> | ||
| 4264 | <event name="OnLeftUp"></event> | ||
| 4265 | <event name="OnMiddleDClick"></event> | ||
| 4266 | <event name="OnMiddleDown"></event> | ||
| 4267 | <event name="OnMiddleUp"></event> | ||
| 4268 | <event name="OnMotion"></event> | ||
| 4269 | <event name="OnMouseEvents"></event> | ||
| 4270 | <event name="OnMouseWheel"></event> | ||
| 4271 | <event name="OnPaint"></event> | ||
| 4272 | <event name="OnRightDClick"></event> | ||
| 4273 | <event name="OnRightDown"></event> | ||
| 4274 | <event name="OnRightUp"></event> | ||
| 4275 | <event name="OnSetFocus"></event> | ||
| 4276 | <event name="OnSize"></event> | ||
| 4277 | <event name="OnUpdateUI"></event> | ||
| 4278 | </object> | ||
| 4279 | </object> | ||
| 4280 | <object class="sizeritem" expanded="1"> | ||
| 4281 | <property name="border">5</property> | ||
| 4282 | <property name="flag">wxALL|wxEXPAND</property> | ||
| 4283 | <property name="proportion">1</property> | ||
| 4284 | <object class="wxListCtrl" expanded="1"> | ||
| 4285 | <property name="bg"></property> | ||
| 4286 | <property name="context_help"></property> | ||
| 4287 | <property name="enabled">1</property> | ||
| 4288 | <property name="fg"></property> | ||
| 4289 | <property name="font"></property> | ||
| 4290 | <property name="hidden">0</property> | ||
| 4291 | <property name="id">wxID_LISTCTRL</property> | ||
| 4292 | <property name="maximum_size"></property> | ||
| 4293 | <property name="minimum_size"></property> | ||
| 4294 | <property name="name">m_listCtrl</property> | ||
| 4295 | <property name="permission">protected</property> | ||
| 4296 | <property name="pos"></property> | ||
| 4297 | <property name="size"></property> | ||
| 4298 | <property name="style">wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_ASCENDING</property> | ||
| 4299 | <property name="subclass"></property> | ||
| 4300 | <property name="tooltip"></property> | ||
| 4301 | <property name="window_extra_style"></property> | ||
| 4302 | <property name="window_name"></property> | ||
| 4303 | <property name="window_style"></property> | ||
| 4304 | <event name="OnChar"></event> | ||
| 4305 | <event name="OnEnterWindow"></event> | ||
| 4306 | <event name="OnEraseBackground"></event> | ||
| 4307 | <event name="OnKeyDown"></event> | ||
| 4308 | <event name="OnKeyUp"></event> | ||
| 4309 | <event name="OnKillFocus"></event> | ||
| 4310 | <event name="OnLeaveWindow"></event> | ||
| 4311 | <event name="OnLeftDClick"></event> | ||
| 4312 | <event name="OnLeftDown"></event> | ||
| 4313 | <event name="OnLeftUp"></event> | ||
| 4314 | <event name="OnListBeginDrag"></event> | ||
| 4315 | <event name="OnListBeginLabelEdit"></event> | ||
| 4316 | <event name="OnListBeginRDrag"></event> | ||
| 4317 | <event name="OnListCacheHint"></event> | ||
| 4318 | <event name="OnListColBeginDrag"></event> | ||
| 4319 | <event name="OnListColClick"></event> | ||
| 4320 | <event name="OnListColDragging"></event> | ||
| 4321 | <event name="OnListColEndDrag"></event> | ||
| 4322 | <event name="OnListColRightClick"></event> | ||
| 4323 | <event name="OnListDeleteAllItems"></event> | ||
| 4324 | <event name="OnListDeleteItem"></event> | ||
| 4325 | <event name="OnListEndLabelEdit">OnListEndLabelEdit</event> | ||
| 4326 | <event name="OnListInsertItem"></event> | ||
| 4327 | <event name="OnListItemActivated">OnListItemActivated</event> | ||
| 4328 | <event name="OnListItemDeselected"></event> | ||
| 4329 | <event name="OnListItemFocused"></event> | ||
| 4330 | <event name="OnListItemMiddleClick"></event> | ||
| 4331 | <event name="OnListItemRightClick"></event> | ||
| 4332 | <event name="OnListItemSelected">OnListItemSelected</event> | ||
| 4333 | <event name="OnListKeyDown"></event> | ||
| 4334 | <event name="OnMiddleDClick"></event> | ||
| 4335 | <event name="OnMiddleDown"></event> | ||
| 4336 | <event name="OnMiddleUp"></event> | ||
| 4337 | <event name="OnMotion"></event> | ||
| 4338 | <event name="OnMouseEvents"></event> | ||
| 4339 | <event name="OnMouseWheel"></event> | ||
| 4340 | <event name="OnPaint"></event> | ||
| 4341 | <event name="OnRightDClick"></event> | ||
| 4342 | <event name="OnRightDown"></event> | ||
| 4343 | <event name="OnRightUp"></event> | ||
| 4344 | <event name="OnSetFocus"></event> | ||
| 4345 | <event name="OnSize"></event> | ||
| 4346 | <event name="OnUpdateUI"></event> | ||
| 4347 | </object> | ||
| 4348 | </object> | ||
| 4349 | <object class="sizeritem" expanded="1"> | ||
| 4350 | <property name="border">5</property> | ||
| 4351 | <property name="flag">wxEXPAND</property> | ||
| 4352 | <property name="proportion">0</property> | ||
| 4353 | <object class="wxBoxSizer" expanded="1"> | ||
| 4354 | <property name="minimum_size"></property> | ||
| 4355 | <property name="name">bSizer69</property> | ||
| 4356 | <property name="orient">wxHORIZONTAL</property> | ||
| 4357 | <property name="permission">none</property> | ||
| 4358 | <object class="sizeritem" expanded="1"> | ||
| 4359 | <property name="border">5</property> | ||
| 4360 | <property name="flag">wxEXPAND</property> | ||
| 4361 | <property name="proportion">1</property> | ||
| 4362 | <object class="spacer" expanded="1"> | ||
| 4363 | <property name="height">0</property> | ||
| 4364 | <property name="permission">protected</property> | ||
| 4365 | <property name="width">0</property> | ||
| 4366 | </object> | ||
| 4367 | </object> | ||
| 4368 | <object class="sizeritem" expanded="1"> | ||
| 4369 | <property name="border">5</property> | ||
| 4370 | <property name="flag">wxALL</property> | ||
| 4371 | <property name="proportion">0</property> | ||
| 4372 | <object class="wxButton" expanded="1"> | ||
| 4373 | <property name="bg"></property> | ||
| 4374 | <property name="context_help"></property> | ||
| 4375 | <property name="default">0</property> | ||
| 4376 | <property name="enabled">1</property> | ||
| 4377 | <property name="fg"></property> | ||
| 4378 | <property name="font"></property> | ||
| 4379 | <property name="hidden">0</property> | ||
| 4380 | <property name="id">wxID_BUTTONEDIT</property> | ||
| 4381 | <property name="label">&Edit...</property> | ||
| 4382 | <property name="maximum_size"></property> | ||
| 4383 | <property name="minimum_size">85,25</property> | ||
| 4384 | <property name="name">m_buttonEdit</property> | ||
| 4385 | <property name="permission">protected</property> | ||
| 4386 | <property name="pos"></property> | ||
| 4387 | <property name="size"></property> | ||
| 4388 | <property name="style"></property> | ||
| 4389 | <property name="subclass"></property> | ||
| 4390 | <property name="tooltip"></property> | ||
| 4391 | <property name="window_extra_style"></property> | ||
| 4392 | <property name="window_name"></property> | ||
| 4393 | <property name="window_style"></property> | ||
| 4394 | <event name="OnButtonClick">OnButtonEdit</event> | ||
| 4395 | <event name="OnChar"></event> | ||
| 4396 | <event name="OnEnterWindow"></event> | ||
| 4397 | <event name="OnEraseBackground"></event> | ||
| 4398 | <event name="OnKeyDown"></event> | ||
| 4399 | <event name="OnKeyUp"></event> | ||
| 4400 | <event name="OnKillFocus"></event> | ||
| 4401 | <event name="OnLeaveWindow"></event> | ||
| 4402 | <event name="OnLeftDClick"></event> | ||
| 4403 | <event name="OnLeftDown"></event> | ||
| 4404 | <event name="OnLeftUp"></event> | ||
| 4405 | <event name="OnMiddleDClick"></event> | ||
| 4406 | <event name="OnMiddleDown"></event> | ||
| 4407 | <event name="OnMiddleUp"></event> | ||
| 4408 | <event name="OnMotion"></event> | ||
| 4409 | <event name="OnMouseEvents"></event> | ||
| 4410 | <event name="OnMouseWheel"></event> | ||
| 4411 | <event name="OnPaint"></event> | ||
| 4412 | <event name="OnRightDClick"></event> | ||
| 4413 | <event name="OnRightDown"></event> | ||
| 4414 | <event name="OnRightUp"></event> | ||
| 4415 | <event name="OnSetFocus"></event> | ||
| 4416 | <event name="OnSize"></event> | ||
| 4417 | <event name="OnUpdateUI"></event> | ||
| 4418 | </object> | ||
| 4419 | </object> | ||
| 4420 | <object class="sizeritem" expanded="1"> | ||
| 4421 | <property name="border">5</property> | ||
| 4422 | <property name="flag">wxALL</property> | ||
| 4423 | <property name="proportion">0</property> | ||
| 4424 | <object class="wxButton" expanded="1"> | ||
| 4425 | <property name="bg"></property> | ||
| 4426 | <property name="context_help"></property> | ||
| 4427 | <property name="default">0</property> | ||
| 4428 | <property name="enabled">1</property> | ||
| 4429 | <property name="fg"></property> | ||
| 4430 | <property name="font"></property> | ||
| 4431 | <property name="hidden">0</property> | ||
| 4432 | <property name="id">wxID_BUTTONNEW</property> | ||
| 4433 | <property name="label">&New Address...</property> | ||
| 4434 | <property name="maximum_size"></property> | ||
| 4435 | <property name="minimum_size">110,25</property> | ||
| 4436 | <property name="name">m_buttonNew</property> | ||
| 4437 | <property name="permission">protected</property> | ||
| 4438 | <property name="pos"></property> | ||
| 4439 | <property name="size"></property> | ||
| 4440 | <property name="style"></property> | ||
| 4441 | <property name="subclass"></property> | ||
| 4442 | <property name="tooltip"></property> | ||
| 4443 | <property name="window_extra_style"></property> | ||
| 4444 | <property name="window_name"></property> | ||
| 4445 | <property name="window_style"></property> | ||
| 4446 | <event name="OnButtonClick">OnButtonNew</event> | ||
| 4447 | <event name="OnChar"></event> | ||
| 4448 | <event name="OnEnterWindow"></event> | ||
| 4449 | <event name="OnEraseBackground"></event> | ||
| 4450 | <event name="OnKeyDown"></event> | ||
| 4451 | <event name="OnKeyUp"></event> | ||
| 4452 | <event name="OnKillFocus"></event> | ||
| 4453 | <event name="OnLeaveWindow"></event> | ||
| 4454 | <event name="OnLeftDClick"></event> | ||
| 4455 | <event name="OnLeftDown"></event> | ||
| 4456 | <event name="OnLeftUp"></event> | ||
| 4457 | <event name="OnMiddleDClick"></event> | ||
| 4458 | <event name="OnMiddleDown"></event> | ||
| 4459 | <event name="OnMiddleUp"></event> | ||
| 4460 | <event name="OnMotion"></event> | ||
| 4461 | <event name="OnMouseEvents"></event> | ||
| 4462 | <event name="OnMouseWheel"></event> | ||
| 4463 | <event name="OnPaint"></event> | ||
| 4464 | <event name="OnRightDClick"></event> | ||
| 4465 | <event name="OnRightDown"></event> | ||
| 4466 | <event name="OnRightUp"></event> | ||
| 4467 | <event name="OnSetFocus"></event> | ||
| 4468 | <event name="OnSize"></event> | ||
| 4469 | <event name="OnUpdateUI"></event> | ||
| 4470 | </object> | ||
| 4471 | </object> | ||
| 4472 | <object class="sizeritem" expanded="1"> | ||
| 4473 | <property name="border">5</property> | ||
| 4474 | <property name="flag">wxALL</property> | ||
| 4475 | <property name="proportion">0</property> | ||
| 4476 | <object class="wxButton" expanded="1"> | ||
| 4477 | <property name="bg"></property> | ||
| 4478 | <property name="context_help"></property> | ||
| 4479 | <property name="default">0</property> | ||
| 4480 | <property name="enabled">1</property> | ||
| 4481 | <property name="fg"></property> | ||
| 4482 | <property name="font"></property> | ||
| 4483 | <property name="hidden">0</property> | ||
| 4484 | <property name="id">wxID_BUTTONDELETE</property> | ||
| 4485 | <property name="label">&Delete</property> | ||
| 4486 | <property name="maximum_size"></property> | ||
| 4487 | <property name="minimum_size">85,25</property> | ||
| 4488 | <property name="name">m_buttonDelete</property> | ||
| 4489 | <property name="permission">protected</property> | ||
| 4490 | <property name="pos"></property> | ||
| 4491 | <property name="size"></property> | ||
| 4492 | <property name="style"></property> | ||
| 4493 | <property name="subclass"></property> | ||
| 4494 | <property name="tooltip"></property> | ||
| 4495 | <property name="window_extra_style"></property> | ||
| 4496 | <property name="window_name"></property> | ||
| 4497 | <property name="window_style"></property> | ||
| 4498 | <event name="OnButtonClick">OnButtonDelete</event> | ||
| 4499 | <event name="OnChar"></event> | ||
| 4500 | <event name="OnEnterWindow"></event> | ||
| 4501 | <event name="OnEraseBackground"></event> | ||
| 4502 | <event name="OnKeyDown"></event> | ||
| 4503 | <event name="OnKeyUp"></event> | ||
| 4504 | <event name="OnKillFocus"></event> | ||
| 4505 | <event name="OnLeaveWindow"></event> | ||
| 4506 | <event name="OnLeftDClick"></event> | ||
| 4507 | <event name="OnLeftDown"></event> | ||
| 4508 | <event name="OnLeftUp"></event> | ||
| 4509 | <event name="OnMiddleDClick"></event> | ||
| 4510 | <event name="OnMiddleDown"></event> | ||
| 4511 | <event name="OnMiddleUp"></event> | ||
| 4512 | <event name="OnMotion"></event> | ||
| 4513 | <event name="OnMouseEvents"></event> | ||
| 4514 | <event name="OnMouseWheel"></event> | ||
| 4515 | <event name="OnPaint"></event> | ||
| 4516 | <event name="OnRightDClick"></event> | ||
| 4517 | <event name="OnRightDown"></event> | ||
| 4518 | <event name="OnRightUp"></event> | ||
| 4519 | <event name="OnSetFocus"></event> | ||
| 4520 | <event name="OnSize"></event> | ||
| 4521 | <event name="OnUpdateUI"></event> | ||
| 4522 | </object> | ||
| 4523 | </object> | ||
| 4524 | <object class="sizeritem" expanded="1"> | ||
| 4525 | <property name="border">5</property> | ||
| 4526 | <property name="flag">wxALL</property> | ||
| 4527 | <property name="proportion">0</property> | ||
| 4528 | <object class="wxButton" expanded="1"> | ||
| 4529 | <property name="bg"></property> | ||
| 4530 | <property name="context_help"></property> | ||
| 4531 | <property name="default">0</property> | ||
| 4532 | <property name="enabled">1</property> | ||
| 4533 | <property name="fg"></property> | ||
| 4534 | <property name="font"></property> | ||
| 4535 | <property name="hidden">0</property> | ||
| 4536 | <property name="id">wxID_OK</property> | ||
| 4537 | <property name="label">OK</property> | ||
| 4538 | <property name="maximum_size"></property> | ||
| 4539 | <property name="minimum_size">85,25</property> | ||
| 4540 | <property name="name">m_buttonOK</property> | ||
| 4541 | <property name="permission">protected</property> | ||
| 4542 | <property name="pos"></property> | ||
| 4543 | <property name="size">-1,-1</property> | ||
| 4544 | <property name="style"></property> | ||
| 4545 | <property name="subclass"></property> | ||
| 4546 | <property name="tooltip"></property> | ||
| 4547 | <property name="window_extra_style"></property> | ||
| 4548 | <property name="window_name"></property> | ||
| 4549 | <property name="window_style"></property> | ||
| 4550 | <event name="OnButtonClick">OnButtonOK</event> | ||
| 4551 | <event name="OnChar"></event> | ||
| 4552 | <event name="OnEnterWindow"></event> | ||
| 4553 | <event name="OnEraseBackground"></event> | ||
| 4554 | <event name="OnKeyDown"></event> | ||
| 4555 | <event name="OnKeyUp"></event> | ||
| 4556 | <event name="OnKillFocus"></event> | ||
| 4557 | <event name="OnLeaveWindow"></event> | ||
| 4558 | <event name="OnLeftDClick"></event> | ||
| 4559 | <event name="OnLeftDown"></event> | ||
| 4560 | <event name="OnLeftUp"></event> | ||
| 4561 | <event name="OnMiddleDClick"></event> | ||
| 4562 | <event name="OnMiddleDown"></event> | ||
| 4563 | <event name="OnMiddleUp"></event> | ||
| 4564 | <event name="OnMotion"></event> | ||
| 4565 | <event name="OnMouseEvents"></event> | ||
| 4566 | <event name="OnMouseWheel"></event> | ||
| 4567 | <event name="OnPaint"></event> | ||
| 4568 | <event name="OnRightDClick"></event> | ||
| 4569 | <event name="OnRightDown"></event> | ||
| 4570 | <event name="OnRightUp"></event> | ||
| 4571 | <event name="OnSetFocus"></event> | ||
| 4572 | <event name="OnSize"></event> | ||
| 4573 | <event name="OnUpdateUI"></event> | ||
| 4574 | </object> | ||
| 4575 | </object> | ||
| 4576 | <object class="sizeritem" expanded="1"> | ||
| 4577 | <property name="border">5</property> | ||
| 4578 | <property name="flag">wxALL</property> | ||
| 4579 | <property name="proportion">0</property> | ||
| 4580 | <object class="wxButton" expanded="1"> | ||
| 4581 | <property name="bg"></property> | ||
| 4582 | <property name="context_help"></property> | ||
| 4583 | <property name="default">0</property> | ||
| 4584 | <property name="enabled">1</property> | ||
| 4585 | <property name="fg"></property> | ||
| 4586 | <property name="font"></property> | ||
| 4587 | <property name="hidden">0</property> | ||
| 4588 | <property name="id">wxID_CANCEL</property> | ||
| 4589 | <property name="label">Cancel</property> | ||
| 4590 | <property name="maximum_size"></property> | ||
| 4591 | <property name="minimum_size">85,25</property> | ||
| 4592 | <property name="name">m_buttonCancel</property> | ||
| 4593 | <property name="permission">public</property> | ||
| 4594 | <property name="pos"></property> | ||
| 4595 | <property name="size">-1,-1</property> | ||
| 4596 | <property name="style"></property> | ||
| 4597 | <property name="subclass"></property> | ||
| 4598 | <property name="tooltip"></property> | ||
| 4599 | <property name="window_extra_style"></property> | ||
| 4600 | <property name="window_name"></property> | ||
| 4601 | <property name="window_style"></property> | ||
| 4602 | <event name="OnButtonClick">OnButtonCancel</event> | ||
| 4603 | <event name="OnChar"></event> | ||
| 4604 | <event name="OnEnterWindow"></event> | ||
| 4605 | <event name="OnEraseBackground"></event> | ||
| 4606 | <event name="OnKeyDown"></event> | ||
| 4607 | <event name="OnKeyUp"></event> | ||
| 4608 | <event name="OnKillFocus"></event> | ||
| 4609 | <event name="OnLeaveWindow"></event> | ||
| 4610 | <event name="OnLeftDClick"></event> | ||
| 4611 | <event name="OnLeftDown"></event> | ||
| 4612 | <event name="OnLeftUp"></event> | ||
| 4613 | <event name="OnMiddleDClick"></event> | ||
| 4614 | <event name="OnMiddleDown"></event> | ||
| 4615 | <event name="OnMiddleUp"></event> | ||
| 4616 | <event name="OnMotion"></event> | ||
| 4617 | <event name="OnMouseEvents"></event> | ||
| 4618 | <event name="OnMouseWheel"></event> | ||
| 4619 | <event name="OnPaint"></event> | ||
| 4620 | <event name="OnRightDClick"></event> | ||
| 4621 | <event name="OnRightDown"></event> | ||
| 4622 | <event name="OnRightUp"></event> | ||
| 4623 | <event name="OnSetFocus"></event> | ||
| 4624 | <event name="OnSize"></event> | ||
| 4625 | <event name="OnUpdateUI"></event> | ||
| 4626 | </object> | ||
| 4627 | </object> | ||
| 4628 | </object> | ||
| 4629 | </object> | ||
| 4630 | </object> | ||
| 4631 | </object> | ||
| 4632 | <object class="Dialog" expanded="0"> | ||
| 4633 | <property name="bg"></property> | ||
| 4634 | <property name="center"></property> | ||
| 4635 | <property name="context_help"></property> | ||
| 4636 | <property name="enabled">1</property> | ||
| 4637 | <property name="extra_style"></property> | ||
| 4638 | <property name="fg"></property> | ||
| 4639 | <property name="font"></property> | ||
| 4640 | <property name="hidden">0</property> | ||
| 4641 | <property name="id">wxID_ANY</property> | ||
| 4642 | <property name="maximum_size"></property> | ||
| 4643 | <property name="minimum_size"></property> | ||
| 4644 | <property name="name">CProductsDialogBase</property> | ||
| 4645 | <property name="pos"></property> | ||
| 4646 | <property name="size">708,535</property> | ||
| 4647 | <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property> | ||
| 4648 | <property name="subclass"></property> | ||
| 4649 | <property name="title">Marketplace</property> | ||
| 4650 | <property name="tooltip"></property> | ||
| 4651 | <property name="window_extra_style"></property> | ||
| 4652 | <property name="window_name"></property> | ||
| 4653 | <property name="window_style"></property> | ||
| 4654 | <event name="OnActivate"></event> | ||
| 4655 | <event name="OnActivateApp"></event> | ||
| 4656 | <event name="OnChar"></event> | ||
| 4657 | <event name="OnClose"></event> | ||
| 4658 | <event name="OnEnterWindow"></event> | ||
| 4659 | <event name="OnEraseBackground"></event> | ||
| 4660 | <event name="OnHibernate"></event> | ||
| 4661 | <event name="OnIconize"></event> | ||
| 4662 | <event name="OnIdle"></event> | ||
| 4663 | <event name="OnInitDialog"></event> | ||
| 4664 | <event name="OnKeyDown"></event> | ||
| 4665 | <event name="OnKeyUp"></event> | ||
| 4666 | <event name="OnKillFocus"></event> | ||
| 4667 | <event name="OnLeaveWindow"></event> | ||
| 4668 | <event name="OnLeftDClick"></event> | ||
| 4669 | <event name="OnLeftDown"></event> | ||
| 4670 | <event name="OnLeftUp"></event> | ||
| 4671 | <event name="OnMiddleDClick"></event> | ||
| 4672 | <event name="OnMiddleDown"></event> | ||
| 4673 | <event name="OnMiddleUp"></event> | ||
| 4674 | <event name="OnMotion"></event> | ||
| 4675 | <event name="OnMouseEvents"></event> | ||
| 4676 | <event name="OnMouseWheel"></event> | ||
| 4677 | <event name="OnPaint"></event> | ||
| 4678 | <event name="OnRightDClick"></event> | ||
| 4679 | <event name="OnRightDown"></event> | ||
| 4680 | <event name="OnRightUp"></event> | ||
| 4681 | <event name="OnSetFocus"></event> | ||
| 4682 | <event name="OnSize"></event> | ||
| 4683 | <event name="OnUpdateUI"></event> | ||
| 4684 | <object class="wxBoxSizer" expanded="1"> | ||
| 4685 | <property name="minimum_size"></property> | ||
| 4686 | <property name="name">bSizer22</property> | ||
| 4687 | <property name="orient">wxVERTICAL</property> | ||
| 4688 | <property name="permission">none</property> | ||
| 4689 | <object class="sizeritem" expanded="1"> | ||
| 4690 | <property name="border">5</property> | ||
| 4691 | <property name="flag">wxEXPAND|wxTOP|wxBOTTOM|wxRIGHT</property> | ||
| 4692 | <property name="proportion">0</property> | ||
| 4693 | <object class="wxBoxSizer" expanded="1"> | ||
| 4694 | <property name="minimum_size"></property> | ||
| 4695 | <property name="name">bSizer23</property> | ||
| 4696 | <property name="orient">wxHORIZONTAL</property> | ||
| 4697 | <property name="permission">none</property> | ||
| 4698 | <object class="sizeritem" expanded="1"> | ||
| 4699 | <property name="border">5</property> | ||
| 4700 | <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property> | ||
| 4701 | <property name="proportion">0</property> | ||
| 4702 | <object class="wxComboBox" expanded="1"> | ||
| 4703 | <property name="bg"></property> | ||
| 4704 | <property name="choices">"(Any Category)"</property> | ||
| 4705 | <property name="context_help"></property> | ||
| 4706 | <property name="enabled">1</property> | ||
| 4707 | <property name="fg"></property> | ||
| 4708 | <property name="font"></property> | ||
| 4709 | <property name="hidden">0</property> | ||
| 4710 | <property name="id">wxID_ANY</property> | ||
| 4711 | <property name="maximum_size"></property> | ||
| 4712 | <property name="minimum_size"></property> | ||
| 4713 | <property name="name">m_comboBoxCategory</property> | ||
| 4714 | <property name="permission">protected</property> | ||
| 4715 | <property name="pos"></property> | ||
| 4716 | <property name="size">150,-1</property> | ||
| 4717 | <property name="style"></property> | ||
| 4718 | <property name="subclass"></property> | ||
| 4719 | <property name="tooltip"></property> | ||
| 4720 | <property name="value">(Any Category)</property> | ||
| 4721 | <property name="window_extra_style"></property> | ||
| 4722 | <property name="window_name"></property> | ||
| 4723 | <property name="window_style"></property> | ||
| 4724 | <event name="OnChar"></event> | ||
| 4725 | <event name="OnCombobox">OnCombobox</event> | ||
| 4726 | <event name="OnEnterWindow"></event> | ||
| 4727 | <event name="OnEraseBackground"></event> | ||
| 4728 | <event name="OnKeyDown"></event> | ||
| 4729 | <event name="OnKeyUp"></event> | ||
| 4730 | <event name="OnKillFocus"></event> | ||
| 4731 | <event name="OnLeaveWindow"></event> | ||
| 4732 | <event name="OnLeftDClick"></event> | ||
| 4733 | <event name="OnLeftDown"></event> | ||
| 4734 | <event name="OnLeftUp"></event> | ||
| 4735 | <event name="OnMiddleDClick"></event> | ||
| 4736 | <event name="OnMiddleDown"></event> | ||
| 4737 | <event name="OnMiddleUp"></event> | ||
| 4738 | <event name="OnMotion"></event> | ||
| 4739 | <event name="OnMouseEvents"></event> | ||
| 4740 | <event name="OnMouseWheel"></event> | ||
| 4741 | <event name="OnPaint"></event> | ||
| 4742 | <event name="OnRightDClick"></event> | ||
| 4743 | <event name="OnRightDown"></event> | ||
| 4744 | <event name="OnRightUp"></event> | ||
| 4745 | <event name="OnSetFocus"></event> | ||
| 4746 | <event name="OnSize"></event> | ||
| 4747 | <event name="OnText"></event> | ||
| 4748 | <event name="OnTextEnter"></event> | ||
| 4749 | <event name="OnUpdateUI"></event> | ||
| 4750 | </object> | ||
| 4751 | </object> | ||
| 4752 | <object class="sizeritem" expanded="1"> | ||
| 4753 | <property name="border">5</property> | ||
| 4754 | <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property> | ||
| 4755 | <property name="proportion">1</property> | ||
| 4756 | <object class="wxTextCtrl" expanded="1"> | ||
| 4757 | <property name="bg"></property> | ||
| 4758 | <property name="context_help"></property> | ||
| 4759 | <property name="enabled">1</property> | ||
| 4760 | <property name="fg"></property> | ||
| 4761 | <property name="font"></property> | ||
| 4762 | <property name="hidden">0</property> | ||
| 4763 | <property name="id">wxID_ANY</property> | ||
| 4764 | <property name="maximum_size"></property> | ||
| 4765 | <property name="maxlength">0</property> | ||
| 4766 | <property name="minimum_size"></property> | ||
| 4767 | <property name="name">m_textCtrlSearch</property> | ||
| 4768 | <property name="permission">protected</property> | ||
| 4769 | <property name="pos"></property> | ||
| 4770 | <property name="size"></property> | ||
| 4771 | <property name="style"></property> | ||
| 4772 | <property name="subclass"></property> | ||
| 4773 | <property name="tooltip"></property> | ||
| 4774 | <property name="value"></property> | ||
| 4775 | <property name="window_extra_style"></property> | ||
| 4776 | <property name="window_name"></property> | ||
| 4777 | <property name="window_style"></property> | ||
| 4778 | <event name="OnChar"></event> | ||
| 4779 | <event name="OnEnterWindow"></event> | ||
| 4780 | <event name="OnEraseBackground"></event> | ||
| 4781 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 4782 | <event name="OnKeyUp"></event> | ||
| 4783 | <event name="OnKillFocus"></event> | ||
| 4784 | <event name="OnLeaveWindow"></event> | ||
| 4785 | <event name="OnLeftDClick"></event> | ||
| 4786 | <event name="OnLeftDown"></event> | ||
| 4787 | <event name="OnLeftUp"></event> | ||
| 4788 | <event name="OnMiddleDClick"></event> | ||
| 4789 | <event name="OnMiddleDown"></event> | ||
| 4790 | <event name="OnMiddleUp"></event> | ||
| 4791 | <event name="OnMotion"></event> | ||
| 4792 | <event name="OnMouseEvents"></event> | ||
| 4793 | <event name="OnMouseWheel"></event> | ||
| 4794 | <event name="OnPaint"></event> | ||
| 4795 | <event name="OnRightDClick"></event> | ||
| 4796 | <event name="OnRightDown"></event> | ||
| 4797 | <event name="OnRightUp"></event> | ||
| 4798 | <event name="OnSetFocus"></event> | ||
| 4799 | <event name="OnSize"></event> | ||
| 4800 | <event name="OnText"></event> | ||
| 4801 | <event name="OnTextEnter"></event> | ||
| 4802 | <event name="OnTextMaxLen"></event> | ||
| 4803 | <event name="OnTextURL"></event> | ||
| 4804 | <event name="OnUpdateUI"></event> | ||
| 4805 | </object> | ||
| 4806 | </object> | ||
| 4807 | <object class="sizeritem" expanded="1"> | ||
| 4808 | <property name="border">5</property> | ||
| 4809 | <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property> | ||
| 4810 | <property name="proportion">0</property> | ||
| 4811 | <object class="wxButton" expanded="1"> | ||
| 4812 | <property name="bg"></property> | ||
| 4813 | <property name="context_help"></property> | ||
| 4814 | <property name="default">0</property> | ||
| 4815 | <property name="enabled">1</property> | ||
| 4816 | <property name="fg"></property> | ||
| 4817 | <property name="font"></property> | ||
| 4818 | <property name="hidden">0</property> | ||
| 4819 | <property name="id">wxID_ANY</property> | ||
| 4820 | <property name="label">&Search</property> | ||
| 4821 | <property name="maximum_size"></property> | ||
| 4822 | <property name="minimum_size"></property> | ||
| 4823 | <property name="name">m_buttonSearch</property> | ||
| 4824 | <property name="permission">protected</property> | ||
| 4825 | <property name="pos"></property> | ||
| 4826 | <property name="size"></property> | ||
| 4827 | <property name="style"></property> | ||
| 4828 | <property name="subclass"></property> | ||
| 4829 | <property name="tooltip"></property> | ||
| 4830 | <property name="window_extra_style"></property> | ||
| 4831 | <property name="window_name"></property> | ||
| 4832 | <property name="window_style"></property> | ||
| 4833 | <event name="OnButtonClick">OnButtonSearch</event> | ||
| 4834 | <event name="OnChar"></event> | ||
| 4835 | <event name="OnEnterWindow"></event> | ||
| 4836 | <event name="OnEraseBackground"></event> | ||
| 4837 | <event name="OnKeyDown"></event> | ||
| 4838 | <event name="OnKeyUp"></event> | ||
| 4839 | <event name="OnKillFocus"></event> | ||
| 4840 | <event name="OnLeaveWindow"></event> | ||
| 4841 | <event name="OnLeftDClick"></event> | ||
| 4842 | <event name="OnLeftDown"></event> | ||
| 4843 | <event name="OnLeftUp"></event> | ||
| 4844 | <event name="OnMiddleDClick"></event> | ||
| 4845 | <event name="OnMiddleDown"></event> | ||
| 4846 | <event name="OnMiddleUp"></event> | ||
| 4847 | <event name="OnMotion"></event> | ||
| 4848 | <event name="OnMouseEvents"></event> | ||
| 4849 | <event name="OnMouseWheel"></event> | ||
| 4850 | <event name="OnPaint"></event> | ||
| 4851 | <event name="OnRightDClick"></event> | ||
| 4852 | <event name="OnRightDown"></event> | ||
| 4853 | <event name="OnRightUp"></event> | ||
| 4854 | <event name="OnSetFocus"></event> | ||
| 4855 | <event name="OnSize"></event> | ||
| 4856 | <event name="OnUpdateUI"></event> | ||
| 4857 | </object> | ||
| 4858 | </object> | ||
| 4859 | </object> | ||
| 4860 | </object> | ||
| 4861 | <object class="sizeritem" expanded="1"> | ||
| 4862 | <property name="border">5</property> | ||
| 4863 | <property name="flag">wxALL|wxEXPAND</property> | ||
| 4864 | <property name="proportion">1</property> | ||
| 4865 | <object class="wxListCtrl" expanded="1"> | ||
| 4866 | <property name="bg"></property> | ||
| 4867 | <property name="context_help"></property> | ||
| 4868 | <property name="enabled">1</property> | ||
| 4869 | <property name="fg"></property> | ||
| 4870 | <property name="font"></property> | ||
| 4871 | <property name="hidden">0</property> | ||
| 4872 | <property name="id">wxID_ANY</property> | ||
| 4873 | <property name="maximum_size"></property> | ||
| 4874 | <property name="minimum_size"></property> | ||
| 4875 | <property name="name">m_listCtrl</property> | ||
| 4876 | <property name="permission">protected</property> | ||
| 4877 | <property name="pos"></property> | ||
| 4878 | <property name="size"></property> | ||
| 4879 | <property name="style">wxLC_NO_SORT_HEADER|wxLC_REPORT</property> | ||
| 4880 | <property name="subclass"></property> | ||
| 4881 | <property name="tooltip"></property> | ||
| 4882 | <property name="window_extra_style"></property> | ||
| 4883 | <property name="window_name"></property> | ||
| 4884 | <property name="window_style"></property> | ||
| 4885 | <event name="OnChar"></event> | ||
| 4886 | <event name="OnEnterWindow"></event> | ||
| 4887 | <event name="OnEraseBackground"></event> | ||
| 4888 | <event name="OnKeyDown"></event> | ||
| 4889 | <event name="OnKeyUp"></event> | ||
| 4890 | <event name="OnKillFocus"></event> | ||
| 4891 | <event name="OnLeaveWindow"></event> | ||
| 4892 | <event name="OnLeftDClick"></event> | ||
| 4893 | <event name="OnLeftDown"></event> | ||
| 4894 | <event name="OnLeftUp"></event> | ||
| 4895 | <event name="OnListBeginDrag"></event> | ||
| 4896 | <event name="OnListBeginLabelEdit"></event> | ||
| 4897 | <event name="OnListBeginRDrag"></event> | ||
| 4898 | <event name="OnListCacheHint"></event> | ||
| 4899 | <event name="OnListColBeginDrag"></event> | ||
| 4900 | <event name="OnListColClick"></event> | ||
| 4901 | <event name="OnListColDragging"></event> | ||
| 4902 | <event name="OnListColEndDrag"></event> | ||
| 4903 | <event name="OnListColRightClick"></event> | ||
| 4904 | <event name="OnListDeleteAllItems"></event> | ||
| 4905 | <event name="OnListDeleteItem"></event> | ||
| 4906 | <event name="OnListEndLabelEdit"></event> | ||
| 4907 | <event name="OnListInsertItem"></event> | ||
| 4908 | <event name="OnListItemActivated">OnListItemActivated</event> | ||
| 4909 | <event name="OnListItemDeselected"></event> | ||
| 4910 | <event name="OnListItemFocused"></event> | ||
| 4911 | <event name="OnListItemMiddleClick"></event> | ||
| 4912 | <event name="OnListItemRightClick"></event> | ||
| 4913 | <event name="OnListItemSelected"></event> | ||
| 4914 | <event name="OnListKeyDown"></event> | ||
| 4915 | <event name="OnMiddleDClick"></event> | ||
| 4916 | <event name="OnMiddleDown"></event> | ||
| 4917 | <event name="OnMiddleUp"></event> | ||
| 4918 | <event name="OnMotion"></event> | ||
| 4919 | <event name="OnMouseEvents"></event> | ||
| 4920 | <event name="OnMouseWheel"></event> | ||
| 4921 | <event name="OnPaint"></event> | ||
| 4922 | <event name="OnRightDClick"></event> | ||
| 4923 | <event name="OnRightDown"></event> | ||
| 4924 | <event name="OnRightUp"></event> | ||
| 4925 | <event name="OnSetFocus"></event> | ||
| 4926 | <event name="OnSize"></event> | ||
| 4927 | <event name="OnUpdateUI"></event> | ||
| 4928 | </object> | ||
| 4929 | </object> | ||
| 4930 | </object> | ||
| 4931 | </object> | ||
| 4932 | <object class="Frame" expanded="0"> | ||
| 4933 | <property name="bg">wxSYS_COLOUR_MENU</property> | ||
| 4934 | <property name="center"></property> | ||
| 4935 | <property name="context_help"></property> | ||
| 4936 | <property name="enabled">1</property> | ||
| 4937 | <property name="extra_style"></property> | ||
| 4938 | <property name="fg"></property> | ||
| 4939 | <property name="font"></property> | ||
| 4940 | <property name="hidden">0</property> | ||
| 4941 | <property name="id">wxID_ANY</property> | ||
| 4942 | <property name="maximum_size"></property> | ||
| 4943 | <property name="minimum_size"></property> | ||
| 4944 | <property name="name">CEditProductDialogBase</property> | ||
| 4945 | <property name="pos"></property> | ||
| 4946 | <property name="size">660,640</property> | ||
| 4947 | <property name="style">wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER</property> | ||
| 4948 | <property name="subclass"></property> | ||
| 4949 | <property name="title">Edit Product</property> | ||
| 4950 | <property name="tooltip"></property> | ||
| 4951 | <property name="window_extra_style"></property> | ||
| 4952 | <property name="window_name"></property> | ||
| 4953 | <property name="window_style">wxTAB_TRAVERSAL</property> | ||
| 4954 | <property name="xrc_skip_sizer">1</property> | ||
| 4955 | <event name="OnActivate"></event> | ||
| 4956 | <event name="OnActivateApp"></event> | ||
| 4957 | <event name="OnChar"></event> | ||
| 4958 | <event name="OnClose"></event> | ||
| 4959 | <event name="OnEnterWindow"></event> | ||
| 4960 | <event name="OnEraseBackground"></event> | ||
| 4961 | <event name="OnHibernate"></event> | ||
| 4962 | <event name="OnIconize"></event> | ||
| 4963 | <event name="OnIdle"></event> | ||
| 4964 | <event name="OnKeyDown"></event> | ||
| 4965 | <event name="OnKeyUp"></event> | ||
| 4966 | <event name="OnKillFocus"></event> | ||
| 4967 | <event name="OnLeaveWindow"></event> | ||
| 4968 | <event name="OnLeftDClick"></event> | ||
| 4969 | <event name="OnLeftDown"></event> | ||
| 4970 | <event name="OnLeftUp"></event> | ||
| 4971 | <event name="OnMiddleDClick"></event> | ||
| 4972 | <event name="OnMiddleDown"></event> | ||
| 4973 | <event name="OnMiddleUp"></event> | ||
| 4974 | <event name="OnMotion"></event> | ||
| 4975 | <event name="OnMouseEvents"></event> | ||
| 4976 | <event name="OnMouseWheel"></event> | ||
| 4977 | <event name="OnPaint"></event> | ||
| 4978 | <event name="OnRightDClick"></event> | ||
| 4979 | <event name="OnRightDown"></event> | ||
| 4980 | <event name="OnRightUp"></event> | ||
| 4981 | <event name="OnSetFocus"></event> | ||
| 4982 | <event name="OnSize"></event> | ||
| 4983 | <event name="OnUpdateUI"></event> | ||
| 4984 | <object class="wxBoxSizer" expanded="1"> | ||
| 4985 | <property name="minimum_size"></property> | ||
| 4986 | <property name="name">bSizer20</property> | ||
| 4987 | <property name="orient">wxVERTICAL</property> | ||
| 4988 | <property name="permission">none</property> | ||
| 4989 | <object class="sizeritem" expanded="1"> | ||
| 4990 | <property name="border">5</property> | ||
| 4991 | <property name="flag">wxEXPAND|wxALL</property> | ||
| 4992 | <property name="proportion">1</property> | ||
| 4993 | <object class="wxScrolledWindow" expanded="1"> | ||
| 4994 | <property name="bg">wxSYS_COLOUR_WINDOW</property> | ||
| 4995 | <property name="context_help"></property> | ||
| 4996 | <property name="enabled">1</property> | ||
| 4997 | <property name="fg"></property> | ||
| 4998 | <property name="font"></property> | ||
| 4999 | <property name="hidden">0</property> | ||
| 5000 | <property name="id">wxID_ANY</property> | ||
| 5001 | <property name="maximum_size"></property> | ||
| 5002 | <property name="minimum_size"></property> | ||
| 5003 | <property name="name">m_scrolledWindow</property> | ||
| 5004 | <property name="permission">protected</property> | ||
| 5005 | <property name="pos"></property> | ||
| 5006 | <property name="scroll_rate_x">5</property> | ||
| 5007 | <property name="scroll_rate_y">5</property> | ||
| 5008 | <property name="size"></property> | ||
| 5009 | <property name="subclass"></property> | ||
| 5010 | <property name="tooltip"></property> | ||
| 5011 | <property name="window_extra_style"></property> | ||
| 5012 | <property name="window_name"></property> | ||
| 5013 | <property name="window_style">wxHSCROLL|wxTAB_TRAVERSAL|wxVSCROLL</property> | ||
| 5014 | <event name="OnChar"></event> | ||
| 5015 | <event name="OnEnterWindow"></event> | ||
| 5016 | <event name="OnEraseBackground"></event> | ||
| 5017 | <event name="OnKeyDown"></event> | ||
| 5018 | <event name="OnKeyUp"></event> | ||
| 5019 | <event name="OnKillFocus"></event> | ||
| 5020 | <event name="OnLeaveWindow"></event> | ||
| 5021 | <event name="OnLeftDClick"></event> | ||
| 5022 | <event name="OnLeftDown"></event> | ||
| 5023 | <event name="OnLeftUp"></event> | ||
| 5024 | <event name="OnMiddleDClick"></event> | ||
| 5025 | <event name="OnMiddleDown"></event> | ||
| 5026 | <event name="OnMiddleUp"></event> | ||
| 5027 | <event name="OnMotion"></event> | ||
| 5028 | <event name="OnMouseEvents"></event> | ||
| 5029 | <event name="OnMouseWheel"></event> | ||
| 5030 | <event name="OnPaint"></event> | ||
| 5031 | <event name="OnRightDClick"></event> | ||
| 5032 | <event name="OnRightDown"></event> | ||
| 5033 | <event name="OnRightUp"></event> | ||
| 5034 | <event name="OnSetFocus"></event> | ||
| 5035 | <event name="OnSize"></event> | ||
| 5036 | <event name="OnUpdateUI"></event> | ||
| 5037 | <object class="wxBoxSizer" expanded="1"> | ||
| 5038 | <property name="minimum_size"></property> | ||
| 5039 | <property name="name">bSizer21</property> | ||
| 5040 | <property name="orient">wxVERTICAL</property> | ||
| 5041 | <property name="permission">none</property> | ||
| 5042 | <object class="sizeritem" expanded="1"> | ||
| 5043 | <property name="border">5</property> | ||
| 5044 | <property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property> | ||
| 5045 | <property name="proportion">0</property> | ||
| 5046 | <object class="wxFlexGridSizer" expanded="1"> | ||
| 5047 | <property name="cols">2</property> | ||
| 5048 | <property name="flexible_direction">wxBOTH</property> | ||
| 5049 | <property name="growablecols">1</property> | ||
| 5050 | <property name="growablerows"></property> | ||
| 5051 | <property name="hgap">0</property> | ||
| 5052 | <property name="minimum_size"></property> | ||
| 5053 | <property name="name">fgSizer8</property> | ||
| 5054 | <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property> | ||
| 5055 | <property name="permission">none</property> | ||
| 5056 | <property name="rows">0</property> | ||
| 5057 | <property name="vgap">0</property> | ||
| 5058 | <object class="sizeritem" expanded="1"> | ||
| 5059 | <property name="border">5</property> | ||
| 5060 | <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT</property> | ||
| 5061 | <property name="proportion">0</property> | ||
| 5062 | <object class="wxStaticText" expanded="1"> | ||
| 5063 | <property name="bg"></property> | ||
| 5064 | <property name="context_help"></property> | ||
| 5065 | <property name="enabled">1</property> | ||
| 5066 | <property name="fg"></property> | ||
| 5067 | <property name="font"></property> | ||
| 5068 | <property name="hidden">0</property> | ||
| 5069 | <property name="id">wxID_ANY</property> | ||
| 5070 | <property name="label">Category</property> | ||
| 5071 | <property name="maximum_size"></property> | ||
| 5072 | <property name="minimum_size"></property> | ||
| 5073 | <property name="name">m_staticText106</property> | ||
| 5074 | <property name="permission">protected</property> | ||
| 5075 | <property name="pos"></property> | ||
| 5076 | <property name="size"></property> | ||
| 5077 | <property name="style">wxALIGN_RIGHT</property> | ||
| 5078 | <property name="subclass"></property> | ||
| 5079 | <property name="tooltip"></property> | ||
| 5080 | <property name="window_extra_style"></property> | ||
| 5081 | <property name="window_name"></property> | ||
| 5082 | <property name="window_style"></property> | ||
| 5083 | <property name="wrap">-1</property> | ||
| 5084 | <event name="OnChar"></event> | ||
| 5085 | <event name="OnEnterWindow"></event> | ||
| 5086 | <event name="OnEraseBackground"></event> | ||
| 5087 | <event name="OnKeyDown"></event> | ||
| 5088 | <event name="OnKeyUp"></event> | ||
| 5089 | <event name="OnKillFocus"></event> | ||
| 5090 | <event name="OnLeaveWindow"></event> | ||
| 5091 | <event name="OnLeftDClick"></event> | ||
| 5092 | <event name="OnLeftDown"></event> | ||
| 5093 | <event name="OnLeftUp"></event> | ||
| 5094 | <event name="OnMiddleDClick"></event> | ||
| 5095 | <event name="OnMiddleDown"></event> | ||
| 5096 | <event name="OnMiddleUp"></event> | ||
| 5097 | <event name="OnMotion"></event> | ||
| 5098 | <event name="OnMouseEvents"></event> | ||
| 5099 | <event name="OnMouseWheel"></event> | ||
| 5100 | <event name="OnPaint"></event> | ||
| 5101 | <event name="OnRightDClick"></event> | ||
| 5102 | <event name="OnRightDown"></event> | ||
| 5103 | <event name="OnRightUp"></event> | ||
| 5104 | <event name="OnSetFocus"></event> | ||
| 5105 | <event name="OnSize"></event> | ||
| 5106 | <event name="OnUpdateUI"></event> | ||
| 5107 | </object> | ||
| 5108 | </object> | ||
| 5109 | <object class="sizeritem" expanded="1"> | ||
| 5110 | <property name="border">5</property> | ||
| 5111 | <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property> | ||
| 5112 | <property name="proportion">0</property> | ||
| 5113 | <object class="wxComboBox" expanded="1"> | ||
| 5114 | <property name="bg"></property> | ||
| 5115 | <property name="choices"></property> | ||
| 5116 | <property name="context_help"></property> | ||
| 5117 | <property name="enabled">1</property> | ||
| 5118 | <property name="fg"></property> | ||
| 5119 | <property name="font"></property> | ||
| 5120 | <property name="hidden">0</property> | ||
| 5121 | <property name="id">wxID_ANY</property> | ||
| 5122 | <property name="maximum_size"></property> | ||
| 5123 | <property name="minimum_size">180,-1</property> | ||
| 5124 | <property name="name">m_comboBoxCategory</property> | ||
| 5125 | <property name="permission">protected</property> | ||
| 5126 | <property name="pos"></property> | ||
| 5127 | <property name="size"></property> | ||
| 5128 | <property name="style"></property> | ||
| 5129 | <property name="subclass"></property> | ||
| 5130 | <property name="tooltip"></property> | ||
| 5131 | <property name="value"></property> | ||
| 5132 | <property name="window_extra_style"></property> | ||
| 5133 | <property name="window_name"></property> | ||
| 5134 | <property name="window_style"></property> | ||
| 5135 | <event name="OnChar"></event> | ||
| 5136 | <event name="OnCombobox"></event> | ||
| 5137 | <event name="OnEnterWindow"></event> | ||
| 5138 | <event name="OnEraseBackground"></event> | ||
| 5139 | <event name="OnKeyDown"></event> | ||
| 5140 | <event name="OnKeyUp"></event> | ||
| 5141 | <event name="OnKillFocus"></event> | ||
| 5142 | <event name="OnLeaveWindow"></event> | ||
| 5143 | <event name="OnLeftDClick"></event> | ||
| 5144 | <event name="OnLeftDown"></event> | ||
| 5145 | <event name="OnLeftUp"></event> | ||
| 5146 | <event name="OnMiddleDClick"></event> | ||
| 5147 | <event name="OnMiddleDown"></event> | ||
| 5148 | <event name="OnMiddleUp"></event> | ||
| 5149 | <event name="OnMotion"></event> | ||
| 5150 | <event name="OnMouseEvents"></event> | ||
| 5151 | <event name="OnMouseWheel"></event> | ||
| 5152 | <event name="OnPaint"></event> | ||
| 5153 | <event name="OnRightDClick"></event> | ||
| 5154 | <event name="OnRightDown"></event> | ||
| 5155 | <event name="OnRightUp"></event> | ||
| 5156 | <event name="OnSetFocus"></event> | ||
| 5157 | <event name="OnSize"></event> | ||
| 5158 | <event name="OnText"></event> | ||
| 5159 | <event name="OnTextEnter"></event> | ||
| 5160 | <event name="OnUpdateUI"></event> | ||
| 5161 | </object> | ||
| 5162 | </object> | ||
| 5163 | <object class="sizeritem" expanded="1"> | ||
| 5164 | <property name="border">5</property> | ||
| 5165 | <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT</property> | ||
| 5166 | <property name="proportion">0</property> | ||
| 5167 | <object class="wxStaticText" expanded="1"> | ||
| 5168 | <property name="bg"></property> | ||
| 5169 | <property name="context_help"></property> | ||
| 5170 | <property name="enabled">1</property> | ||
| 5171 | <property name="fg"></property> | ||
| 5172 | <property name="font"></property> | ||
| 5173 | <property name="hidden">0</property> | ||
| 5174 | <property name="id">wxID_ANY</property> | ||
| 5175 | <property name="label">Title</property> | ||
| 5176 | <property name="maximum_size"></property> | ||
| 5177 | <property name="minimum_size"></property> | ||
| 5178 | <property name="name">m_staticText108</property> | ||
| 5179 | <property name="permission">protected</property> | ||
| 5180 | <property name="pos"></property> | ||
| 5181 | <property name="size"></property> | ||
| 5182 | <property name="style">wxALIGN_RIGHT</property> | ||
| 5183 | <property name="subclass"></property> | ||
| 5184 | <property name="tooltip"></property> | ||
| 5185 | <property name="window_extra_style"></property> | ||
| 5186 | <property name="window_name"></property> | ||
| 5187 | <property name="window_style"></property> | ||
| 5188 | <property name="wrap">-1</property> | ||
| 5189 | <event name="OnChar"></event> | ||
| 5190 | <event name="OnEnterWindow"></event> | ||
| 5191 | <event name="OnEraseBackground"></event> | ||
| 5192 | <event name="OnKeyDown"></event> | ||
| 5193 | <event name="OnKeyUp"></event> | ||
| 5194 | <event name="OnKillFocus"></event> | ||
| 5195 | <event name="OnLeaveWindow"></event> | ||
| 5196 | <event name="OnLeftDClick"></event> | ||
| 5197 | <event name="OnLeftDown"></event> | ||
| 5198 | <event name="OnLeftUp"></event> | ||
| 5199 | <event name="OnMiddleDClick"></event> | ||
| 5200 | <event name="OnMiddleDown"></event> | ||
| 5201 | <event name="OnMiddleUp"></event> | ||
| 5202 | <event name="OnMotion"></event> | ||
| 5203 | <event name="OnMouseEvents"></event> | ||
| 5204 | <event name="OnMouseWheel"></event> | ||
| 5205 | <event name="OnPaint"></event> | ||
| 5206 | <event name="OnRightDClick"></event> | ||
| 5207 | <event name="OnRightDown"></event> | ||
| 5208 | <event name="OnRightUp"></event> | ||
| 5209 | <event name="OnSetFocus"></event> | ||
| 5210 | <event name="OnSize"></event> | ||
| 5211 | <event name="OnUpdateUI"></event> | ||
| 5212 | </object> | ||
| 5213 | </object> | ||
| 5214 | <object class="sizeritem" expanded="1"> | ||
| 5215 | <property name="border">5</property> | ||
| 5216 | <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property> | ||
| 5217 | <property name="proportion">1</property> | ||
| 5218 | <object class="wxTextCtrl" expanded="1"> | ||
| 5219 | <property name="bg"></property> | ||
| 5220 | <property name="context_help"></property> | ||
| 5221 | <property name="enabled">1</property> | ||
| 5222 | <property name="fg"></property> | ||
| 5223 | <property name="font"></property> | ||
| 5224 | <property name="hidden">0</property> | ||
| 5225 | <property name="id">wxID_ANY</property> | ||
| 5226 | <property name="maximum_size"></property> | ||
| 5227 | <property name="maxlength">0</property> | ||
| 5228 | <property name="minimum_size"></property> | ||
| 5229 | <property name="name">m_textCtrlTitle</property> | ||
| 5230 | <property name="permission">protected</property> | ||
| 5231 | <property name="pos"></property> | ||
| 5232 | <property name="size"></property> | ||
| 5233 | <property name="style"></property> | ||
| 5234 | <property name="subclass"></property> | ||
| 5235 | <property name="tooltip"></property> | ||
| 5236 | <property name="value"></property> | ||
| 5237 | <property name="window_extra_style"></property> | ||
| 5238 | <property name="window_name"></property> | ||
| 5239 | <property name="window_style"></property> | ||
| 5240 | <event name="OnChar"></event> | ||
| 5241 | <event name="OnEnterWindow"></event> | ||
| 5242 | <event name="OnEraseBackground"></event> | ||
| 5243 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 5244 | <event name="OnKeyUp"></event> | ||
| 5245 | <event name="OnKillFocus"></event> | ||
| 5246 | <event name="OnLeaveWindow"></event> | ||
| 5247 | <event name="OnLeftDClick"></event> | ||
| 5248 | <event name="OnLeftDown"></event> | ||
| 5249 | <event name="OnLeftUp"></event> | ||
| 5250 | <event name="OnMiddleDClick"></event> | ||
| 5251 | <event name="OnMiddleDown"></event> | ||
| 5252 | <event name="OnMiddleUp"></event> | ||
| 5253 | <event name="OnMotion"></event> | ||
| 5254 | <event name="OnMouseEvents"></event> | ||
| 5255 | <event name="OnMouseWheel"></event> | ||
| 5256 | <event name="OnPaint"></event> | ||
| 5257 | <event name="OnRightDClick"></event> | ||
| 5258 | <event name="OnRightDown"></event> | ||
| 5259 | <event name="OnRightUp"></event> | ||
| 5260 | <event name="OnSetFocus"></event> | ||
| 5261 | <event name="OnSize"></event> | ||
| 5262 | <event name="OnText"></event> | ||
| 5263 | <event name="OnTextEnter"></event> | ||
| 5264 | <event name="OnTextMaxLen"></event> | ||
| 5265 | <event name="OnTextURL"></event> | ||
| 5266 | <event name="OnUpdateUI"></event> | ||
| 5267 | </object> | ||
| 5268 | </object> | ||
| 5269 | <object class="sizeritem" expanded="1"> | ||
| 5270 | <property name="border">5</property> | ||
| 5271 | <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT</property> | ||
| 5272 | <property name="proportion">0</property> | ||
| 5273 | <object class="wxStaticText" expanded="1"> | ||
| 5274 | <property name="bg"></property> | ||
| 5275 | <property name="context_help"></property> | ||
| 5276 | <property name="enabled">1</property> | ||
| 5277 | <property name="fg"></property> | ||
| 5278 | <property name="font"></property> | ||
| 5279 | <property name="hidden">0</property> | ||
| 5280 | <property name="id">wxID_ANY</property> | ||
| 5281 | <property name="label">Price</property> | ||
| 5282 | <property name="maximum_size"></property> | ||
| 5283 | <property name="minimum_size"></property> | ||
| 5284 | <property name="name">m_staticText107</property> | ||
| 5285 | <property name="permission">protected</property> | ||
| 5286 | <property name="pos"></property> | ||
| 5287 | <property name="size"></property> | ||
| 5288 | <property name="style">wxALIGN_RIGHT</property> | ||
| 5289 | <property name="subclass"></property> | ||
| 5290 | <property name="tooltip"></property> | ||
| 5291 | <property name="window_extra_style"></property> | ||
| 5292 | <property name="window_name"></property> | ||
| 5293 | <property name="window_style"></property> | ||
| 5294 | <property name="wrap">-1</property> | ||
| 5295 | <event name="OnChar"></event> | ||
| 5296 | <event name="OnEnterWindow"></event> | ||
| 5297 | <event name="OnEraseBackground"></event> | ||
| 5298 | <event name="OnKeyDown"></event> | ||
| 5299 | <event name="OnKeyUp"></event> | ||
| 5300 | <event name="OnKillFocus"></event> | ||
| 5301 | <event name="OnLeaveWindow"></event> | ||
| 5302 | <event name="OnLeftDClick"></event> | ||
| 5303 | <event name="OnLeftDown"></event> | ||
| 5304 | <event name="OnLeftUp"></event> | ||
| 5305 | <event name="OnMiddleDClick"></event> | ||
| 5306 | <event name="OnMiddleDown"></event> | ||
| 5307 | <event name="OnMiddleUp"></event> | ||
| 5308 | <event name="OnMotion"></event> | ||
| 5309 | <event name="OnMouseEvents"></event> | ||
| 5310 | <event name="OnMouseWheel"></event> | ||
| 5311 | <event name="OnPaint"></event> | ||
| 5312 | <event name="OnRightDClick"></event> | ||
| 5313 | <event name="OnRightDown"></event> | ||
| 5314 | <event name="OnRightUp"></event> | ||
| 5315 | <event name="OnSetFocus"></event> | ||
| 5316 | <event name="OnSize"></event> | ||
| 5317 | <event name="OnUpdateUI"></event> | ||
| 5318 | </object> | ||
| 5319 | </object> | ||
| 5320 | <object class="sizeritem" expanded="1"> | ||
| 5321 | <property name="border">5</property> | ||
| 5322 | <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property> | ||
| 5323 | <property name="proportion">0</property> | ||
| 5324 | <object class="wxTextCtrl" expanded="1"> | ||
| 5325 | <property name="bg"></property> | ||
| 5326 | <property name="context_help"></property> | ||
| 5327 | <property name="enabled">1</property> | ||
| 5328 | <property name="fg"></property> | ||
| 5329 | <property name="font"></property> | ||
| 5330 | <property name="hidden">0</property> | ||
| 5331 | <property name="id">wxID_ANY</property> | ||
| 5332 | <property name="maximum_size"></property> | ||
| 5333 | <property name="maxlength">0</property> | ||
| 5334 | <property name="minimum_size">105,-1</property> | ||
| 5335 | <property name="name">m_textCtrlPrice</property> | ||
| 5336 | <property name="permission">protected</property> | ||
| 5337 | <property name="pos"></property> | ||
| 5338 | <property name="size"></property> | ||
| 5339 | <property name="style"></property> | ||
| 5340 | <property name="subclass"></property> | ||
| 5341 | <property name="tooltip"></property> | ||
| 5342 | <property name="value"></property> | ||
| 5343 | <property name="window_extra_style"></property> | ||
| 5344 | <property name="window_name"></property> | ||
| 5345 | <property name="window_style"></property> | ||
| 5346 | <event name="OnChar"></event> | ||
| 5347 | <event name="OnEnterWindow"></event> | ||
| 5348 | <event name="OnEraseBackground"></event> | ||
| 5349 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 5350 | <event name="OnKeyUp"></event> | ||
| 5351 | <event name="OnKillFocus"></event> | ||
| 5352 | <event name="OnLeaveWindow"></event> | ||
| 5353 | <event name="OnLeftDClick"></event> | ||
| 5354 | <event name="OnLeftDown"></event> | ||
| 5355 | <event name="OnLeftUp"></event> | ||
| 5356 | <event name="OnMiddleDClick"></event> | ||
| 5357 | <event name="OnMiddleDown"></event> | ||
| 5358 | <event name="OnMiddleUp"></event> | ||
| 5359 | <event name="OnMotion"></event> | ||
| 5360 | <event name="OnMouseEvents"></event> | ||
| 5361 | <event name="OnMouseWheel"></event> | ||
| 5362 | <event name="OnPaint"></event> | ||
| 5363 | <event name="OnRightDClick"></event> | ||
| 5364 | <event name="OnRightDown"></event> | ||
| 5365 | <event name="OnRightUp"></event> | ||
| 5366 | <event name="OnSetFocus"></event> | ||
| 5367 | <event name="OnSize"></event> | ||
| 5368 | <event name="OnText"></event> | ||
| 5369 | <event name="OnTextEnter"></event> | ||
| 5370 | <event name="OnTextMaxLen"></event> | ||
| 5371 | <event name="OnTextURL"></event> | ||
| 5372 | <event name="OnUpdateUI"></event> | ||
| 5373 | </object> | ||
| 5374 | </object> | ||
| 5375 | </object> | ||
| 5376 | </object> | ||
| 5377 | <object class="sizeritem" expanded="1"> | ||
| 5378 | <property name="border">5</property> | ||
| 5379 | <property name="flag">wxTOP|wxRIGHT|wxLEFT</property> | ||
| 5380 | <property name="proportion">0</property> | ||
| 5381 | <object class="wxStaticText" expanded="1"> | ||
| 5382 | <property name="bg"></property> | ||
| 5383 | <property name="context_help"></property> | ||
| 5384 | <property name="enabled">1</property> | ||
| 5385 | <property name="fg"></property> | ||
| 5386 | <property name="font"></property> | ||
| 5387 | <property name="hidden">0</property> | ||
| 5388 | <property name="id">wxID_ANY</property> | ||
| 5389 | <property name="label">Page 1: Description</property> | ||
| 5390 | <property name="maximum_size"></property> | ||
| 5391 | <property name="minimum_size"></property> | ||
| 5392 | <property name="name">m_staticText22</property> | ||
| 5393 | <property name="permission">protected</property> | ||
| 5394 | <property name="pos"></property> | ||
| 5395 | <property name="size"></property> | ||
| 5396 | <property name="style"></property> | ||
| 5397 | <property name="subclass"></property> | ||
| 5398 | <property name="tooltip"></property> | ||
| 5399 | <property name="window_extra_style"></property> | ||
| 5400 | <property name="window_name"></property> | ||
| 5401 | <property name="window_style"></property> | ||
| 5402 | <property name="wrap">-1</property> | ||
| 5403 | <event name="OnChar"></event> | ||
| 5404 | <event name="OnEnterWindow"></event> | ||
| 5405 | <event name="OnEraseBackground"></event> | ||
| 5406 | <event name="OnKeyDown"></event> | ||
| 5407 | <event name="OnKeyUp"></event> | ||
| 5408 | <event name="OnKillFocus"></event> | ||
| 5409 | <event name="OnLeaveWindow"></event> | ||
| 5410 | <event name="OnLeftDClick"></event> | ||
| 5411 | <event name="OnLeftDown"></event> | ||
| 5412 | <event name="OnLeftUp"></event> | ||
| 5413 | <event name="OnMiddleDClick"></event> | ||
| 5414 | <event name="OnMiddleDown"></event> | ||
| 5415 | <event name="OnMiddleUp"></event> | ||
| 5416 | <event name="OnMotion"></event> | ||
| 5417 | <event name="OnMouseEvents"></event> | ||
| 5418 | <event name="OnMouseWheel"></event> | ||
| 5419 | <event name="OnPaint"></event> | ||
| 5420 | <event name="OnRightDClick"></event> | ||
| 5421 | <event name="OnRightDown"></event> | ||
| 5422 | <event name="OnRightUp"></event> | ||
| 5423 | <event name="OnSetFocus"></event> | ||
| 5424 | <event name="OnSize"></event> | ||
| 5425 | <event name="OnUpdateUI"></event> | ||
| 5426 | </object> | ||
| 5427 | </object> | ||
| 5428 | <object class="sizeritem" expanded="1"> | ||
| 5429 | <property name="border">5</property> | ||
| 5430 | <property name="flag">wxALL|wxEXPAND</property> | ||
| 5431 | <property name="proportion">0</property> | ||
| 5432 | <object class="wxTextCtrl" expanded="1"> | ||
| 5433 | <property name="bg"></property> | ||
| 5434 | <property name="context_help"></property> | ||
| 5435 | <property name="enabled">1</property> | ||
| 5436 | <property name="fg"></property> | ||
| 5437 | <property name="font"></property> | ||
| 5438 | <property name="hidden">0</property> | ||
| 5439 | <property name="id">wxID_ANY</property> | ||
| 5440 | <property name="maximum_size"></property> | ||
| 5441 | <property name="maxlength">0</property> | ||
| 5442 | <property name="minimum_size">-1,170</property> | ||
| 5443 | <property name="name">m_textCtrlDescription</property> | ||
| 5444 | <property name="permission">protected</property> | ||
| 5445 | <property name="pos"></property> | ||
| 5446 | <property name="size"></property> | ||
| 5447 | <property name="style">wxTE_MULTILINE</property> | ||
| 5448 | <property name="subclass"></property> | ||
| 5449 | <property name="tooltip"></property> | ||
| 5450 | <property name="value"></property> | ||
| 5451 | <property name="window_extra_style"></property> | ||
| 5452 | <property name="window_name"></property> | ||
| 5453 | <property name="window_style"></property> | ||
| 5454 | <event name="OnChar"></event> | ||
| 5455 | <event name="OnEnterWindow"></event> | ||
| 5456 | <event name="OnEraseBackground"></event> | ||
| 5457 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 5458 | <event name="OnKeyUp"></event> | ||
| 5459 | <event name="OnKillFocus"></event> | ||
| 5460 | <event name="OnLeaveWindow"></event> | ||
| 5461 | <event name="OnLeftDClick"></event> | ||
| 5462 | <event name="OnLeftDown"></event> | ||
| 5463 | <event name="OnLeftUp"></event> | ||
| 5464 | <event name="OnMiddleDClick"></event> | ||
| 5465 | <event name="OnMiddleDown"></event> | ||
| 5466 | <event name="OnMiddleUp"></event> | ||
| 5467 | <event name="OnMotion"></event> | ||
| 5468 | <event name="OnMouseEvents"></event> | ||
| 5469 | <event name="OnMouseWheel"></event> | ||
| 5470 | <event name="OnPaint"></event> | ||
| 5471 | <event name="OnRightDClick"></event> | ||
| 5472 | <event name="OnRightDown"></event> | ||
| 5473 | <event name="OnRightUp"></event> | ||
| 5474 | <event name="OnSetFocus"></event> | ||
| 5475 | <event name="OnSize"></event> | ||
| 5476 | <event name="OnText"></event> | ||
| 5477 | <event name="OnTextEnter"></event> | ||
| 5478 | <event name="OnTextMaxLen"></event> | ||
| 5479 | <event name="OnTextURL"></event> | ||
| 5480 | <event name="OnUpdateUI"></event> | ||
| 5481 | </object> | ||
| 5482 | </object> | ||
| 5483 | <object class="sizeritem" expanded="1"> | ||
| 5484 | <property name="border">5</property> | ||
| 5485 | <property name="flag">wxTOP|wxRIGHT|wxLEFT</property> | ||
| 5486 | <property name="proportion">0</property> | ||
| 5487 | <object class="wxStaticText" expanded="1"> | ||
| 5488 | <property name="bg"></property> | ||
| 5489 | <property name="context_help"></property> | ||
| 5490 | <property name="enabled">1</property> | ||
| 5491 | <property name="fg"></property> | ||
| 5492 | <property name="font"></property> | ||
| 5493 | <property name="hidden">0</property> | ||
| 5494 | <property name="id">wxID_ANY</property> | ||
| 5495 | <property name="label">Page 2: Order Form</property> | ||
| 5496 | <property name="maximum_size"></property> | ||
| 5497 | <property name="minimum_size"></property> | ||
| 5498 | <property name="name">m_staticText23</property> | ||
| 5499 | <property name="permission">protected</property> | ||
| 5500 | <property name="pos"></property> | ||
| 5501 | <property name="size"></property> | ||
| 5502 | <property name="style"></property> | ||
| 5503 | <property name="subclass"></property> | ||
| 5504 | <property name="tooltip"></property> | ||
| 5505 | <property name="window_extra_style"></property> | ||
| 5506 | <property name="window_name"></property> | ||
| 5507 | <property name="window_style"></property> | ||
| 5508 | <property name="wrap">-1</property> | ||
| 5509 | <event name="OnChar"></event> | ||
| 5510 | <event name="OnEnterWindow"></event> | ||
| 5511 | <event name="OnEraseBackground"></event> | ||
| 5512 | <event name="OnKeyDown"></event> | ||
| 5513 | <event name="OnKeyUp"></event> | ||
| 5514 | <event name="OnKillFocus"></event> | ||
| 5515 | <event name="OnLeaveWindow"></event> | ||
| 5516 | <event name="OnLeftDClick"></event> | ||
| 5517 | <event name="OnLeftDown"></event> | ||
| 5518 | <event name="OnLeftUp"></event> | ||
| 5519 | <event name="OnMiddleDClick"></event> | ||
| 5520 | <event name="OnMiddleDown"></event> | ||
| 5521 | <event name="OnMiddleUp"></event> | ||
| 5522 | <event name="OnMotion"></event> | ||
| 5523 | <event name="OnMouseEvents"></event> | ||
| 5524 | <event name="OnMouseWheel"></event> | ||
| 5525 | <event name="OnPaint"></event> | ||
| 5526 | <event name="OnRightDClick"></event> | ||
| 5527 | <event name="OnRightDown"></event> | ||
| 5528 | <event name="OnRightUp"></event> | ||
| 5529 | <event name="OnSetFocus"></event> | ||
| 5530 | <event name="OnSize"></event> | ||
| 5531 | <event name="OnUpdateUI"></event> | ||
| 5532 | </object> | ||
| 5533 | </object> | ||
| 5534 | <object class="sizeritem" expanded="1"> | ||
| 5535 | <property name="border">5</property> | ||
| 5536 | <property name="flag">wxEXPAND|wxALL</property> | ||
| 5537 | <property name="proportion">0</property> | ||
| 5538 | <object class="wxTextCtrl" expanded="1"> | ||
| 5539 | <property name="bg"></property> | ||
| 5540 | <property name="context_help"></property> | ||
| 5541 | <property name="enabled">1</property> | ||
| 5542 | <property name="fg"></property> | ||
| 5543 | <property name="font"></property> | ||
| 5544 | <property name="hidden">0</property> | ||
| 5545 | <property name="id">wxID_ANY</property> | ||
| 5546 | <property name="maximum_size"></property> | ||
| 5547 | <property name="maxlength">0</property> | ||
| 5548 | <property name="minimum_size">-1,120</property> | ||
| 5549 | <property name="name">m_textCtrlInstructions</property> | ||
| 5550 | <property name="permission">protected</property> | ||
| 5551 | <property name="pos"></property> | ||
| 5552 | <property name="size"></property> | ||
| 5553 | <property name="style">wxTE_MULTILINE</property> | ||
| 5554 | <property name="subclass"></property> | ||
| 5555 | <property name="tooltip"></property> | ||
| 5556 | <property name="value"></property> | ||
| 5557 | <property name="window_extra_style"></property> | ||
| 5558 | <property name="window_name"></property> | ||
| 5559 | <property name="window_style"></property> | ||
| 5560 | <event name="OnChar"></event> | ||
| 5561 | <event name="OnEnterWindow"></event> | ||
| 5562 | <event name="OnEraseBackground"></event> | ||
| 5563 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 5564 | <event name="OnKeyUp"></event> | ||
| 5565 | <event name="OnKillFocus"></event> | ||
| 5566 | <event name="OnLeaveWindow"></event> | ||
| 5567 | <event name="OnLeftDClick"></event> | ||
| 5568 | <event name="OnLeftDown"></event> | ||
| 5569 | <event name="OnLeftUp"></event> | ||
| 5570 | <event name="OnMiddleDClick"></event> | ||
| 5571 | <event name="OnMiddleDown"></event> | ||
| 5572 | <event name="OnMiddleUp"></event> | ||
| 5573 | <event name="OnMotion"></event> | ||
| 5574 | <event name="OnMouseEvents"></event> | ||
| 5575 | <event name="OnMouseWheel"></event> | ||
| 5576 | <event name="OnPaint"></event> | ||
| 5577 | <event name="OnRightDClick"></event> | ||
| 5578 | <event name="OnRightDown"></event> | ||
| 5579 | <event name="OnRightUp"></event> | ||
| 5580 | <event name="OnSetFocus"></event> | ||
| 5581 | <event name="OnSize"></event> | ||
| 5582 | <event name="OnText"></event> | ||
| 5583 | <event name="OnTextEnter"></event> | ||
| 5584 | <event name="OnTextMaxLen"></event> | ||
| 5585 | <event name="OnTextURL"></event> | ||
| 5586 | <event name="OnUpdateUI"></event> | ||
| 5587 | </object> | ||
| 5588 | </object> | ||
| 5589 | <object class="sizeritem" expanded="1"> | ||
| 5590 | <property name="border">5</property> | ||
| 5591 | <property name="flag">wxEXPAND</property> | ||
| 5592 | <property name="proportion">0</property> | ||
| 5593 | <object class="wxFlexGridSizer" expanded="0"> | ||
| 5594 | <property name="cols">3</property> | ||
| 5595 | <property name="flexible_direction">wxBOTH</property> | ||
| 5596 | <property name="growablecols">1</property> | ||
| 5597 | <property name="growablerows"></property> | ||
| 5598 | <property name="hgap">0</property> | ||
| 5599 | <property name="minimum_size"></property> | ||
| 5600 | <property name="name">fgSizer5</property> | ||
| 5601 | <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property> | ||
| 5602 | <property name="permission">public</property> | ||
| 5603 | <property name="rows">0</property> | ||
| 5604 | <property name="vgap">0</property> | ||
| 5605 | <object class="sizeritem" expanded="1"> | ||
| 5606 | <property name="border">5</property> | ||
| 5607 | <property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT</property> | ||
| 5608 | <property name="proportion">0</property> | ||
| 5609 | <object class="wxStaticText" expanded="1"> | ||
| 5610 | <property name="bg"></property> | ||
| 5611 | <property name="context_help"></property> | ||
| 5612 | <property name="enabled">1</property> | ||
| 5613 | <property name="fg"></property> | ||
| 5614 | <property name="font"></property> | ||
| 5615 | <property name="hidden">0</property> | ||
| 5616 | <property name="id">wxID_ANY</property> | ||
| 5617 | <property name="label">Label</property> | ||
| 5618 | <property name="maximum_size"></property> | ||
| 5619 | <property name="minimum_size"></property> | ||
| 5620 | <property name="name">m_staticText24</property> | ||
| 5621 | <property name="permission">protected</property> | ||
| 5622 | <property name="pos"></property> | ||
| 5623 | <property name="size"></property> | ||
| 5624 | <property name="style"></property> | ||
| 5625 | <property name="subclass"></property> | ||
| 5626 | <property name="tooltip"></property> | ||
| 5627 | <property name="window_extra_style"></property> | ||
| 5628 | <property name="window_name"></property> | ||
| 5629 | <property name="window_style"></property> | ||
| 5630 | <property name="wrap">-1</property> | ||
| 5631 | <event name="OnChar"></event> | ||
| 5632 | <event name="OnEnterWindow"></event> | ||
| 5633 | <event name="OnEraseBackground"></event> | ||
| 5634 | <event name="OnKeyDown"></event> | ||
| 5635 | <event name="OnKeyUp"></event> | ||
| 5636 | <event name="OnKillFocus"></event> | ||
| 5637 | <event name="OnLeaveWindow"></event> | ||
| 5638 | <event name="OnLeftDClick"></event> | ||
| 5639 | <event name="OnLeftDown"></event> | ||
| 5640 | <event name="OnLeftUp"></event> | ||
| 5641 | <event name="OnMiddleDClick"></event> | ||
| 5642 | <event name="OnMiddleDown"></event> | ||
| 5643 | <event name="OnMiddleUp"></event> | ||
| 5644 | <event name="OnMotion"></event> | ||
| 5645 | <event name="OnMouseEvents"></event> | ||
| 5646 | <event name="OnMouseWheel"></event> | ||
| 5647 | <event name="OnPaint"></event> | ||
| 5648 | <event name="OnRightDClick"></event> | ||
| 5649 | <event name="OnRightDown"></event> | ||
| 5650 | <event name="OnRightUp"></event> | ||
| 5651 | <event name="OnSetFocus"></event> | ||
| 5652 | <event name="OnSize"></event> | ||
| 5653 | <event name="OnUpdateUI"></event> | ||
| 5654 | </object> | ||
| 5655 | </object> | ||
| 5656 | <object class="sizeritem" expanded="1"> | ||
| 5657 | <property name="border">5</property> | ||
| 5658 | <property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT</property> | ||
| 5659 | <property name="proportion">0</property> | ||
| 5660 | <object class="wxStaticText" expanded="1"> | ||
| 5661 | <property name="bg"></property> | ||
| 5662 | <property name="context_help"></property> | ||
| 5663 | <property name="enabled">1</property> | ||
| 5664 | <property name="fg"></property> | ||
| 5665 | <property name="font"></property> | ||
| 5666 | <property name="hidden">0</property> | ||
| 5667 | <property name="id">wxID_ANY</property> | ||
| 5668 | <property name="label">Comma separated list of choices, or leave blank for text field</property> | ||
| 5669 | <property name="maximum_size"></property> | ||
| 5670 | <property name="minimum_size"></property> | ||
| 5671 | <property name="name">m_staticText25</property> | ||
| 5672 | <property name="permission">protected</property> | ||
| 5673 | <property name="pos"></property> | ||
| 5674 | <property name="size"></property> | ||
| 5675 | <property name="style"></property> | ||
| 5676 | <property name="subclass"></property> | ||
| 5677 | <property name="tooltip"></property> | ||
| 5678 | <property name="window_extra_style"></property> | ||
| 5679 | <property name="window_name"></property> | ||
| 5680 | <property name="window_style"></property> | ||
| 5681 | <property name="wrap">-1</property> | ||
| 5682 | <event name="OnChar"></event> | ||
| 5683 | <event name="OnEnterWindow"></event> | ||
| 5684 | <event name="OnEraseBackground"></event> | ||
| 5685 | <event name="OnKeyDown"></event> | ||
| 5686 | <event name="OnKeyUp"></event> | ||
| 5687 | <event name="OnKillFocus"></event> | ||
| 5688 | <event name="OnLeaveWindow"></event> | ||
| 5689 | <event name="OnLeftDClick"></event> | ||
| 5690 | <event name="OnLeftDown"></event> | ||
| 5691 | <event name="OnLeftUp"></event> | ||
| 5692 | <event name="OnMiddleDClick"></event> | ||
| 5693 | <event name="OnMiddleDown"></event> | ||
| 5694 | <event name="OnMiddleUp"></event> | ||
| 5695 | <event name="OnMotion"></event> | ||
| 5696 | <event name="OnMouseEvents"></event> | ||
| 5697 | <event name="OnMouseWheel"></event> | ||
| 5698 | <event name="OnPaint"></event> | ||
| 5699 | <event name="OnRightDClick"></event> | ||
| 5700 | <event name="OnRightDown"></event> | ||
| 5701 | <event name="OnRightUp"></event> | ||
| 5702 | <event name="OnSetFocus"></event> | ||
| 5703 | <event name="OnSize"></event> | ||
| 5704 | <event name="OnUpdateUI"></event> | ||
| 5705 | </object> | ||
| 5706 | </object> | ||
| 5707 | <object class="sizeritem" expanded="1"> | ||
| 5708 | <property name="border">5</property> | ||
| 5709 | <property name="flag">wxEXPAND</property> | ||
| 5710 | <property name="proportion">1</property> | ||
| 5711 | <object class="spacer" expanded="1"> | ||
| 5712 | <property name="height">0</property> | ||
| 5713 | <property name="permission">protected</property> | ||
| 5714 | <property name="width">0</property> | ||
| 5715 | </object> | ||
| 5716 | </object> | ||
| 5717 | <object class="sizeritem" expanded="1"> | ||
| 5718 | <property name="border">5</property> | ||
| 5719 | <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property> | ||
| 5720 | <property name="proportion">0</property> | ||
| 5721 | <object class="wxTextCtrl" expanded="1"> | ||
| 5722 | <property name="bg"></property> | ||
| 5723 | <property name="context_help"></property> | ||
| 5724 | <property name="enabled">1</property> | ||
| 5725 | <property name="fg"></property> | ||
| 5726 | <property name="font"></property> | ||
| 5727 | <property name="hidden">0</property> | ||
| 5728 | <property name="id">wxID_ANY</property> | ||
| 5729 | <property name="maximum_size"></property> | ||
| 5730 | <property name="maxlength">0</property> | ||
| 5731 | <property name="minimum_size">150,-1</property> | ||
| 5732 | <property name="name">m_textCtrlLabel0</property> | ||
| 5733 | <property name="permission">protected</property> | ||
| 5734 | <property name="pos"></property> | ||
| 5735 | <property name="size"></property> | ||
| 5736 | <property name="style"></property> | ||
| 5737 | <property name="subclass"></property> | ||
| 5738 | <property name="tooltip"></property> | ||
| 5739 | <property name="value"></property> | ||
| 5740 | <property name="window_extra_style"></property> | ||
| 5741 | <property name="window_name"></property> | ||
| 5742 | <property name="window_style"></property> | ||
| 5743 | <event name="OnChar"></event> | ||
| 5744 | <event name="OnEnterWindow"></event> | ||
| 5745 | <event name="OnEraseBackground"></event> | ||
| 5746 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 5747 | <event name="OnKeyUp"></event> | ||
| 5748 | <event name="OnKillFocus"></event> | ||
| 5749 | <event name="OnLeaveWindow"></event> | ||
| 5750 | <event name="OnLeftDClick"></event> | ||
| 5751 | <event name="OnLeftDown"></event> | ||
| 5752 | <event name="OnLeftUp"></event> | ||
| 5753 | <event name="OnMiddleDClick"></event> | ||
| 5754 | <event name="OnMiddleDown"></event> | ||
| 5755 | <event name="OnMiddleUp"></event> | ||
| 5756 | <event name="OnMotion"></event> | ||
| 5757 | <event name="OnMouseEvents"></event> | ||
| 5758 | <event name="OnMouseWheel"></event> | ||
| 5759 | <event name="OnPaint"></event> | ||
| 5760 | <event name="OnRightDClick"></event> | ||
| 5761 | <event name="OnRightDown"></event> | ||
| 5762 | <event name="OnRightUp"></event> | ||
| 5763 | <event name="OnSetFocus"></event> | ||
| 5764 | <event name="OnSize"></event> | ||
| 5765 | <event name="OnText"></event> | ||
| 5766 | <event name="OnTextEnter"></event> | ||
| 5767 | <event name="OnTextMaxLen"></event> | ||
| 5768 | <event name="OnTextURL"></event> | ||
| 5769 | <event name="OnUpdateUI"></event> | ||
| 5770 | </object> | ||
| 5771 | </object> | ||
| 5772 | <object class="sizeritem" expanded="1"> | ||
| 5773 | <property name="border">5</property> | ||
| 5774 | <property name="flag">wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL</property> | ||
| 5775 | <property name="proportion">0</property> | ||
| 5776 | <object class="wxTextCtrl" expanded="1"> | ||
| 5777 | <property name="bg"></property> | ||
| 5778 | <property name="context_help"></property> | ||
| 5779 | <property name="enabled">1</property> | ||
| 5780 | <property name="fg"></property> | ||
| 5781 | <property name="font"></property> | ||
| 5782 | <property name="hidden">0</property> | ||
| 5783 | <property name="id">wxID_ANY</property> | ||
| 5784 | <property name="maximum_size">-1,-1</property> | ||
| 5785 | <property name="maxlength">0</property> | ||
| 5786 | <property name="minimum_size">-1,-1</property> | ||
| 5787 | <property name="name">m_textCtrlField0</property> | ||
| 5788 | <property name="permission">protected</property> | ||
| 5789 | <property name="pos"></property> | ||
| 5790 | <property name="size">-1,-1</property> | ||
| 5791 | <property name="style"></property> | ||
| 5792 | <property name="subclass"></property> | ||
| 5793 | <property name="tooltip"></property> | ||
| 5794 | <property name="value"></property> | ||
| 5795 | <property name="window_extra_style"></property> | ||
| 5796 | <property name="window_name"></property> | ||
| 5797 | <property name="window_style"></property> | ||
| 5798 | <event name="OnChar"></event> | ||
| 5799 | <event name="OnEnterWindow"></event> | ||
| 5800 | <event name="OnEraseBackground"></event> | ||
| 5801 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 5802 | <event name="OnKeyUp"></event> | ||
| 5803 | <event name="OnKillFocus"></event> | ||
| 5804 | <event name="OnLeaveWindow"></event> | ||
| 5805 | <event name="OnLeftDClick"></event> | ||
| 5806 | <event name="OnLeftDown"></event> | ||
| 5807 | <event name="OnLeftUp"></event> | ||
| 5808 | <event name="OnMiddleDClick"></event> | ||
| 5809 | <event name="OnMiddleDown"></event> | ||
| 5810 | <event name="OnMiddleUp"></event> | ||
| 5811 | <event name="OnMotion"></event> | ||
| 5812 | <event name="OnMouseEvents"></event> | ||
| 5813 | <event name="OnMouseWheel"></event> | ||
| 5814 | <event name="OnPaint"></event> | ||
| 5815 | <event name="OnRightDClick"></event> | ||
| 5816 | <event name="OnRightDown"></event> | ||
| 5817 | <event name="OnRightUp"></event> | ||
| 5818 | <event name="OnSetFocus"></event> | ||
| 5819 | <event name="OnSize"></event> | ||
| 5820 | <event name="OnText"></event> | ||
| 5821 | <event name="OnTextEnter"></event> | ||
| 5822 | <event name="OnTextMaxLen"></event> | ||
| 5823 | <event name="OnTextURL"></event> | ||
| 5824 | <event name="OnUpdateUI"></event> | ||
| 5825 | </object> | ||
| 5826 | </object> | ||
| 5827 | <object class="sizeritem" expanded="1"> | ||
| 5828 | <property name="border">5</property> | ||
| 5829 | <property name="flag">wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL</property> | ||
| 5830 | <property name="proportion">0</property> | ||
| 5831 | <object class="wxButton" expanded="1"> | ||
| 5832 | <property name="bg"></property> | ||
| 5833 | <property name="context_help"></property> | ||
| 5834 | <property name="default">0</property> | ||
| 5835 | <property name="enabled">1</property> | ||
| 5836 | <property name="fg"></property> | ||
| 5837 | <property name="font"></property> | ||
| 5838 | <property name="hidden">0</property> | ||
| 5839 | <property name="id">wxID_DEL0</property> | ||
| 5840 | <property name="label">Delete</property> | ||
| 5841 | <property name="maximum_size"></property> | ||
| 5842 | <property name="minimum_size">-1,-1</property> | ||
| 5843 | <property name="name">m_buttonDel0</property> | ||
| 5844 | <property name="permission">protected</property> | ||
| 5845 | <property name="pos"></property> | ||
| 5846 | <property name="size">60,20</property> | ||
| 5847 | <property name="style"></property> | ||
| 5848 | <property name="subclass"></property> | ||
| 5849 | <property name="tooltip"></property> | ||
| 5850 | <property name="window_extra_style"></property> | ||
| 5851 | <property name="window_name"></property> | ||
| 5852 | <property name="window_style"></property> | ||
| 5853 | <event name="OnButtonClick">OnButtonDel0</event> | ||
| 5854 | <event name="OnChar"></event> | ||
| 5855 | <event name="OnEnterWindow"></event> | ||
| 5856 | <event name="OnEraseBackground"></event> | ||
| 5857 | <event name="OnKeyDown"></event> | ||
| 5858 | <event name="OnKeyUp"></event> | ||
| 5859 | <event name="OnKillFocus"></event> | ||
| 5860 | <event name="OnLeaveWindow"></event> | ||
| 5861 | <event name="OnLeftDClick"></event> | ||
| 5862 | <event name="OnLeftDown"></event> | ||
| 5863 | <event name="OnLeftUp"></event> | ||
| 5864 | <event name="OnMiddleDClick"></event> | ||
| 5865 | <event name="OnMiddleDown"></event> | ||
| 5866 | <event name="OnMiddleUp"></event> | ||
| 5867 | <event name="OnMotion"></event> | ||
| 5868 | <event name="OnMouseEvents"></event> | ||
| 5869 | <event name="OnMouseWheel"></event> | ||
| 5870 | <event name="OnPaint"></event> | ||
| 5871 | <event name="OnRightDClick"></event> | ||
| 5872 | <event name="OnRightDown"></event> | ||
| 5873 | <event name="OnRightUp"></event> | ||
| 5874 | <event name="OnSetFocus"></event> | ||
| 5875 | <event name="OnSize"></event> | ||
| 5876 | <event name="OnUpdateUI"></event> | ||
| 5877 | </object> | ||
| 5878 | </object> | ||
| 5879 | <object class="sizeritem" expanded="1"> | ||
| 5880 | <property name="border">5</property> | ||
| 5881 | <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property> | ||
| 5882 | <property name="proportion">0</property> | ||
| 5883 | <object class="wxTextCtrl" expanded="1"> | ||
| 5884 | <property name="bg"></property> | ||
| 5885 | <property name="context_help"></property> | ||
| 5886 | <property name="enabled">1</property> | ||
| 5887 | <property name="fg"></property> | ||
| 5888 | <property name="font"></property> | ||
| 5889 | <property name="hidden">0</property> | ||
| 5890 | <property name="id">wxID_ANY</property> | ||
| 5891 | <property name="maximum_size"></property> | ||
| 5892 | <property name="maxlength">0</property> | ||
| 5893 | <property name="minimum_size">150,-1</property> | ||
| 5894 | <property name="name">m_textCtrlLabel1</property> | ||
| 5895 | <property name="permission">protected</property> | ||
| 5896 | <property name="pos"></property> | ||
| 5897 | <property name="size"></property> | ||
| 5898 | <property name="style"></property> | ||
| 5899 | <property name="subclass"></property> | ||
| 5900 | <property name="tooltip"></property> | ||
| 5901 | <property name="value"></property> | ||
| 5902 | <property name="window_extra_style"></property> | ||
| 5903 | <property name="window_name"></property> | ||
| 5904 | <property name="window_style"></property> | ||
| 5905 | <event name="OnChar"></event> | ||
| 5906 | <event name="OnEnterWindow"></event> | ||
| 5907 | <event name="OnEraseBackground"></event> | ||
| 5908 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 5909 | <event name="OnKeyUp"></event> | ||
| 5910 | <event name="OnKillFocus"></event> | ||
| 5911 | <event name="OnLeaveWindow"></event> | ||
| 5912 | <event name="OnLeftDClick"></event> | ||
| 5913 | <event name="OnLeftDown"></event> | ||
| 5914 | <event name="OnLeftUp"></event> | ||
| 5915 | <event name="OnMiddleDClick"></event> | ||
| 5916 | <event name="OnMiddleDown"></event> | ||
| 5917 | <event name="OnMiddleUp"></event> | ||
| 5918 | <event name="OnMotion"></event> | ||
| 5919 | <event name="OnMouseEvents"></event> | ||
| 5920 | <event name="OnMouseWheel"></event> | ||
| 5921 | <event name="OnPaint"></event> | ||
| 5922 | <event name="OnRightDClick"></event> | ||
| 5923 | <event name="OnRightDown"></event> | ||
| 5924 | <event name="OnRightUp"></event> | ||
| 5925 | <event name="OnSetFocus"></event> | ||
| 5926 | <event name="OnSize"></event> | ||
| 5927 | <event name="OnText"></event> | ||
| 5928 | <event name="OnTextEnter"></event> | ||
| 5929 | <event name="OnTextMaxLen"></event> | ||
| 5930 | <event name="OnTextURL"></event> | ||
| 5931 | <event name="OnUpdateUI"></event> | ||
| 5932 | </object> | ||
| 5933 | </object> | ||
| 5934 | <object class="sizeritem" expanded="1"> | ||
| 5935 | <property name="border">5</property> | ||
| 5936 | <property name="flag">wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL</property> | ||
| 5937 | <property name="proportion">0</property> | ||
| 5938 | <object class="wxTextCtrl" expanded="1"> | ||
| 5939 | <property name="bg"></property> | ||
| 5940 | <property name="context_help"></property> | ||
| 5941 | <property name="enabled">1</property> | ||
| 5942 | <property name="fg"></property> | ||
| 5943 | <property name="font"></property> | ||
| 5944 | <property name="hidden">0</property> | ||
| 5945 | <property name="id">wxID_ANY</property> | ||
| 5946 | <property name="maximum_size">-1,-1</property> | ||
| 5947 | <property name="maxlength">0</property> | ||
| 5948 | <property name="minimum_size">-1,-1</property> | ||
| 5949 | <property name="name">m_textCtrlField1</property> | ||
| 5950 | <property name="permission">protected</property> | ||
| 5951 | <property name="pos"></property> | ||
| 5952 | <property name="size">-1,-1</property> | ||
| 5953 | <property name="style"></property> | ||
| 5954 | <property name="subclass"></property> | ||
| 5955 | <property name="tooltip"></property> | ||
| 5956 | <property name="value"></property> | ||
| 5957 | <property name="window_extra_style"></property> | ||
| 5958 | <property name="window_name"></property> | ||
| 5959 | <property name="window_style"></property> | ||
| 5960 | <event name="OnChar"></event> | ||
| 5961 | <event name="OnEnterWindow"></event> | ||
| 5962 | <event name="OnEraseBackground"></event> | ||
| 5963 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 5964 | <event name="OnKeyUp"></event> | ||
| 5965 | <event name="OnKillFocus"></event> | ||
| 5966 | <event name="OnLeaveWindow"></event> | ||
| 5967 | <event name="OnLeftDClick"></event> | ||
| 5968 | <event name="OnLeftDown"></event> | ||
| 5969 | <event name="OnLeftUp"></event> | ||
| 5970 | <event name="OnMiddleDClick"></event> | ||
| 5971 | <event name="OnMiddleDown"></event> | ||
| 5972 | <event name="OnMiddleUp"></event> | ||
| 5973 | <event name="OnMotion"></event> | ||
| 5974 | <event name="OnMouseEvents"></event> | ||
| 5975 | <event name="OnMouseWheel"></event> | ||
| 5976 | <event name="OnPaint"></event> | ||
| 5977 | <event name="OnRightDClick"></event> | ||
| 5978 | <event name="OnRightDown"></event> | ||
| 5979 | <event name="OnRightUp"></event> | ||
| 5980 | <event name="OnSetFocus"></event> | ||
| 5981 | <event name="OnSize"></event> | ||
| 5982 | <event name="OnText"></event> | ||
| 5983 | <event name="OnTextEnter"></event> | ||
| 5984 | <event name="OnTextMaxLen"></event> | ||
| 5985 | <event name="OnTextURL"></event> | ||
| 5986 | <event name="OnUpdateUI"></event> | ||
| 5987 | </object> | ||
| 5988 | </object> | ||
| 5989 | <object class="sizeritem" expanded="1"> | ||
| 5990 | <property name="border">5</property> | ||
| 5991 | <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property> | ||
| 5992 | <property name="proportion">0</property> | ||
| 5993 | <object class="wxButton" expanded="1"> | ||
| 5994 | <property name="bg"></property> | ||
| 5995 | <property name="context_help"></property> | ||
| 5996 | <property name="default">0</property> | ||
| 5997 | <property name="enabled">1</property> | ||
| 5998 | <property name="fg"></property> | ||
| 5999 | <property name="font"></property> | ||
| 6000 | <property name="hidden">0</property> | ||
| 6001 | <property name="id">wxID_DEL1</property> | ||
| 6002 | <property name="label">Delete</property> | ||
| 6003 | <property name="maximum_size"></property> | ||
| 6004 | <property name="minimum_size">-1,-1</property> | ||
| 6005 | <property name="name">m_buttonDel1</property> | ||
| 6006 | <property name="permission">protected</property> | ||
| 6007 | <property name="pos"></property> | ||
| 6008 | <property name="size">60,20</property> | ||
| 6009 | <property name="style"></property> | ||
| 6010 | <property name="subclass"></property> | ||
| 6011 | <property name="tooltip"></property> | ||
| 6012 | <property name="window_extra_style"></property> | ||
| 6013 | <property name="window_name"></property> | ||
| 6014 | <property name="window_style"></property> | ||
| 6015 | <event name="OnButtonClick">OnButtonDel1</event> | ||
| 6016 | <event name="OnChar"></event> | ||
| 6017 | <event name="OnEnterWindow"></event> | ||
| 6018 | <event name="OnEraseBackground"></event> | ||
| 6019 | <event name="OnKeyDown"></event> | ||
| 6020 | <event name="OnKeyUp"></event> | ||
| 6021 | <event name="OnKillFocus"></event> | ||
| 6022 | <event name="OnLeaveWindow"></event> | ||
| 6023 | <event name="OnLeftDClick"></event> | ||
| 6024 | <event name="OnLeftDown"></event> | ||
| 6025 | <event name="OnLeftUp"></event> | ||
| 6026 | <event name="OnMiddleDClick"></event> | ||
| 6027 | <event name="OnMiddleDown"></event> | ||
| 6028 | <event name="OnMiddleUp"></event> | ||
| 6029 | <event name="OnMotion"></event> | ||
| 6030 | <event name="OnMouseEvents"></event> | ||
| 6031 | <event name="OnMouseWheel"></event> | ||
| 6032 | <event name="OnPaint"></event> | ||
| 6033 | <event name="OnRightDClick"></event> | ||
| 6034 | <event name="OnRightDown"></event> | ||
| 6035 | <event name="OnRightUp"></event> | ||
| 6036 | <event name="OnSetFocus"></event> | ||
| 6037 | <event name="OnSize"></event> | ||
| 6038 | <event name="OnUpdateUI"></event> | ||
| 6039 | </object> | ||
| 6040 | </object> | ||
| 6041 | <object class="sizeritem" expanded="1"> | ||
| 6042 | <property name="border">5</property> | ||
| 6043 | <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property> | ||
| 6044 | <property name="proportion">0</property> | ||
| 6045 | <object class="wxTextCtrl" expanded="1"> | ||
| 6046 | <property name="bg"></property> | ||
| 6047 | <property name="context_help"></property> | ||
| 6048 | <property name="enabled">1</property> | ||
| 6049 | <property name="fg"></property> | ||
| 6050 | <property name="font"></property> | ||
| 6051 | <property name="hidden">0</property> | ||
| 6052 | <property name="id">wxID_ANY</property> | ||
| 6053 | <property name="maximum_size"></property> | ||
| 6054 | <property name="maxlength">0</property> | ||
| 6055 | <property name="minimum_size">150,-1</property> | ||
| 6056 | <property name="name">m_textCtrlLabel2</property> | ||
| 6057 | <property name="permission">protected</property> | ||
| 6058 | <property name="pos"></property> | ||
| 6059 | <property name="size"></property> | ||
| 6060 | <property name="style"></property> | ||
| 6061 | <property name="subclass"></property> | ||
| 6062 | <property name="tooltip"></property> | ||
| 6063 | <property name="value"></property> | ||
| 6064 | <property name="window_extra_style"></property> | ||
| 6065 | <property name="window_name"></property> | ||
| 6066 | <property name="window_style"></property> | ||
| 6067 | <event name="OnChar"></event> | ||
| 6068 | <event name="OnEnterWindow"></event> | ||
| 6069 | <event name="OnEraseBackground"></event> | ||
| 6070 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 6071 | <event name="OnKeyUp"></event> | ||
| 6072 | <event name="OnKillFocus"></event> | ||
| 6073 | <event name="OnLeaveWindow"></event> | ||
| 6074 | <event name="OnLeftDClick"></event> | ||
| 6075 | <event name="OnLeftDown"></event> | ||
| 6076 | <event name="OnLeftUp"></event> | ||
| 6077 | <event name="OnMiddleDClick"></event> | ||
| 6078 | <event name="OnMiddleDown"></event> | ||
| 6079 | <event name="OnMiddleUp"></event> | ||
| 6080 | <event name="OnMotion"></event> | ||
| 6081 | <event name="OnMouseEvents"></event> | ||
| 6082 | <event name="OnMouseWheel"></event> | ||
| 6083 | <event name="OnPaint"></event> | ||
| 6084 | <event name="OnRightDClick"></event> | ||
| 6085 | <event name="OnRightDown"></event> | ||
| 6086 | <event name="OnRightUp"></event> | ||
| 6087 | <event name="OnSetFocus"></event> | ||
| 6088 | <event name="OnSize"></event> | ||
| 6089 | <event name="OnText"></event> | ||
| 6090 | <event name="OnTextEnter"></event> | ||
| 6091 | <event name="OnTextMaxLen"></event> | ||
| 6092 | <event name="OnTextURL"></event> | ||
| 6093 | <event name="OnUpdateUI"></event> | ||
| 6094 | </object> | ||
| 6095 | </object> | ||
| 6096 | <object class="sizeritem" expanded="1"> | ||
| 6097 | <property name="border">5</property> | ||
| 6098 | <property name="flag">wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL</property> | ||
| 6099 | <property name="proportion">0</property> | ||
| 6100 | <object class="wxTextCtrl" expanded="1"> | ||
| 6101 | <property name="bg"></property> | ||
| 6102 | <property name="context_help"></property> | ||
| 6103 | <property name="enabled">1</property> | ||
| 6104 | <property name="fg"></property> | ||
| 6105 | <property name="font"></property> | ||
| 6106 | <property name="hidden">0</property> | ||
| 6107 | <property name="id">wxID_ANY</property> | ||
| 6108 | <property name="maximum_size">-1,-1</property> | ||
| 6109 | <property name="maxlength">0</property> | ||
| 6110 | <property name="minimum_size">-1,-1</property> | ||
| 6111 | <property name="name">m_textCtrlField2</property> | ||
| 6112 | <property name="permission">protected</property> | ||
| 6113 | <property name="pos"></property> | ||
| 6114 | <property name="size">-1,-1</property> | ||
| 6115 | <property name="style"></property> | ||
| 6116 | <property name="subclass"></property> | ||
| 6117 | <property name="tooltip"></property> | ||
| 6118 | <property name="value"></property> | ||
| 6119 | <property name="window_extra_style"></property> | ||
| 6120 | <property name="window_name"></property> | ||
| 6121 | <property name="window_style"></property> | ||
| 6122 | <event name="OnChar"></event> | ||
| 6123 | <event name="OnEnterWindow"></event> | ||
| 6124 | <event name="OnEraseBackground"></event> | ||
| 6125 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 6126 | <event name="OnKeyUp"></event> | ||
| 6127 | <event name="OnKillFocus"></event> | ||
| 6128 | <event name="OnLeaveWindow"></event> | ||
| 6129 | <event name="OnLeftDClick"></event> | ||
| 6130 | <event name="OnLeftDown"></event> | ||
| 6131 | <event name="OnLeftUp"></event> | ||
| 6132 | <event name="OnMiddleDClick"></event> | ||
| 6133 | <event name="OnMiddleDown"></event> | ||
| 6134 | <event name="OnMiddleUp"></event> | ||
| 6135 | <event name="OnMotion"></event> | ||
| 6136 | <event name="OnMouseEvents"></event> | ||
| 6137 | <event name="OnMouseWheel"></event> | ||
| 6138 | <event name="OnPaint"></event> | ||
| 6139 | <event name="OnRightDClick"></event> | ||
| 6140 | <event name="OnRightDown"></event> | ||
| 6141 | <event name="OnRightUp"></event> | ||
| 6142 | <event name="OnSetFocus"></event> | ||
| 6143 | <event name="OnSize"></event> | ||
| 6144 | <event name="OnText"></event> | ||
| 6145 | <event name="OnTextEnter"></event> | ||
| 6146 | <event name="OnTextMaxLen"></event> | ||
| 6147 | <event name="OnTextURL"></event> | ||
| 6148 | <event name="OnUpdateUI"></event> | ||
| 6149 | </object> | ||
| 6150 | </object> | ||
| 6151 | <object class="sizeritem" expanded="1"> | ||
| 6152 | <property name="border">5</property> | ||
| 6153 | <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property> | ||
| 6154 | <property name="proportion">0</property> | ||
| 6155 | <object class="wxButton" expanded="1"> | ||
| 6156 | <property name="bg"></property> | ||
| 6157 | <property name="context_help"></property> | ||
| 6158 | <property name="default">0</property> | ||
| 6159 | <property name="enabled">1</property> | ||
| 6160 | <property name="fg"></property> | ||
| 6161 | <property name="font"></property> | ||
| 6162 | <property name="hidden">0</property> | ||
| 6163 | <property name="id">wxID_DEL2</property> | ||
| 6164 | <property name="label">Delete</property> | ||
| 6165 | <property name="maximum_size"></property> | ||
| 6166 | <property name="minimum_size">-1,-1</property> | ||
| 6167 | <property name="name">m_buttonDel2</property> | ||
| 6168 | <property name="permission">protected</property> | ||
| 6169 | <property name="pos"></property> | ||
| 6170 | <property name="size">60,20</property> | ||
| 6171 | <property name="style"></property> | ||
| 6172 | <property name="subclass"></property> | ||
| 6173 | <property name="tooltip"></property> | ||
| 6174 | <property name="window_extra_style"></property> | ||
| 6175 | <property name="window_name"></property> | ||
| 6176 | <property name="window_style"></property> | ||
| 6177 | <event name="OnButtonClick">OnButtonDel2</event> | ||
| 6178 | <event name="OnChar"></event> | ||
| 6179 | <event name="OnEnterWindow"></event> | ||
| 6180 | <event name="OnEraseBackground"></event> | ||
| 6181 | <event name="OnKeyDown"></event> | ||
| 6182 | <event name="OnKeyUp"></event> | ||
| 6183 | <event name="OnKillFocus"></event> | ||
| 6184 | <event name="OnLeaveWindow"></event> | ||
| 6185 | <event name="OnLeftDClick"></event> | ||
| 6186 | <event name="OnLeftDown"></event> | ||
| 6187 | <event name="OnLeftUp"></event> | ||
| 6188 | <event name="OnMiddleDClick"></event> | ||
| 6189 | <event name="OnMiddleDown"></event> | ||
| 6190 | <event name="OnMiddleUp"></event> | ||
| 6191 | <event name="OnMotion"></event> | ||
| 6192 | <event name="OnMouseEvents"></event> | ||
| 6193 | <event name="OnMouseWheel"></event> | ||
| 6194 | <event name="OnPaint"></event> | ||
| 6195 | <event name="OnRightDClick"></event> | ||
| 6196 | <event name="OnRightDown"></event> | ||
| 6197 | <event name="OnRightUp"></event> | ||
| 6198 | <event name="OnSetFocus"></event> | ||
| 6199 | <event name="OnSize"></event> | ||
| 6200 | <event name="OnUpdateUI"></event> | ||
| 6201 | </object> | ||
| 6202 | </object> | ||
| 6203 | <object class="sizeritem" expanded="1"> | ||
| 6204 | <property name="border">5</property> | ||
| 6205 | <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property> | ||
| 6206 | <property name="proportion">0</property> | ||
| 6207 | <object class="wxTextCtrl" expanded="1"> | ||
| 6208 | <property name="bg"></property> | ||
| 6209 | <property name="context_help"></property> | ||
| 6210 | <property name="enabled">1</property> | ||
| 6211 | <property name="fg"></property> | ||
| 6212 | <property name="font"></property> | ||
| 6213 | <property name="hidden">0</property> | ||
| 6214 | <property name="id">wxID_ANY</property> | ||
| 6215 | <property name="maximum_size"></property> | ||
| 6216 | <property name="maxlength">0</property> | ||
| 6217 | <property name="minimum_size">150,-1</property> | ||
| 6218 | <property name="name">m_textCtrlLabel3</property> | ||
| 6219 | <property name="permission">protected</property> | ||
| 6220 | <property name="pos"></property> | ||
| 6221 | <property name="size"></property> | ||
| 6222 | <property name="style"></property> | ||
| 6223 | <property name="subclass"></property> | ||
| 6224 | <property name="tooltip"></property> | ||
| 6225 | <property name="value"></property> | ||
| 6226 | <property name="window_extra_style"></property> | ||
| 6227 | <property name="window_name"></property> | ||
| 6228 | <property name="window_style"></property> | ||
| 6229 | <event name="OnChar"></event> | ||
| 6230 | <event name="OnEnterWindow"></event> | ||
| 6231 | <event name="OnEraseBackground"></event> | ||
| 6232 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 6233 | <event name="OnKeyUp"></event> | ||
| 6234 | <event name="OnKillFocus"></event> | ||
| 6235 | <event name="OnLeaveWindow"></event> | ||
| 6236 | <event name="OnLeftDClick"></event> | ||
| 6237 | <event name="OnLeftDown"></event> | ||
| 6238 | <event name="OnLeftUp"></event> | ||
| 6239 | <event name="OnMiddleDClick"></event> | ||
| 6240 | <event name="OnMiddleDown"></event> | ||
| 6241 | <event name="OnMiddleUp"></event> | ||
| 6242 | <event name="OnMotion"></event> | ||
| 6243 | <event name="OnMouseEvents"></event> | ||
| 6244 | <event name="OnMouseWheel"></event> | ||
| 6245 | <event name="OnPaint"></event> | ||
| 6246 | <event name="OnRightDClick"></event> | ||
| 6247 | <event name="OnRightDown"></event> | ||
| 6248 | <event name="OnRightUp"></event> | ||
| 6249 | <event name="OnSetFocus"></event> | ||
| 6250 | <event name="OnSize"></event> | ||
| 6251 | <event name="OnText"></event> | ||
| 6252 | <event name="OnTextEnter"></event> | ||
| 6253 | <event name="OnTextMaxLen"></event> | ||
| 6254 | <event name="OnTextURL"></event> | ||
| 6255 | <event name="OnUpdateUI"></event> | ||
| 6256 | </object> | ||
| 6257 | </object> | ||
| 6258 | <object class="sizeritem" expanded="1"> | ||
| 6259 | <property name="border">5</property> | ||
| 6260 | <property name="flag">wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL</property> | ||
| 6261 | <property name="proportion">0</property> | ||
| 6262 | <object class="wxTextCtrl" expanded="1"> | ||
| 6263 | <property name="bg"></property> | ||
| 6264 | <property name="context_help"></property> | ||
| 6265 | <property name="enabled">1</property> | ||
| 6266 | <property name="fg"></property> | ||
| 6267 | <property name="font"></property> | ||
| 6268 | <property name="hidden">0</property> | ||
| 6269 | <property name="id">wxID_ANY</property> | ||
| 6270 | <property name="maximum_size">-1,-1</property> | ||
| 6271 | <property name="maxlength">0</property> | ||
| 6272 | <property name="minimum_size">-1,-1</property> | ||
| 6273 | <property name="name">m_textCtrlField3</property> | ||
| 6274 | <property name="permission">protected</property> | ||
| 6275 | <property name="pos"></property> | ||
| 6276 | <property name="size">-1,-1</property> | ||
| 6277 | <property name="style"></property> | ||
| 6278 | <property name="subclass"></property> | ||
| 6279 | <property name="tooltip"></property> | ||
| 6280 | <property name="value"></property> | ||
| 6281 | <property name="window_extra_style"></property> | ||
| 6282 | <property name="window_name"></property> | ||
| 6283 | <property name="window_style"></property> | ||
| 6284 | <event name="OnChar"></event> | ||
| 6285 | <event name="OnEnterWindow"></event> | ||
| 6286 | <event name="OnEraseBackground"></event> | ||
| 6287 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 6288 | <event name="OnKeyUp"></event> | ||
| 6289 | <event name="OnKillFocus"></event> | ||
| 6290 | <event name="OnLeaveWindow"></event> | ||
| 6291 | <event name="OnLeftDClick"></event> | ||
| 6292 | <event name="OnLeftDown"></event> | ||
| 6293 | <event name="OnLeftUp"></event> | ||
| 6294 | <event name="OnMiddleDClick"></event> | ||
| 6295 | <event name="OnMiddleDown"></event> | ||
| 6296 | <event name="OnMiddleUp"></event> | ||
| 6297 | <event name="OnMotion"></event> | ||
| 6298 | <event name="OnMouseEvents"></event> | ||
| 6299 | <event name="OnMouseWheel"></event> | ||
| 6300 | <event name="OnPaint"></event> | ||
| 6301 | <event name="OnRightDClick"></event> | ||
| 6302 | <event name="OnRightDown"></event> | ||
| 6303 | <event name="OnRightUp"></event> | ||
| 6304 | <event name="OnSetFocus"></event> | ||
| 6305 | <event name="OnSize"></event> | ||
| 6306 | <event name="OnText"></event> | ||
| 6307 | <event name="OnTextEnter"></event> | ||
| 6308 | <event name="OnTextMaxLen"></event> | ||
| 6309 | <event name="OnTextURL"></event> | ||
| 6310 | <event name="OnUpdateUI"></event> | ||
| 6311 | </object> | ||
| 6312 | </object> | ||
| 6313 | <object class="sizeritem" expanded="1"> | ||
| 6314 | <property name="border">5</property> | ||
| 6315 | <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property> | ||
| 6316 | <property name="proportion">0</property> | ||
| 6317 | <object class="wxButton" expanded="1"> | ||
| 6318 | <property name="bg"></property> | ||
| 6319 | <property name="context_help"></property> | ||
| 6320 | <property name="default">0</property> | ||
| 6321 | <property name="enabled">1</property> | ||
| 6322 | <property name="fg"></property> | ||
| 6323 | <property name="font"></property> | ||
| 6324 | <property name="hidden">0</property> | ||
| 6325 | <property name="id">wxID_DEL3</property> | ||
| 6326 | <property name="label">Delete</property> | ||
| 6327 | <property name="maximum_size"></property> | ||
| 6328 | <property name="minimum_size">-1,-1</property> | ||
| 6329 | <property name="name">m_buttonDel3</property> | ||
| 6330 | <property name="permission">protected</property> | ||
| 6331 | <property name="pos"></property> | ||
| 6332 | <property name="size">60,20</property> | ||
| 6333 | <property name="style"></property> | ||
| 6334 | <property name="subclass"></property> | ||
| 6335 | <property name="tooltip"></property> | ||
| 6336 | <property name="window_extra_style"></property> | ||
| 6337 | <property name="window_name"></property> | ||
| 6338 | <property name="window_style"></property> | ||
| 6339 | <event name="OnButtonClick">OnButtonDel3</event> | ||
| 6340 | <event name="OnChar"></event> | ||
| 6341 | <event name="OnEnterWindow"></event> | ||
| 6342 | <event name="OnEraseBackground"></event> | ||
| 6343 | <event name="OnKeyDown"></event> | ||
| 6344 | <event name="OnKeyUp"></event> | ||
| 6345 | <event name="OnKillFocus"></event> | ||
| 6346 | <event name="OnLeaveWindow"></event> | ||
| 6347 | <event name="OnLeftDClick"></event> | ||
| 6348 | <event name="OnLeftDown"></event> | ||
| 6349 | <event name="OnLeftUp"></event> | ||
| 6350 | <event name="OnMiddleDClick"></event> | ||
| 6351 | <event name="OnMiddleDown"></event> | ||
| 6352 | <event name="OnMiddleUp"></event> | ||
| 6353 | <event name="OnMotion"></event> | ||
| 6354 | <event name="OnMouseEvents"></event> | ||
| 6355 | <event name="OnMouseWheel"></event> | ||
| 6356 | <event name="OnPaint"></event> | ||
| 6357 | <event name="OnRightDClick"></event> | ||
| 6358 | <event name="OnRightDown"></event> | ||
| 6359 | <event name="OnRightUp"></event> | ||
| 6360 | <event name="OnSetFocus"></event> | ||
| 6361 | <event name="OnSize"></event> | ||
| 6362 | <event name="OnUpdateUI"></event> | ||
| 6363 | </object> | ||
| 6364 | </object> | ||
| 6365 | <object class="sizeritem" expanded="1"> | ||
| 6366 | <property name="border">5</property> | ||
| 6367 | <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property> | ||
| 6368 | <property name="proportion">0</property> | ||
| 6369 | <object class="wxTextCtrl" expanded="1"> | ||
| 6370 | <property name="bg"></property> | ||
| 6371 | <property name="context_help"></property> | ||
| 6372 | <property name="enabled">1</property> | ||
| 6373 | <property name="fg"></property> | ||
| 6374 | <property name="font"></property> | ||
| 6375 | <property name="hidden">0</property> | ||
| 6376 | <property name="id">wxID_ANY</property> | ||
| 6377 | <property name="maximum_size"></property> | ||
| 6378 | <property name="maxlength">0</property> | ||
| 6379 | <property name="minimum_size">150,-1</property> | ||
| 6380 | <property name="name">m_textCtrlLabel4</property> | ||
| 6381 | <property name="permission">protected</property> | ||
| 6382 | <property name="pos"></property> | ||
| 6383 | <property name="size"></property> | ||
| 6384 | <property name="style"></property> | ||
| 6385 | <property name="subclass"></property> | ||
| 6386 | <property name="tooltip"></property> | ||
| 6387 | <property name="value"></property> | ||
| 6388 | <property name="window_extra_style"></property> | ||
| 6389 | <property name="window_name"></property> | ||
| 6390 | <property name="window_style"></property> | ||
| 6391 | <event name="OnChar"></event> | ||
| 6392 | <event name="OnEnterWindow"></event> | ||
| 6393 | <event name="OnEraseBackground"></event> | ||
| 6394 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 6395 | <event name="OnKeyUp"></event> | ||
| 6396 | <event name="OnKillFocus"></event> | ||
| 6397 | <event name="OnLeaveWindow"></event> | ||
| 6398 | <event name="OnLeftDClick"></event> | ||
| 6399 | <event name="OnLeftDown"></event> | ||
| 6400 | <event name="OnLeftUp"></event> | ||
| 6401 | <event name="OnMiddleDClick"></event> | ||
| 6402 | <event name="OnMiddleDown"></event> | ||
| 6403 | <event name="OnMiddleUp"></event> | ||
| 6404 | <event name="OnMotion"></event> | ||
| 6405 | <event name="OnMouseEvents"></event> | ||
| 6406 | <event name="OnMouseWheel"></event> | ||
| 6407 | <event name="OnPaint"></event> | ||
| 6408 | <event name="OnRightDClick"></event> | ||
| 6409 | <event name="OnRightDown"></event> | ||
| 6410 | <event name="OnRightUp"></event> | ||
| 6411 | <event name="OnSetFocus"></event> | ||
| 6412 | <event name="OnSize"></event> | ||
| 6413 | <event name="OnText"></event> | ||
| 6414 | <event name="OnTextEnter"></event> | ||
| 6415 | <event name="OnTextMaxLen"></event> | ||
| 6416 | <event name="OnTextURL"></event> | ||
| 6417 | <event name="OnUpdateUI"></event> | ||
| 6418 | </object> | ||
| 6419 | </object> | ||
| 6420 | <object class="sizeritem" expanded="1"> | ||
| 6421 | <property name="border">5</property> | ||
| 6422 | <property name="flag">wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL</property> | ||
| 6423 | <property name="proportion">0</property> | ||
| 6424 | <object class="wxTextCtrl" expanded="1"> | ||
| 6425 | <property name="bg"></property> | ||
| 6426 | <property name="context_help"></property> | ||
| 6427 | <property name="enabled">1</property> | ||
| 6428 | <property name="fg"></property> | ||
| 6429 | <property name="font"></property> | ||
| 6430 | <property name="hidden">0</property> | ||
| 6431 | <property name="id">wxID_ANY</property> | ||
| 6432 | <property name="maximum_size">-1,-1</property> | ||
| 6433 | <property name="maxlength">0</property> | ||
| 6434 | <property name="minimum_size">-1,-1</property> | ||
| 6435 | <property name="name">m_textCtrlField4</property> | ||
| 6436 | <property name="permission">protected</property> | ||
| 6437 | <property name="pos"></property> | ||
| 6438 | <property name="size">-1,-1</property> | ||
| 6439 | <property name="style"></property> | ||
| 6440 | <property name="subclass"></property> | ||
| 6441 | <property name="tooltip"></property> | ||
| 6442 | <property name="value"></property> | ||
| 6443 | <property name="window_extra_style"></property> | ||
| 6444 | <property name="window_name"></property> | ||
| 6445 | <property name="window_style"></property> | ||
| 6446 | <event name="OnChar"></event> | ||
| 6447 | <event name="OnEnterWindow"></event> | ||
| 6448 | <event name="OnEraseBackground"></event> | ||
| 6449 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 6450 | <event name="OnKeyUp"></event> | ||
| 6451 | <event name="OnKillFocus"></event> | ||
| 6452 | <event name="OnLeaveWindow"></event> | ||
| 6453 | <event name="OnLeftDClick"></event> | ||
| 6454 | <event name="OnLeftDown"></event> | ||
| 6455 | <event name="OnLeftUp"></event> | ||
| 6456 | <event name="OnMiddleDClick"></event> | ||
| 6457 | <event name="OnMiddleDown"></event> | ||
| 6458 | <event name="OnMiddleUp"></event> | ||
| 6459 | <event name="OnMotion"></event> | ||
| 6460 | <event name="OnMouseEvents"></event> | ||
| 6461 | <event name="OnMouseWheel"></event> | ||
| 6462 | <event name="OnPaint"></event> | ||
| 6463 | <event name="OnRightDClick"></event> | ||
| 6464 | <event name="OnRightDown"></event> | ||
| 6465 | <event name="OnRightUp"></event> | ||
| 6466 | <event name="OnSetFocus"></event> | ||
| 6467 | <event name="OnSize"></event> | ||
| 6468 | <event name="OnText"></event> | ||
| 6469 | <event name="OnTextEnter"></event> | ||
| 6470 | <event name="OnTextMaxLen"></event> | ||
| 6471 | <event name="OnTextURL"></event> | ||
| 6472 | <event name="OnUpdateUI"></event> | ||
| 6473 | </object> | ||
| 6474 | </object> | ||
| 6475 | <object class="sizeritem" expanded="1"> | ||
| 6476 | <property name="border">5</property> | ||
| 6477 | <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property> | ||
| 6478 | <property name="proportion">0</property> | ||
| 6479 | <object class="wxButton" expanded="1"> | ||
| 6480 | <property name="bg"></property> | ||
| 6481 | <property name="context_help"></property> | ||
| 6482 | <property name="default">0</property> | ||
| 6483 | <property name="enabled">1</property> | ||
| 6484 | <property name="fg"></property> | ||
| 6485 | <property name="font"></property> | ||
| 6486 | <property name="hidden">0</property> | ||
| 6487 | <property name="id">wxID_DEL4</property> | ||
| 6488 | <property name="label">Delete</property> | ||
| 6489 | <property name="maximum_size"></property> | ||
| 6490 | <property name="minimum_size">-1,-1</property> | ||
| 6491 | <property name="name">m_buttonDel4</property> | ||
| 6492 | <property name="permission">protected</property> | ||
| 6493 | <property name="pos"></property> | ||
| 6494 | <property name="size">60,20</property> | ||
| 6495 | <property name="style"></property> | ||
| 6496 | <property name="subclass"></property> | ||
| 6497 | <property name="tooltip"></property> | ||
| 6498 | <property name="window_extra_style"></property> | ||
| 6499 | <property name="window_name"></property> | ||
| 6500 | <property name="window_style"></property> | ||
| 6501 | <event name="OnButtonClick">OnButtonDel4</event> | ||
| 6502 | <event name="OnChar"></event> | ||
| 6503 | <event name="OnEnterWindow"></event> | ||
| 6504 | <event name="OnEraseBackground"></event> | ||
| 6505 | <event name="OnKeyDown"></event> | ||
| 6506 | <event name="OnKeyUp"></event> | ||
| 6507 | <event name="OnKillFocus"></event> | ||
| 6508 | <event name="OnLeaveWindow"></event> | ||
| 6509 | <event name="OnLeftDClick"></event> | ||
| 6510 | <event name="OnLeftDown"></event> | ||
| 6511 | <event name="OnLeftUp"></event> | ||
| 6512 | <event name="OnMiddleDClick"></event> | ||
| 6513 | <event name="OnMiddleDown"></event> | ||
| 6514 | <event name="OnMiddleUp"></event> | ||
| 6515 | <event name="OnMotion"></event> | ||
| 6516 | <event name="OnMouseEvents"></event> | ||
| 6517 | <event name="OnMouseWheel"></event> | ||
| 6518 | <event name="OnPaint"></event> | ||
| 6519 | <event name="OnRightDClick"></event> | ||
| 6520 | <event name="OnRightDown"></event> | ||
| 6521 | <event name="OnRightUp"></event> | ||
| 6522 | <event name="OnSetFocus"></event> | ||
| 6523 | <event name="OnSize"></event> | ||
| 6524 | <event name="OnUpdateUI"></event> | ||
| 6525 | </object> | ||
| 6526 | </object> | ||
| 6527 | <object class="sizeritem" expanded="1"> | ||
| 6528 | <property name="border">5</property> | ||
| 6529 | <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property> | ||
| 6530 | <property name="proportion">0</property> | ||
| 6531 | <object class="wxTextCtrl" expanded="1"> | ||
| 6532 | <property name="bg"></property> | ||
| 6533 | <property name="context_help"></property> | ||
| 6534 | <property name="enabled">1</property> | ||
| 6535 | <property name="fg"></property> | ||
| 6536 | <property name="font"></property> | ||
| 6537 | <property name="hidden">0</property> | ||
| 6538 | <property name="id">wxID_ANY</property> | ||
| 6539 | <property name="maximum_size"></property> | ||
| 6540 | <property name="maxlength">0</property> | ||
| 6541 | <property name="minimum_size">150,-1</property> | ||
| 6542 | <property name="name">m_textCtrlLabel5</property> | ||
| 6543 | <property name="permission">protected</property> | ||
| 6544 | <property name="pos"></property> | ||
| 6545 | <property name="size"></property> | ||
| 6546 | <property name="style"></property> | ||
| 6547 | <property name="subclass"></property> | ||
| 6548 | <property name="tooltip"></property> | ||
| 6549 | <property name="value"></property> | ||
| 6550 | <property name="window_extra_style"></property> | ||
| 6551 | <property name="window_name"></property> | ||
| 6552 | <property name="window_style"></property> | ||
| 6553 | <event name="OnChar"></event> | ||
| 6554 | <event name="OnEnterWindow"></event> | ||
| 6555 | <event name="OnEraseBackground"></event> | ||
| 6556 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 6557 | <event name="OnKeyUp"></event> | ||
| 6558 | <event name="OnKillFocus"></event> | ||
| 6559 | <event name="OnLeaveWindow"></event> | ||
| 6560 | <event name="OnLeftDClick"></event> | ||
| 6561 | <event name="OnLeftDown"></event> | ||
| 6562 | <event name="OnLeftUp"></event> | ||
| 6563 | <event name="OnMiddleDClick"></event> | ||
| 6564 | <event name="OnMiddleDown"></event> | ||
| 6565 | <event name="OnMiddleUp"></event> | ||
| 6566 | <event name="OnMotion"></event> | ||
| 6567 | <event name="OnMouseEvents"></event> | ||
| 6568 | <event name="OnMouseWheel"></event> | ||
| 6569 | <event name="OnPaint"></event> | ||
| 6570 | <event name="OnRightDClick"></event> | ||
| 6571 | <event name="OnRightDown"></event> | ||
| 6572 | <event name="OnRightUp"></event> | ||
| 6573 | <event name="OnSetFocus"></event> | ||
| 6574 | <event name="OnSize"></event> | ||
| 6575 | <event name="OnText"></event> | ||
| 6576 | <event name="OnTextEnter"></event> | ||
| 6577 | <event name="OnTextMaxLen"></event> | ||
| 6578 | <event name="OnTextURL"></event> | ||
| 6579 | <event name="OnUpdateUI"></event> | ||
| 6580 | </object> | ||
| 6581 | </object> | ||
| 6582 | <object class="sizeritem" expanded="1"> | ||
| 6583 | <property name="border">5</property> | ||
| 6584 | <property name="flag">wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL</property> | ||
| 6585 | <property name="proportion">0</property> | ||
| 6586 | <object class="wxTextCtrl" expanded="1"> | ||
| 6587 | <property name="bg"></property> | ||
| 6588 | <property name="context_help"></property> | ||
| 6589 | <property name="enabled">1</property> | ||
| 6590 | <property name="fg"></property> | ||
| 6591 | <property name="font"></property> | ||
| 6592 | <property name="hidden">0</property> | ||
| 6593 | <property name="id">wxID_ANY</property> | ||
| 6594 | <property name="maximum_size">-1,-1</property> | ||
| 6595 | <property name="maxlength">0</property> | ||
| 6596 | <property name="minimum_size">-1,-1</property> | ||
| 6597 | <property name="name">m_textCtrlField5</property> | ||
| 6598 | <property name="permission">protected</property> | ||
| 6599 | <property name="pos"></property> | ||
| 6600 | <property name="size">-1,-1</property> | ||
| 6601 | <property name="style"></property> | ||
| 6602 | <property name="subclass"></property> | ||
| 6603 | <property name="tooltip"></property> | ||
| 6604 | <property name="value"></property> | ||
| 6605 | <property name="window_extra_style"></property> | ||
| 6606 | <property name="window_name"></property> | ||
| 6607 | <property name="window_style"></property> | ||
| 6608 | <event name="OnChar"></event> | ||
| 6609 | <event name="OnEnterWindow"></event> | ||
| 6610 | <event name="OnEraseBackground"></event> | ||
| 6611 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 6612 | <event name="OnKeyUp"></event> | ||
| 6613 | <event name="OnKillFocus"></event> | ||
| 6614 | <event name="OnLeaveWindow"></event> | ||
| 6615 | <event name="OnLeftDClick"></event> | ||
| 6616 | <event name="OnLeftDown"></event> | ||
| 6617 | <event name="OnLeftUp"></event> | ||
| 6618 | <event name="OnMiddleDClick"></event> | ||
| 6619 | <event name="OnMiddleDown"></event> | ||
| 6620 | <event name="OnMiddleUp"></event> | ||
| 6621 | <event name="OnMotion"></event> | ||
| 6622 | <event name="OnMouseEvents"></event> | ||
| 6623 | <event name="OnMouseWheel"></event> | ||
| 6624 | <event name="OnPaint"></event> | ||
| 6625 | <event name="OnRightDClick"></event> | ||
| 6626 | <event name="OnRightDown"></event> | ||
| 6627 | <event name="OnRightUp"></event> | ||
| 6628 | <event name="OnSetFocus"></event> | ||
| 6629 | <event name="OnSize"></event> | ||
| 6630 | <event name="OnText"></event> | ||
| 6631 | <event name="OnTextEnter"></event> | ||
| 6632 | <event name="OnTextMaxLen"></event> | ||
| 6633 | <event name="OnTextURL"></event> | ||
| 6634 | <event name="OnUpdateUI"></event> | ||
| 6635 | </object> | ||
| 6636 | </object> | ||
| 6637 | <object class="sizeritem" expanded="1"> | ||
| 6638 | <property name="border">5</property> | ||
| 6639 | <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property> | ||
| 6640 | <property name="proportion">0</property> | ||
| 6641 | <object class="wxButton" expanded="1"> | ||
| 6642 | <property name="bg"></property> | ||
| 6643 | <property name="context_help"></property> | ||
| 6644 | <property name="default">0</property> | ||
| 6645 | <property name="enabled">1</property> | ||
| 6646 | <property name="fg"></property> | ||
| 6647 | <property name="font"></property> | ||
| 6648 | <property name="hidden">0</property> | ||
| 6649 | <property name="id">wxID_DEL5</property> | ||
| 6650 | <property name="label">Delete</property> | ||
| 6651 | <property name="maximum_size"></property> | ||
| 6652 | <property name="minimum_size">-1,-1</property> | ||
| 6653 | <property name="name">m_buttonDel5</property> | ||
| 6654 | <property name="permission">protected</property> | ||
| 6655 | <property name="pos"></property> | ||
| 6656 | <property name="size">60,20</property> | ||
| 6657 | <property name="style"></property> | ||
| 6658 | <property name="subclass"></property> | ||
| 6659 | <property name="tooltip"></property> | ||
| 6660 | <property name="window_extra_style"></property> | ||
| 6661 | <property name="window_name"></property> | ||
| 6662 | <property name="window_style"></property> | ||
| 6663 | <event name="OnButtonClick">OnButtonDel5</event> | ||
| 6664 | <event name="OnChar"></event> | ||
| 6665 | <event name="OnEnterWindow"></event> | ||
| 6666 | <event name="OnEraseBackground"></event> | ||
| 6667 | <event name="OnKeyDown"></event> | ||
| 6668 | <event name="OnKeyUp"></event> | ||
| 6669 | <event name="OnKillFocus"></event> | ||
| 6670 | <event name="OnLeaveWindow"></event> | ||
| 6671 | <event name="OnLeftDClick"></event> | ||
| 6672 | <event name="OnLeftDown"></event> | ||
| 6673 | <event name="OnLeftUp"></event> | ||
| 6674 | <event name="OnMiddleDClick"></event> | ||
| 6675 | <event name="OnMiddleDown"></event> | ||
| 6676 | <event name="OnMiddleUp"></event> | ||
| 6677 | <event name="OnMotion"></event> | ||
| 6678 | <event name="OnMouseEvents"></event> | ||
| 6679 | <event name="OnMouseWheel"></event> | ||
| 6680 | <event name="OnPaint"></event> | ||
| 6681 | <event name="OnRightDClick"></event> | ||
| 6682 | <event name="OnRightDown"></event> | ||
| 6683 | <event name="OnRightUp"></event> | ||
| 6684 | <event name="OnSetFocus"></event> | ||
| 6685 | <event name="OnSize"></event> | ||
| 6686 | <event name="OnUpdateUI"></event> | ||
| 6687 | </object> | ||
| 6688 | </object> | ||
| 6689 | <object class="sizeritem" expanded="1"> | ||
| 6690 | <property name="border">5</property> | ||
| 6691 | <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property> | ||
| 6692 | <property name="proportion">0</property> | ||
| 6693 | <object class="wxTextCtrl" expanded="1"> | ||
| 6694 | <property name="bg"></property> | ||
| 6695 | <property name="context_help"></property> | ||
| 6696 | <property name="enabled">1</property> | ||
| 6697 | <property name="fg"></property> | ||
| 6698 | <property name="font"></property> | ||
| 6699 | <property name="hidden">0</property> | ||
| 6700 | <property name="id">wxID_ANY</property> | ||
| 6701 | <property name="maximum_size"></property> | ||
| 6702 | <property name="maxlength">0</property> | ||
| 6703 | <property name="minimum_size">150,-1</property> | ||
| 6704 | <property name="name">m_textCtrlLabel6</property> | ||
| 6705 | <property name="permission">protected</property> | ||
| 6706 | <property name="pos"></property> | ||
| 6707 | <property name="size"></property> | ||
| 6708 | <property name="style"></property> | ||
| 6709 | <property name="subclass"></property> | ||
| 6710 | <property name="tooltip"></property> | ||
| 6711 | <property name="value"></property> | ||
| 6712 | <property name="window_extra_style"></property> | ||
| 6713 | <property name="window_name"></property> | ||
| 6714 | <property name="window_style"></property> | ||
| 6715 | <event name="OnChar"></event> | ||
| 6716 | <event name="OnEnterWindow"></event> | ||
| 6717 | <event name="OnEraseBackground"></event> | ||
| 6718 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 6719 | <event name="OnKeyUp"></event> | ||
| 6720 | <event name="OnKillFocus"></event> | ||
| 6721 | <event name="OnLeaveWindow"></event> | ||
| 6722 | <event name="OnLeftDClick"></event> | ||
| 6723 | <event name="OnLeftDown"></event> | ||
| 6724 | <event name="OnLeftUp"></event> | ||
| 6725 | <event name="OnMiddleDClick"></event> | ||
| 6726 | <event name="OnMiddleDown"></event> | ||
| 6727 | <event name="OnMiddleUp"></event> | ||
| 6728 | <event name="OnMotion"></event> | ||
| 6729 | <event name="OnMouseEvents"></event> | ||
| 6730 | <event name="OnMouseWheel"></event> | ||
| 6731 | <event name="OnPaint"></event> | ||
| 6732 | <event name="OnRightDClick"></event> | ||
| 6733 | <event name="OnRightDown"></event> | ||
| 6734 | <event name="OnRightUp"></event> | ||
| 6735 | <event name="OnSetFocus"></event> | ||
| 6736 | <event name="OnSize"></event> | ||
| 6737 | <event name="OnText"></event> | ||
| 6738 | <event name="OnTextEnter"></event> | ||
| 6739 | <event name="OnTextMaxLen"></event> | ||
| 6740 | <event name="OnTextURL"></event> | ||
| 6741 | <event name="OnUpdateUI"></event> | ||
| 6742 | </object> | ||
| 6743 | </object> | ||
| 6744 | <object class="sizeritem" expanded="1"> | ||
| 6745 | <property name="border">5</property> | ||
| 6746 | <property name="flag">wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL</property> | ||
| 6747 | <property name="proportion">0</property> | ||
| 6748 | <object class="wxTextCtrl" expanded="1"> | ||
| 6749 | <property name="bg"></property> | ||
| 6750 | <property name="context_help"></property> | ||
| 6751 | <property name="enabled">1</property> | ||
| 6752 | <property name="fg"></property> | ||
| 6753 | <property name="font"></property> | ||
| 6754 | <property name="hidden">0</property> | ||
| 6755 | <property name="id">wxID_ANY</property> | ||
| 6756 | <property name="maximum_size">-1,-1</property> | ||
| 6757 | <property name="maxlength">0</property> | ||
| 6758 | <property name="minimum_size">-1,-1</property> | ||
| 6759 | <property name="name">m_textCtrlField6</property> | ||
| 6760 | <property name="permission">protected</property> | ||
| 6761 | <property name="pos"></property> | ||
| 6762 | <property name="size">-1,-1</property> | ||
| 6763 | <property name="style"></property> | ||
| 6764 | <property name="subclass"></property> | ||
| 6765 | <property name="tooltip"></property> | ||
| 6766 | <property name="value"></property> | ||
| 6767 | <property name="window_extra_style"></property> | ||
| 6768 | <property name="window_name"></property> | ||
| 6769 | <property name="window_style"></property> | ||
| 6770 | <event name="OnChar"></event> | ||
| 6771 | <event name="OnEnterWindow"></event> | ||
| 6772 | <event name="OnEraseBackground"></event> | ||
| 6773 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 6774 | <event name="OnKeyUp"></event> | ||
| 6775 | <event name="OnKillFocus"></event> | ||
| 6776 | <event name="OnLeaveWindow"></event> | ||
| 6777 | <event name="OnLeftDClick"></event> | ||
| 6778 | <event name="OnLeftDown"></event> | ||
| 6779 | <event name="OnLeftUp"></event> | ||
| 6780 | <event name="OnMiddleDClick"></event> | ||
| 6781 | <event name="OnMiddleDown"></event> | ||
| 6782 | <event name="OnMiddleUp"></event> | ||
| 6783 | <event name="OnMotion"></event> | ||
| 6784 | <event name="OnMouseEvents"></event> | ||
| 6785 | <event name="OnMouseWheel"></event> | ||
| 6786 | <event name="OnPaint"></event> | ||
| 6787 | <event name="OnRightDClick"></event> | ||
| 6788 | <event name="OnRightDown"></event> | ||
| 6789 | <event name="OnRightUp"></event> | ||
| 6790 | <event name="OnSetFocus"></event> | ||
| 6791 | <event name="OnSize"></event> | ||
| 6792 | <event name="OnText"></event> | ||
| 6793 | <event name="OnTextEnter"></event> | ||
| 6794 | <event name="OnTextMaxLen"></event> | ||
| 6795 | <event name="OnTextURL"></event> | ||
| 6796 | <event name="OnUpdateUI"></event> | ||
| 6797 | </object> | ||
| 6798 | </object> | ||
| 6799 | <object class="sizeritem" expanded="1"> | ||
| 6800 | <property name="border">5</property> | ||
| 6801 | <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property> | ||
| 6802 | <property name="proportion">0</property> | ||
| 6803 | <object class="wxButton" expanded="1"> | ||
| 6804 | <property name="bg"></property> | ||
| 6805 | <property name="context_help"></property> | ||
| 6806 | <property name="default">0</property> | ||
| 6807 | <property name="enabled">1</property> | ||
| 6808 | <property name="fg"></property> | ||
| 6809 | <property name="font"></property> | ||
| 6810 | <property name="hidden">0</property> | ||
| 6811 | <property name="id">wxID_DEL6</property> | ||
| 6812 | <property name="label">Delete</property> | ||
| 6813 | <property name="maximum_size"></property> | ||
| 6814 | <property name="minimum_size">-1,-1</property> | ||
| 6815 | <property name="name">m_buttonDel6</property> | ||
| 6816 | <property name="permission">protected</property> | ||
| 6817 | <property name="pos"></property> | ||
| 6818 | <property name="size">60,20</property> | ||
| 6819 | <property name="style"></property> | ||
| 6820 | <property name="subclass"></property> | ||
| 6821 | <property name="tooltip"></property> | ||
| 6822 | <property name="window_extra_style"></property> | ||
| 6823 | <property name="window_name"></property> | ||
| 6824 | <property name="window_style"></property> | ||
| 6825 | <event name="OnButtonClick">OnButtonDel6</event> | ||
| 6826 | <event name="OnChar"></event> | ||
| 6827 | <event name="OnEnterWindow"></event> | ||
| 6828 | <event name="OnEraseBackground"></event> | ||
| 6829 | <event name="OnKeyDown"></event> | ||
| 6830 | <event name="OnKeyUp"></event> | ||
| 6831 | <event name="OnKillFocus"></event> | ||
| 6832 | <event name="OnLeaveWindow"></event> | ||
| 6833 | <event name="OnLeftDClick"></event> | ||
| 6834 | <event name="OnLeftDown"></event> | ||
| 6835 | <event name="OnLeftUp"></event> | ||
| 6836 | <event name="OnMiddleDClick"></event> | ||
| 6837 | <event name="OnMiddleDown"></event> | ||
| 6838 | <event name="OnMiddleUp"></event> | ||
| 6839 | <event name="OnMotion"></event> | ||
| 6840 | <event name="OnMouseEvents"></event> | ||
| 6841 | <event name="OnMouseWheel"></event> | ||
| 6842 | <event name="OnPaint"></event> | ||
| 6843 | <event name="OnRightDClick"></event> | ||
| 6844 | <event name="OnRightDown"></event> | ||
| 6845 | <event name="OnRightUp"></event> | ||
| 6846 | <event name="OnSetFocus"></event> | ||
| 6847 | <event name="OnSize"></event> | ||
| 6848 | <event name="OnUpdateUI"></event> | ||
| 6849 | </object> | ||
| 6850 | </object> | ||
| 6851 | <object class="sizeritem" expanded="1"> | ||
| 6852 | <property name="border">5</property> | ||
| 6853 | <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property> | ||
| 6854 | <property name="proportion">0</property> | ||
| 6855 | <object class="wxTextCtrl" expanded="1"> | ||
| 6856 | <property name="bg"></property> | ||
| 6857 | <property name="context_help"></property> | ||
| 6858 | <property name="enabled">1</property> | ||
| 6859 | <property name="fg"></property> | ||
| 6860 | <property name="font"></property> | ||
| 6861 | <property name="hidden">0</property> | ||
| 6862 | <property name="id">wxID_ANY</property> | ||
| 6863 | <property name="maximum_size"></property> | ||
| 6864 | <property name="maxlength">0</property> | ||
| 6865 | <property name="minimum_size">150,-1</property> | ||
| 6866 | <property name="name">m_textCtrlLabel7</property> | ||
| 6867 | <property name="permission">protected</property> | ||
| 6868 | <property name="pos"></property> | ||
| 6869 | <property name="size"></property> | ||
| 6870 | <property name="style"></property> | ||
| 6871 | <property name="subclass"></property> | ||
| 6872 | <property name="tooltip"></property> | ||
| 6873 | <property name="value"></property> | ||
| 6874 | <property name="window_extra_style"></property> | ||
| 6875 | <property name="window_name"></property> | ||
| 6876 | <property name="window_style"></property> | ||
| 6877 | <event name="OnChar"></event> | ||
| 6878 | <event name="OnEnterWindow"></event> | ||
| 6879 | <event name="OnEraseBackground"></event> | ||
| 6880 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 6881 | <event name="OnKeyUp"></event> | ||
| 6882 | <event name="OnKillFocus"></event> | ||
| 6883 | <event name="OnLeaveWindow"></event> | ||
| 6884 | <event name="OnLeftDClick"></event> | ||
| 6885 | <event name="OnLeftDown"></event> | ||
| 6886 | <event name="OnLeftUp"></event> | ||
| 6887 | <event name="OnMiddleDClick"></event> | ||
| 6888 | <event name="OnMiddleDown"></event> | ||
| 6889 | <event name="OnMiddleUp"></event> | ||
| 6890 | <event name="OnMotion"></event> | ||
| 6891 | <event name="OnMouseEvents"></event> | ||
| 6892 | <event name="OnMouseWheel"></event> | ||
| 6893 | <event name="OnPaint"></event> | ||
| 6894 | <event name="OnRightDClick"></event> | ||
| 6895 | <event name="OnRightDown"></event> | ||
| 6896 | <event name="OnRightUp"></event> | ||
| 6897 | <event name="OnSetFocus"></event> | ||
| 6898 | <event name="OnSize"></event> | ||
| 6899 | <event name="OnText"></event> | ||
| 6900 | <event name="OnTextEnter"></event> | ||
| 6901 | <event name="OnTextMaxLen"></event> | ||
| 6902 | <event name="OnTextURL"></event> | ||
| 6903 | <event name="OnUpdateUI"></event> | ||
| 6904 | </object> | ||
| 6905 | </object> | ||
| 6906 | <object class="sizeritem" expanded="1"> | ||
| 6907 | <property name="border">5</property> | ||
| 6908 | <property name="flag">wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL</property> | ||
| 6909 | <property name="proportion">0</property> | ||
| 6910 | <object class="wxTextCtrl" expanded="1"> | ||
| 6911 | <property name="bg"></property> | ||
| 6912 | <property name="context_help"></property> | ||
| 6913 | <property name="enabled">1</property> | ||
| 6914 | <property name="fg"></property> | ||
| 6915 | <property name="font"></property> | ||
| 6916 | <property name="hidden">0</property> | ||
| 6917 | <property name="id">wxID_ANY</property> | ||
| 6918 | <property name="maximum_size">-1,-1</property> | ||
| 6919 | <property name="maxlength">0</property> | ||
| 6920 | <property name="minimum_size">-1,-1</property> | ||
| 6921 | <property name="name">m_textCtrlField7</property> | ||
| 6922 | <property name="permission">protected</property> | ||
| 6923 | <property name="pos"></property> | ||
| 6924 | <property name="size">-1,-1</property> | ||
| 6925 | <property name="style"></property> | ||
| 6926 | <property name="subclass"></property> | ||
| 6927 | <property name="tooltip"></property> | ||
| 6928 | <property name="value"></property> | ||
| 6929 | <property name="window_extra_style"></property> | ||
| 6930 | <property name="window_name"></property> | ||
| 6931 | <property name="window_style"></property> | ||
| 6932 | <event name="OnChar"></event> | ||
| 6933 | <event name="OnEnterWindow"></event> | ||
| 6934 | <event name="OnEraseBackground"></event> | ||
| 6935 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 6936 | <event name="OnKeyUp"></event> | ||
| 6937 | <event name="OnKillFocus"></event> | ||
| 6938 | <event name="OnLeaveWindow"></event> | ||
| 6939 | <event name="OnLeftDClick"></event> | ||
| 6940 | <event name="OnLeftDown"></event> | ||
| 6941 | <event name="OnLeftUp"></event> | ||
| 6942 | <event name="OnMiddleDClick"></event> | ||
| 6943 | <event name="OnMiddleDown"></event> | ||
| 6944 | <event name="OnMiddleUp"></event> | ||
| 6945 | <event name="OnMotion"></event> | ||
| 6946 | <event name="OnMouseEvents"></event> | ||
| 6947 | <event name="OnMouseWheel"></event> | ||
| 6948 | <event name="OnPaint"></event> | ||
| 6949 | <event name="OnRightDClick"></event> | ||
| 6950 | <event name="OnRightDown"></event> | ||
| 6951 | <event name="OnRightUp"></event> | ||
| 6952 | <event name="OnSetFocus"></event> | ||
| 6953 | <event name="OnSize"></event> | ||
| 6954 | <event name="OnText"></event> | ||
| 6955 | <event name="OnTextEnter"></event> | ||
| 6956 | <event name="OnTextMaxLen"></event> | ||
| 6957 | <event name="OnTextURL"></event> | ||
| 6958 | <event name="OnUpdateUI"></event> | ||
| 6959 | </object> | ||
| 6960 | </object> | ||
| 6961 | <object class="sizeritem" expanded="1"> | ||
| 6962 | <property name="border">5</property> | ||
| 6963 | <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property> | ||
| 6964 | <property name="proportion">0</property> | ||
| 6965 | <object class="wxButton" expanded="1"> | ||
| 6966 | <property name="bg"></property> | ||
| 6967 | <property name="context_help"></property> | ||
| 6968 | <property name="default">0</property> | ||
| 6969 | <property name="enabled">1</property> | ||
| 6970 | <property name="fg"></property> | ||
| 6971 | <property name="font"></property> | ||
| 6972 | <property name="hidden">0</property> | ||
| 6973 | <property name="id">wxID_DEL7</property> | ||
| 6974 | <property name="label">Delete</property> | ||
| 6975 | <property name="maximum_size"></property> | ||
| 6976 | <property name="minimum_size">-1,-1</property> | ||
| 6977 | <property name="name">m_buttonDel7</property> | ||
| 6978 | <property name="permission">protected</property> | ||
| 6979 | <property name="pos"></property> | ||
| 6980 | <property name="size">60,20</property> | ||
| 6981 | <property name="style"></property> | ||
| 6982 | <property name="subclass"></property> | ||
| 6983 | <property name="tooltip"></property> | ||
| 6984 | <property name="window_extra_style"></property> | ||
| 6985 | <property name="window_name"></property> | ||
| 6986 | <property name="window_style"></property> | ||
| 6987 | <event name="OnButtonClick">OnButtonDel7</event> | ||
| 6988 | <event name="OnChar"></event> | ||
| 6989 | <event name="OnEnterWindow"></event> | ||
| 6990 | <event name="OnEraseBackground"></event> | ||
| 6991 | <event name="OnKeyDown"></event> | ||
| 6992 | <event name="OnKeyUp"></event> | ||
| 6993 | <event name="OnKillFocus"></event> | ||
| 6994 | <event name="OnLeaveWindow"></event> | ||
| 6995 | <event name="OnLeftDClick"></event> | ||
| 6996 | <event name="OnLeftDown"></event> | ||
| 6997 | <event name="OnLeftUp"></event> | ||
| 6998 | <event name="OnMiddleDClick"></event> | ||
| 6999 | <event name="OnMiddleDown"></event> | ||
| 7000 | <event name="OnMiddleUp"></event> | ||
| 7001 | <event name="OnMotion"></event> | ||
| 7002 | <event name="OnMouseEvents"></event> | ||
| 7003 | <event name="OnMouseWheel"></event> | ||
| 7004 | <event name="OnPaint"></event> | ||
| 7005 | <event name="OnRightDClick"></event> | ||
| 7006 | <event name="OnRightDown"></event> | ||
| 7007 | <event name="OnRightUp"></event> | ||
| 7008 | <event name="OnSetFocus"></event> | ||
| 7009 | <event name="OnSize"></event> | ||
| 7010 | <event name="OnUpdateUI"></event> | ||
| 7011 | </object> | ||
| 7012 | </object> | ||
| 7013 | <object class="sizeritem" expanded="1"> | ||
| 7014 | <property name="border">5</property> | ||
| 7015 | <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property> | ||
| 7016 | <property name="proportion">0</property> | ||
| 7017 | <object class="wxTextCtrl" expanded="1"> | ||
| 7018 | <property name="bg"></property> | ||
| 7019 | <property name="context_help"></property> | ||
| 7020 | <property name="enabled">1</property> | ||
| 7021 | <property name="fg"></property> | ||
| 7022 | <property name="font"></property> | ||
| 7023 | <property name="hidden">0</property> | ||
| 7024 | <property name="id">wxID_ANY</property> | ||
| 7025 | <property name="maximum_size"></property> | ||
| 7026 | <property name="maxlength">0</property> | ||
| 7027 | <property name="minimum_size">150,-1</property> | ||
| 7028 | <property name="name">m_textCtrlLabel8</property> | ||
| 7029 | <property name="permission">protected</property> | ||
| 7030 | <property name="pos"></property> | ||
| 7031 | <property name="size"></property> | ||
| 7032 | <property name="style"></property> | ||
| 7033 | <property name="subclass"></property> | ||
| 7034 | <property name="tooltip"></property> | ||
| 7035 | <property name="value"></property> | ||
| 7036 | <property name="window_extra_style"></property> | ||
| 7037 | <property name="window_name"></property> | ||
| 7038 | <property name="window_style"></property> | ||
| 7039 | <event name="OnChar"></event> | ||
| 7040 | <event name="OnEnterWindow"></event> | ||
| 7041 | <event name="OnEraseBackground"></event> | ||
| 7042 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 7043 | <event name="OnKeyUp"></event> | ||
| 7044 | <event name="OnKillFocus"></event> | ||
| 7045 | <event name="OnLeaveWindow"></event> | ||
| 7046 | <event name="OnLeftDClick"></event> | ||
| 7047 | <event name="OnLeftDown"></event> | ||
| 7048 | <event name="OnLeftUp"></event> | ||
| 7049 | <event name="OnMiddleDClick"></event> | ||
| 7050 | <event name="OnMiddleDown"></event> | ||
| 7051 | <event name="OnMiddleUp"></event> | ||
| 7052 | <event name="OnMotion"></event> | ||
| 7053 | <event name="OnMouseEvents"></event> | ||
| 7054 | <event name="OnMouseWheel"></event> | ||
| 7055 | <event name="OnPaint"></event> | ||
| 7056 | <event name="OnRightDClick"></event> | ||
| 7057 | <event name="OnRightDown"></event> | ||
| 7058 | <event name="OnRightUp"></event> | ||
| 7059 | <event name="OnSetFocus"></event> | ||
| 7060 | <event name="OnSize"></event> | ||
| 7061 | <event name="OnText"></event> | ||
| 7062 | <event name="OnTextEnter"></event> | ||
| 7063 | <event name="OnTextMaxLen"></event> | ||
| 7064 | <event name="OnTextURL"></event> | ||
| 7065 | <event name="OnUpdateUI"></event> | ||
| 7066 | </object> | ||
| 7067 | </object> | ||
| 7068 | <object class="sizeritem" expanded="1"> | ||
| 7069 | <property name="border">5</property> | ||
| 7070 | <property name="flag">wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL</property> | ||
| 7071 | <property name="proportion">0</property> | ||
| 7072 | <object class="wxTextCtrl" expanded="1"> | ||
| 7073 | <property name="bg"></property> | ||
| 7074 | <property name="context_help"></property> | ||
| 7075 | <property name="enabled">1</property> | ||
| 7076 | <property name="fg"></property> | ||
| 7077 | <property name="font"></property> | ||
| 7078 | <property name="hidden">0</property> | ||
| 7079 | <property name="id">wxID_ANY</property> | ||
| 7080 | <property name="maximum_size">-1,-1</property> | ||
| 7081 | <property name="maxlength">0</property> | ||
| 7082 | <property name="minimum_size">-1,-1</property> | ||
| 7083 | <property name="name">m_textCtrlField8</property> | ||
| 7084 | <property name="permission">protected</property> | ||
| 7085 | <property name="pos"></property> | ||
| 7086 | <property name="size">-1,-1</property> | ||
| 7087 | <property name="style"></property> | ||
| 7088 | <property name="subclass"></property> | ||
| 7089 | <property name="tooltip"></property> | ||
| 7090 | <property name="value"></property> | ||
| 7091 | <property name="window_extra_style"></property> | ||
| 7092 | <property name="window_name"></property> | ||
| 7093 | <property name="window_style"></property> | ||
| 7094 | <event name="OnChar"></event> | ||
| 7095 | <event name="OnEnterWindow"></event> | ||
| 7096 | <event name="OnEraseBackground"></event> | ||
| 7097 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 7098 | <event name="OnKeyUp"></event> | ||
| 7099 | <event name="OnKillFocus"></event> | ||
| 7100 | <event name="OnLeaveWindow"></event> | ||
| 7101 | <event name="OnLeftDClick"></event> | ||
| 7102 | <event name="OnLeftDown"></event> | ||
| 7103 | <event name="OnLeftUp"></event> | ||
| 7104 | <event name="OnMiddleDClick"></event> | ||
| 7105 | <event name="OnMiddleDown"></event> | ||
| 7106 | <event name="OnMiddleUp"></event> | ||
| 7107 | <event name="OnMotion"></event> | ||
| 7108 | <event name="OnMouseEvents"></event> | ||
| 7109 | <event name="OnMouseWheel"></event> | ||
| 7110 | <event name="OnPaint"></event> | ||
| 7111 | <event name="OnRightDClick"></event> | ||
| 7112 | <event name="OnRightDown"></event> | ||
| 7113 | <event name="OnRightUp"></event> | ||
| 7114 | <event name="OnSetFocus"></event> | ||
| 7115 | <event name="OnSize"></event> | ||
| 7116 | <event name="OnText"></event> | ||
| 7117 | <event name="OnTextEnter"></event> | ||
| 7118 | <event name="OnTextMaxLen"></event> | ||
| 7119 | <event name="OnTextURL"></event> | ||
| 7120 | <event name="OnUpdateUI"></event> | ||
| 7121 | </object> | ||
| 7122 | </object> | ||
| 7123 | <object class="sizeritem" expanded="1"> | ||
| 7124 | <property name="border">5</property> | ||
| 7125 | <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property> | ||
| 7126 | <property name="proportion">0</property> | ||
| 7127 | <object class="wxButton" expanded="1"> | ||
| 7128 | <property name="bg"></property> | ||
| 7129 | <property name="context_help"></property> | ||
| 7130 | <property name="default">0</property> | ||
| 7131 | <property name="enabled">1</property> | ||
| 7132 | <property name="fg"></property> | ||
| 7133 | <property name="font"></property> | ||
| 7134 | <property name="hidden">0</property> | ||
| 7135 | <property name="id">wxID_DEL8</property> | ||
| 7136 | <property name="label">Delete</property> | ||
| 7137 | <property name="maximum_size"></property> | ||
| 7138 | <property name="minimum_size">-1,-1</property> | ||
| 7139 | <property name="name">m_buttonDel8</property> | ||
| 7140 | <property name="permission">protected</property> | ||
| 7141 | <property name="pos"></property> | ||
| 7142 | <property name="size">60,20</property> | ||
| 7143 | <property name="style"></property> | ||
| 7144 | <property name="subclass"></property> | ||
| 7145 | <property name="tooltip"></property> | ||
| 7146 | <property name="window_extra_style"></property> | ||
| 7147 | <property name="window_name"></property> | ||
| 7148 | <property name="window_style"></property> | ||
| 7149 | <event name="OnButtonClick">OnButtonDel8</event> | ||
| 7150 | <event name="OnChar"></event> | ||
| 7151 | <event name="OnEnterWindow"></event> | ||
| 7152 | <event name="OnEraseBackground"></event> | ||
| 7153 | <event name="OnKeyDown"></event> | ||
| 7154 | <event name="OnKeyUp"></event> | ||
| 7155 | <event name="OnKillFocus"></event> | ||
| 7156 | <event name="OnLeaveWindow"></event> | ||
| 7157 | <event name="OnLeftDClick"></event> | ||
| 7158 | <event name="OnLeftDown"></event> | ||
| 7159 | <event name="OnLeftUp"></event> | ||
| 7160 | <event name="OnMiddleDClick"></event> | ||
| 7161 | <event name="OnMiddleDown"></event> | ||
| 7162 | <event name="OnMiddleUp"></event> | ||
| 7163 | <event name="OnMotion"></event> | ||
| 7164 | <event name="OnMouseEvents"></event> | ||
| 7165 | <event name="OnMouseWheel"></event> | ||
| 7166 | <event name="OnPaint"></event> | ||
| 7167 | <event name="OnRightDClick"></event> | ||
| 7168 | <event name="OnRightDown"></event> | ||
| 7169 | <event name="OnRightUp"></event> | ||
| 7170 | <event name="OnSetFocus"></event> | ||
| 7171 | <event name="OnSize"></event> | ||
| 7172 | <event name="OnUpdateUI"></event> | ||
| 7173 | </object> | ||
| 7174 | </object> | ||
| 7175 | <object class="sizeritem" expanded="1"> | ||
| 7176 | <property name="border">5</property> | ||
| 7177 | <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property> | ||
| 7178 | <property name="proportion">0</property> | ||
| 7179 | <object class="wxTextCtrl" expanded="1"> | ||
| 7180 | <property name="bg"></property> | ||
| 7181 | <property name="context_help"></property> | ||
| 7182 | <property name="enabled">1</property> | ||
| 7183 | <property name="fg"></property> | ||
| 7184 | <property name="font"></property> | ||
| 7185 | <property name="hidden">0</property> | ||
| 7186 | <property name="id">wxID_ANY</property> | ||
| 7187 | <property name="maximum_size"></property> | ||
| 7188 | <property name="maxlength">0</property> | ||
| 7189 | <property name="minimum_size">150,-1</property> | ||
| 7190 | <property name="name">m_textCtrlLabel9</property> | ||
| 7191 | <property name="permission">protected</property> | ||
| 7192 | <property name="pos"></property> | ||
| 7193 | <property name="size"></property> | ||
| 7194 | <property name="style"></property> | ||
| 7195 | <property name="subclass"></property> | ||
| 7196 | <property name="tooltip"></property> | ||
| 7197 | <property name="value"></property> | ||
| 7198 | <property name="window_extra_style"></property> | ||
| 7199 | <property name="window_name"></property> | ||
| 7200 | <property name="window_style"></property> | ||
| 7201 | <event name="OnChar"></event> | ||
| 7202 | <event name="OnEnterWindow"></event> | ||
| 7203 | <event name="OnEraseBackground"></event> | ||
| 7204 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 7205 | <event name="OnKeyUp"></event> | ||
| 7206 | <event name="OnKillFocus"></event> | ||
| 7207 | <event name="OnLeaveWindow"></event> | ||
| 7208 | <event name="OnLeftDClick"></event> | ||
| 7209 | <event name="OnLeftDown"></event> | ||
| 7210 | <event name="OnLeftUp"></event> | ||
| 7211 | <event name="OnMiddleDClick"></event> | ||
| 7212 | <event name="OnMiddleDown"></event> | ||
| 7213 | <event name="OnMiddleUp"></event> | ||
| 7214 | <event name="OnMotion"></event> | ||
| 7215 | <event name="OnMouseEvents"></event> | ||
| 7216 | <event name="OnMouseWheel"></event> | ||
| 7217 | <event name="OnPaint"></event> | ||
| 7218 | <event name="OnRightDClick"></event> | ||
| 7219 | <event name="OnRightDown"></event> | ||
| 7220 | <event name="OnRightUp"></event> | ||
| 7221 | <event name="OnSetFocus"></event> | ||
| 7222 | <event name="OnSize"></event> | ||
| 7223 | <event name="OnText"></event> | ||
| 7224 | <event name="OnTextEnter"></event> | ||
| 7225 | <event name="OnTextMaxLen"></event> | ||
| 7226 | <event name="OnTextURL"></event> | ||
| 7227 | <event name="OnUpdateUI"></event> | ||
| 7228 | </object> | ||
| 7229 | </object> | ||
| 7230 | <object class="sizeritem" expanded="1"> | ||
| 7231 | <property name="border">5</property> | ||
| 7232 | <property name="flag">wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL</property> | ||
| 7233 | <property name="proportion">0</property> | ||
| 7234 | <object class="wxTextCtrl" expanded="1"> | ||
| 7235 | <property name="bg"></property> | ||
| 7236 | <property name="context_help"></property> | ||
| 7237 | <property name="enabled">1</property> | ||
| 7238 | <property name="fg"></property> | ||
| 7239 | <property name="font"></property> | ||
| 7240 | <property name="hidden">0</property> | ||
| 7241 | <property name="id">wxID_ANY</property> | ||
| 7242 | <property name="maximum_size">-1,-1</property> | ||
| 7243 | <property name="maxlength">0</property> | ||
| 7244 | <property name="minimum_size">-1,-1</property> | ||
| 7245 | <property name="name">m_textCtrlField9</property> | ||
| 7246 | <property name="permission">protected</property> | ||
| 7247 | <property name="pos"></property> | ||
| 7248 | <property name="size">-1,-1</property> | ||
| 7249 | <property name="style"></property> | ||
| 7250 | <property name="subclass"></property> | ||
| 7251 | <property name="tooltip"></property> | ||
| 7252 | <property name="value"></property> | ||
| 7253 | <property name="window_extra_style"></property> | ||
| 7254 | <property name="window_name"></property> | ||
| 7255 | <property name="window_style"></property> | ||
| 7256 | <event name="OnChar"></event> | ||
| 7257 | <event name="OnEnterWindow"></event> | ||
| 7258 | <event name="OnEraseBackground"></event> | ||
| 7259 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 7260 | <event name="OnKeyUp"></event> | ||
| 7261 | <event name="OnKillFocus"></event> | ||
| 7262 | <event name="OnLeaveWindow"></event> | ||
| 7263 | <event name="OnLeftDClick"></event> | ||
| 7264 | <event name="OnLeftDown"></event> | ||
| 7265 | <event name="OnLeftUp"></event> | ||
| 7266 | <event name="OnMiddleDClick"></event> | ||
| 7267 | <event name="OnMiddleDown"></event> | ||
| 7268 | <event name="OnMiddleUp"></event> | ||
| 7269 | <event name="OnMotion"></event> | ||
| 7270 | <event name="OnMouseEvents"></event> | ||
| 7271 | <event name="OnMouseWheel"></event> | ||
| 7272 | <event name="OnPaint"></event> | ||
| 7273 | <event name="OnRightDClick"></event> | ||
| 7274 | <event name="OnRightDown"></event> | ||
| 7275 | <event name="OnRightUp"></event> | ||
| 7276 | <event name="OnSetFocus"></event> | ||
| 7277 | <event name="OnSize"></event> | ||
| 7278 | <event name="OnText"></event> | ||
| 7279 | <event name="OnTextEnter"></event> | ||
| 7280 | <event name="OnTextMaxLen"></event> | ||
| 7281 | <event name="OnTextURL"></event> | ||
| 7282 | <event name="OnUpdateUI"></event> | ||
| 7283 | </object> | ||
| 7284 | </object> | ||
| 7285 | <object class="sizeritem" expanded="1"> | ||
| 7286 | <property name="border">5</property> | ||
| 7287 | <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property> | ||
| 7288 | <property name="proportion">0</property> | ||
| 7289 | <object class="wxButton" expanded="1"> | ||
| 7290 | <property name="bg"></property> | ||
| 7291 | <property name="context_help"></property> | ||
| 7292 | <property name="default">0</property> | ||
| 7293 | <property name="enabled">1</property> | ||
| 7294 | <property name="fg"></property> | ||
| 7295 | <property name="font"></property> | ||
| 7296 | <property name="hidden">0</property> | ||
| 7297 | <property name="id">wxID_DEL9</property> | ||
| 7298 | <property name="label">Delete</property> | ||
| 7299 | <property name="maximum_size"></property> | ||
| 7300 | <property name="minimum_size">-1,-1</property> | ||
| 7301 | <property name="name">m_buttonDel9</property> | ||
| 7302 | <property name="permission">protected</property> | ||
| 7303 | <property name="pos"></property> | ||
| 7304 | <property name="size">60,20</property> | ||
| 7305 | <property name="style"></property> | ||
| 7306 | <property name="subclass"></property> | ||
| 7307 | <property name="tooltip"></property> | ||
| 7308 | <property name="window_extra_style"></property> | ||
| 7309 | <property name="window_name"></property> | ||
| 7310 | <property name="window_style"></property> | ||
| 7311 | <event name="OnButtonClick">OnButtonDel9</event> | ||
| 7312 | <event name="OnChar"></event> | ||
| 7313 | <event name="OnEnterWindow"></event> | ||
| 7314 | <event name="OnEraseBackground"></event> | ||
| 7315 | <event name="OnKeyDown"></event> | ||
| 7316 | <event name="OnKeyUp"></event> | ||
| 7317 | <event name="OnKillFocus"></event> | ||
| 7318 | <event name="OnLeaveWindow"></event> | ||
| 7319 | <event name="OnLeftDClick"></event> | ||
| 7320 | <event name="OnLeftDown"></event> | ||
| 7321 | <event name="OnLeftUp"></event> | ||
| 7322 | <event name="OnMiddleDClick"></event> | ||
| 7323 | <event name="OnMiddleDown"></event> | ||
| 7324 | <event name="OnMiddleUp"></event> | ||
| 7325 | <event name="OnMotion"></event> | ||
| 7326 | <event name="OnMouseEvents"></event> | ||
| 7327 | <event name="OnMouseWheel"></event> | ||
| 7328 | <event name="OnPaint"></event> | ||
| 7329 | <event name="OnRightDClick"></event> | ||
| 7330 | <event name="OnRightDown"></event> | ||
| 7331 | <event name="OnRightUp"></event> | ||
| 7332 | <event name="OnSetFocus"></event> | ||
| 7333 | <event name="OnSize"></event> | ||
| 7334 | <event name="OnUpdateUI"></event> | ||
| 7335 | </object> | ||
| 7336 | </object> | ||
| 7337 | <object class="sizeritem" expanded="1"> | ||
| 7338 | <property name="border">5</property> | ||
| 7339 | <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property> | ||
| 7340 | <property name="proportion">0</property> | ||
| 7341 | <object class="wxTextCtrl" expanded="1"> | ||
| 7342 | <property name="bg"></property> | ||
| 7343 | <property name="context_help"></property> | ||
| 7344 | <property name="enabled">1</property> | ||
| 7345 | <property name="fg"></property> | ||
| 7346 | <property name="font"></property> | ||
| 7347 | <property name="hidden">0</property> | ||
| 7348 | <property name="id">wxID_ANY</property> | ||
| 7349 | <property name="maximum_size"></property> | ||
| 7350 | <property name="maxlength">0</property> | ||
| 7351 | <property name="minimum_size">150,-1</property> | ||
| 7352 | <property name="name">m_textCtrlLabel10</property> | ||
| 7353 | <property name="permission">protected</property> | ||
| 7354 | <property name="pos"></property> | ||
| 7355 | <property name="size"></property> | ||
| 7356 | <property name="style"></property> | ||
| 7357 | <property name="subclass"></property> | ||
| 7358 | <property name="tooltip"></property> | ||
| 7359 | <property name="value"></property> | ||
| 7360 | <property name="window_extra_style"></property> | ||
| 7361 | <property name="window_name"></property> | ||
| 7362 | <property name="window_style"></property> | ||
| 7363 | <event name="OnChar"></event> | ||
| 7364 | <event name="OnEnterWindow"></event> | ||
| 7365 | <event name="OnEraseBackground"></event> | ||
| 7366 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 7367 | <event name="OnKeyUp"></event> | ||
| 7368 | <event name="OnKillFocus"></event> | ||
| 7369 | <event name="OnLeaveWindow"></event> | ||
| 7370 | <event name="OnLeftDClick"></event> | ||
| 7371 | <event name="OnLeftDown"></event> | ||
| 7372 | <event name="OnLeftUp"></event> | ||
| 7373 | <event name="OnMiddleDClick"></event> | ||
| 7374 | <event name="OnMiddleDown"></event> | ||
| 7375 | <event name="OnMiddleUp"></event> | ||
| 7376 | <event name="OnMotion"></event> | ||
| 7377 | <event name="OnMouseEvents"></event> | ||
| 7378 | <event name="OnMouseWheel"></event> | ||
| 7379 | <event name="OnPaint"></event> | ||
| 7380 | <event name="OnRightDClick"></event> | ||
| 7381 | <event name="OnRightDown"></event> | ||
| 7382 | <event name="OnRightUp"></event> | ||
| 7383 | <event name="OnSetFocus"></event> | ||
| 7384 | <event name="OnSize"></event> | ||
| 7385 | <event name="OnText"></event> | ||
| 7386 | <event name="OnTextEnter"></event> | ||
| 7387 | <event name="OnTextMaxLen"></event> | ||
| 7388 | <event name="OnTextURL"></event> | ||
| 7389 | <event name="OnUpdateUI"></event> | ||
| 7390 | </object> | ||
| 7391 | </object> | ||
| 7392 | <object class="sizeritem" expanded="1"> | ||
| 7393 | <property name="border">5</property> | ||
| 7394 | <property name="flag">wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL</property> | ||
| 7395 | <property name="proportion">0</property> | ||
| 7396 | <object class="wxTextCtrl" expanded="1"> | ||
| 7397 | <property name="bg"></property> | ||
| 7398 | <property name="context_help"></property> | ||
| 7399 | <property name="enabled">1</property> | ||
| 7400 | <property name="fg"></property> | ||
| 7401 | <property name="font"></property> | ||
| 7402 | <property name="hidden">0</property> | ||
| 7403 | <property name="id">wxID_ANY</property> | ||
| 7404 | <property name="maximum_size">-1,-1</property> | ||
| 7405 | <property name="maxlength">0</property> | ||
| 7406 | <property name="minimum_size">-1,-1</property> | ||
| 7407 | <property name="name">m_textCtrlField10</property> | ||
| 7408 | <property name="permission">protected</property> | ||
| 7409 | <property name="pos"></property> | ||
| 7410 | <property name="size">-1,-1</property> | ||
| 7411 | <property name="style"></property> | ||
| 7412 | <property name="subclass"></property> | ||
| 7413 | <property name="tooltip"></property> | ||
| 7414 | <property name="value"></property> | ||
| 7415 | <property name="window_extra_style"></property> | ||
| 7416 | <property name="window_name"></property> | ||
| 7417 | <property name="window_style"></property> | ||
| 7418 | <event name="OnChar"></event> | ||
| 7419 | <event name="OnEnterWindow"></event> | ||
| 7420 | <event name="OnEraseBackground"></event> | ||
| 7421 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 7422 | <event name="OnKeyUp"></event> | ||
| 7423 | <event name="OnKillFocus"></event> | ||
| 7424 | <event name="OnLeaveWindow"></event> | ||
| 7425 | <event name="OnLeftDClick"></event> | ||
| 7426 | <event name="OnLeftDown"></event> | ||
| 7427 | <event name="OnLeftUp"></event> | ||
| 7428 | <event name="OnMiddleDClick"></event> | ||
| 7429 | <event name="OnMiddleDown"></event> | ||
| 7430 | <event name="OnMiddleUp"></event> | ||
| 7431 | <event name="OnMotion"></event> | ||
| 7432 | <event name="OnMouseEvents"></event> | ||
| 7433 | <event name="OnMouseWheel"></event> | ||
| 7434 | <event name="OnPaint"></event> | ||
| 7435 | <event name="OnRightDClick"></event> | ||
| 7436 | <event name="OnRightDown"></event> | ||
| 7437 | <event name="OnRightUp"></event> | ||
| 7438 | <event name="OnSetFocus"></event> | ||
| 7439 | <event name="OnSize"></event> | ||
| 7440 | <event name="OnText"></event> | ||
| 7441 | <event name="OnTextEnter"></event> | ||
| 7442 | <event name="OnTextMaxLen"></event> | ||
| 7443 | <event name="OnTextURL"></event> | ||
| 7444 | <event name="OnUpdateUI"></event> | ||
| 7445 | </object> | ||
| 7446 | </object> | ||
| 7447 | <object class="sizeritem" expanded="1"> | ||
| 7448 | <property name="border">5</property> | ||
| 7449 | <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property> | ||
| 7450 | <property name="proportion">0</property> | ||
| 7451 | <object class="wxButton" expanded="1"> | ||
| 7452 | <property name="bg"></property> | ||
| 7453 | <property name="context_help"></property> | ||
| 7454 | <property name="default">0</property> | ||
| 7455 | <property name="enabled">1</property> | ||
| 7456 | <property name="fg"></property> | ||
| 7457 | <property name="font"></property> | ||
| 7458 | <property name="hidden">0</property> | ||
| 7459 | <property name="id">wxID_DEL10</property> | ||
| 7460 | <property name="label">Delete</property> | ||
| 7461 | <property name="maximum_size"></property> | ||
| 7462 | <property name="minimum_size">-1,-1</property> | ||
| 7463 | <property name="name">m_buttonDel10</property> | ||
| 7464 | <property name="permission">protected</property> | ||
| 7465 | <property name="pos"></property> | ||
| 7466 | <property name="size">60,20</property> | ||
| 7467 | <property name="style"></property> | ||
| 7468 | <property name="subclass"></property> | ||
| 7469 | <property name="tooltip"></property> | ||
| 7470 | <property name="window_extra_style"></property> | ||
| 7471 | <property name="window_name"></property> | ||
| 7472 | <property name="window_style"></property> | ||
| 7473 | <event name="OnButtonClick">OnButtonDel10</event> | ||
| 7474 | <event name="OnChar"></event> | ||
| 7475 | <event name="OnEnterWindow"></event> | ||
| 7476 | <event name="OnEraseBackground"></event> | ||
| 7477 | <event name="OnKeyDown"></event> | ||
| 7478 | <event name="OnKeyUp"></event> | ||
| 7479 | <event name="OnKillFocus"></event> | ||
| 7480 | <event name="OnLeaveWindow"></event> | ||
| 7481 | <event name="OnLeftDClick"></event> | ||
| 7482 | <event name="OnLeftDown"></event> | ||
| 7483 | <event name="OnLeftUp"></event> | ||
| 7484 | <event name="OnMiddleDClick"></event> | ||
| 7485 | <event name="OnMiddleDown"></event> | ||
| 7486 | <event name="OnMiddleUp"></event> | ||
| 7487 | <event name="OnMotion"></event> | ||
| 7488 | <event name="OnMouseEvents"></event> | ||
| 7489 | <event name="OnMouseWheel"></event> | ||
| 7490 | <event name="OnPaint"></event> | ||
| 7491 | <event name="OnRightDClick"></event> | ||
| 7492 | <event name="OnRightDown"></event> | ||
| 7493 | <event name="OnRightUp"></event> | ||
| 7494 | <event name="OnSetFocus"></event> | ||
| 7495 | <event name="OnSize"></event> | ||
| 7496 | <event name="OnUpdateUI"></event> | ||
| 7497 | </object> | ||
| 7498 | </object> | ||
| 7499 | <object class="sizeritem" expanded="1"> | ||
| 7500 | <property name="border">5</property> | ||
| 7501 | <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property> | ||
| 7502 | <property name="proportion">0</property> | ||
| 7503 | <object class="wxTextCtrl" expanded="1"> | ||
| 7504 | <property name="bg"></property> | ||
| 7505 | <property name="context_help"></property> | ||
| 7506 | <property name="enabled">1</property> | ||
| 7507 | <property name="fg"></property> | ||
| 7508 | <property name="font"></property> | ||
| 7509 | <property name="hidden">0</property> | ||
| 7510 | <property name="id">wxID_ANY</property> | ||
| 7511 | <property name="maximum_size"></property> | ||
| 7512 | <property name="maxlength">0</property> | ||
| 7513 | <property name="minimum_size">150,-1</property> | ||
| 7514 | <property name="name">m_textCtrlLabel11</property> | ||
| 7515 | <property name="permission">protected</property> | ||
| 7516 | <property name="pos"></property> | ||
| 7517 | <property name="size"></property> | ||
| 7518 | <property name="style"></property> | ||
| 7519 | <property name="subclass"></property> | ||
| 7520 | <property name="tooltip"></property> | ||
| 7521 | <property name="value"></property> | ||
| 7522 | <property name="window_extra_style"></property> | ||
| 7523 | <property name="window_name"></property> | ||
| 7524 | <property name="window_style"></property> | ||
| 7525 | <event name="OnChar"></event> | ||
| 7526 | <event name="OnEnterWindow"></event> | ||
| 7527 | <event name="OnEraseBackground"></event> | ||
| 7528 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 7529 | <event name="OnKeyUp"></event> | ||
| 7530 | <event name="OnKillFocus"></event> | ||
| 7531 | <event name="OnLeaveWindow"></event> | ||
| 7532 | <event name="OnLeftDClick"></event> | ||
| 7533 | <event name="OnLeftDown"></event> | ||
| 7534 | <event name="OnLeftUp"></event> | ||
| 7535 | <event name="OnMiddleDClick"></event> | ||
| 7536 | <event name="OnMiddleDown"></event> | ||
| 7537 | <event name="OnMiddleUp"></event> | ||
| 7538 | <event name="OnMotion"></event> | ||
| 7539 | <event name="OnMouseEvents"></event> | ||
| 7540 | <event name="OnMouseWheel"></event> | ||
| 7541 | <event name="OnPaint"></event> | ||
| 7542 | <event name="OnRightDClick"></event> | ||
| 7543 | <event name="OnRightDown"></event> | ||
| 7544 | <event name="OnRightUp"></event> | ||
| 7545 | <event name="OnSetFocus"></event> | ||
| 7546 | <event name="OnSize"></event> | ||
| 7547 | <event name="OnText"></event> | ||
| 7548 | <event name="OnTextEnter"></event> | ||
| 7549 | <event name="OnTextMaxLen"></event> | ||
| 7550 | <event name="OnTextURL"></event> | ||
| 7551 | <event name="OnUpdateUI"></event> | ||
| 7552 | </object> | ||
| 7553 | </object> | ||
| 7554 | <object class="sizeritem" expanded="1"> | ||
| 7555 | <property name="border">5</property> | ||
| 7556 | <property name="flag">wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL</property> | ||
| 7557 | <property name="proportion">0</property> | ||
| 7558 | <object class="wxTextCtrl" expanded="1"> | ||
| 7559 | <property name="bg"></property> | ||
| 7560 | <property name="context_help"></property> | ||
| 7561 | <property name="enabled">1</property> | ||
| 7562 | <property name="fg"></property> | ||
| 7563 | <property name="font"></property> | ||
| 7564 | <property name="hidden">0</property> | ||
| 7565 | <property name="id">wxID_ANY</property> | ||
| 7566 | <property name="maximum_size">-1,-1</property> | ||
| 7567 | <property name="maxlength">0</property> | ||
| 7568 | <property name="minimum_size">-1,-1</property> | ||
| 7569 | <property name="name">m_textCtrlField11</property> | ||
| 7570 | <property name="permission">protected</property> | ||
| 7571 | <property name="pos"></property> | ||
| 7572 | <property name="size">-1,-1</property> | ||
| 7573 | <property name="style"></property> | ||
| 7574 | <property name="subclass"></property> | ||
| 7575 | <property name="tooltip"></property> | ||
| 7576 | <property name="value"></property> | ||
| 7577 | <property name="window_extra_style"></property> | ||
| 7578 | <property name="window_name"></property> | ||
| 7579 | <property name="window_style"></property> | ||
| 7580 | <event name="OnChar"></event> | ||
| 7581 | <event name="OnEnterWindow"></event> | ||
| 7582 | <event name="OnEraseBackground"></event> | ||
| 7583 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 7584 | <event name="OnKeyUp"></event> | ||
| 7585 | <event name="OnKillFocus"></event> | ||
| 7586 | <event name="OnLeaveWindow"></event> | ||
| 7587 | <event name="OnLeftDClick"></event> | ||
| 7588 | <event name="OnLeftDown"></event> | ||
| 7589 | <event name="OnLeftUp"></event> | ||
| 7590 | <event name="OnMiddleDClick"></event> | ||
| 7591 | <event name="OnMiddleDown"></event> | ||
| 7592 | <event name="OnMiddleUp"></event> | ||
| 7593 | <event name="OnMotion"></event> | ||
| 7594 | <event name="OnMouseEvents"></event> | ||
| 7595 | <event name="OnMouseWheel"></event> | ||
| 7596 | <event name="OnPaint"></event> | ||
| 7597 | <event name="OnRightDClick"></event> | ||
| 7598 | <event name="OnRightDown"></event> | ||
| 7599 | <event name="OnRightUp"></event> | ||
| 7600 | <event name="OnSetFocus"></event> | ||
| 7601 | <event name="OnSize"></event> | ||
| 7602 | <event name="OnText"></event> | ||
| 7603 | <event name="OnTextEnter"></event> | ||
| 7604 | <event name="OnTextMaxLen"></event> | ||
| 7605 | <event name="OnTextURL"></event> | ||
| 7606 | <event name="OnUpdateUI"></event> | ||
| 7607 | </object> | ||
| 7608 | </object> | ||
| 7609 | <object class="sizeritem" expanded="1"> | ||
| 7610 | <property name="border">5</property> | ||
| 7611 | <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property> | ||
| 7612 | <property name="proportion">0</property> | ||
| 7613 | <object class="wxButton" expanded="1"> | ||
| 7614 | <property name="bg"></property> | ||
| 7615 | <property name="context_help"></property> | ||
| 7616 | <property name="default">0</property> | ||
| 7617 | <property name="enabled">1</property> | ||
| 7618 | <property name="fg"></property> | ||
| 7619 | <property name="font"></property> | ||
| 7620 | <property name="hidden">0</property> | ||
| 7621 | <property name="id">wxID_DEL11</property> | ||
| 7622 | <property name="label">Delete</property> | ||
| 7623 | <property name="maximum_size"></property> | ||
| 7624 | <property name="minimum_size">-1,-1</property> | ||
| 7625 | <property name="name">m_buttonDel11</property> | ||
| 7626 | <property name="permission">protected</property> | ||
| 7627 | <property name="pos"></property> | ||
| 7628 | <property name="size">60,20</property> | ||
| 7629 | <property name="style"></property> | ||
| 7630 | <property name="subclass"></property> | ||
| 7631 | <property name="tooltip"></property> | ||
| 7632 | <property name="window_extra_style"></property> | ||
| 7633 | <property name="window_name"></property> | ||
| 7634 | <property name="window_style"></property> | ||
| 7635 | <event name="OnButtonClick">OnButtonDel11</event> | ||
| 7636 | <event name="OnChar"></event> | ||
| 7637 | <event name="OnEnterWindow"></event> | ||
| 7638 | <event name="OnEraseBackground"></event> | ||
| 7639 | <event name="OnKeyDown"></event> | ||
| 7640 | <event name="OnKeyUp"></event> | ||
| 7641 | <event name="OnKillFocus"></event> | ||
| 7642 | <event name="OnLeaveWindow"></event> | ||
| 7643 | <event name="OnLeftDClick"></event> | ||
| 7644 | <event name="OnLeftDown"></event> | ||
| 7645 | <event name="OnLeftUp"></event> | ||
| 7646 | <event name="OnMiddleDClick"></event> | ||
| 7647 | <event name="OnMiddleDown"></event> | ||
| 7648 | <event name="OnMiddleUp"></event> | ||
| 7649 | <event name="OnMotion"></event> | ||
| 7650 | <event name="OnMouseEvents"></event> | ||
| 7651 | <event name="OnMouseWheel"></event> | ||
| 7652 | <event name="OnPaint"></event> | ||
| 7653 | <event name="OnRightDClick"></event> | ||
| 7654 | <event name="OnRightDown"></event> | ||
| 7655 | <event name="OnRightUp"></event> | ||
| 7656 | <event name="OnSetFocus"></event> | ||
| 7657 | <event name="OnSize"></event> | ||
| 7658 | <event name="OnUpdateUI"></event> | ||
| 7659 | </object> | ||
| 7660 | </object> | ||
| 7661 | <object class="sizeritem" expanded="1"> | ||
| 7662 | <property name="border">5</property> | ||
| 7663 | <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property> | ||
| 7664 | <property name="proportion">0</property> | ||
| 7665 | <object class="wxTextCtrl" expanded="1"> | ||
| 7666 | <property name="bg"></property> | ||
| 7667 | <property name="context_help"></property> | ||
| 7668 | <property name="enabled">1</property> | ||
| 7669 | <property name="fg"></property> | ||
| 7670 | <property name="font"></property> | ||
| 7671 | <property name="hidden">0</property> | ||
| 7672 | <property name="id">wxID_ANY</property> | ||
| 7673 | <property name="maximum_size"></property> | ||
| 7674 | <property name="maxlength">0</property> | ||
| 7675 | <property name="minimum_size">150,-1</property> | ||
| 7676 | <property name="name">m_textCtrlLabel12</property> | ||
| 7677 | <property name="permission">protected</property> | ||
| 7678 | <property name="pos"></property> | ||
| 7679 | <property name="size"></property> | ||
| 7680 | <property name="style"></property> | ||
| 7681 | <property name="subclass"></property> | ||
| 7682 | <property name="tooltip"></property> | ||
| 7683 | <property name="value"></property> | ||
| 7684 | <property name="window_extra_style"></property> | ||
| 7685 | <property name="window_name"></property> | ||
| 7686 | <property name="window_style"></property> | ||
| 7687 | <event name="OnChar"></event> | ||
| 7688 | <event name="OnEnterWindow"></event> | ||
| 7689 | <event name="OnEraseBackground"></event> | ||
| 7690 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 7691 | <event name="OnKeyUp"></event> | ||
| 7692 | <event name="OnKillFocus"></event> | ||
| 7693 | <event name="OnLeaveWindow"></event> | ||
| 7694 | <event name="OnLeftDClick"></event> | ||
| 7695 | <event name="OnLeftDown"></event> | ||
| 7696 | <event name="OnLeftUp"></event> | ||
| 7697 | <event name="OnMiddleDClick"></event> | ||
| 7698 | <event name="OnMiddleDown"></event> | ||
| 7699 | <event name="OnMiddleUp"></event> | ||
| 7700 | <event name="OnMotion"></event> | ||
| 7701 | <event name="OnMouseEvents"></event> | ||
| 7702 | <event name="OnMouseWheel"></event> | ||
| 7703 | <event name="OnPaint"></event> | ||
| 7704 | <event name="OnRightDClick"></event> | ||
| 7705 | <event name="OnRightDown"></event> | ||
| 7706 | <event name="OnRightUp"></event> | ||
| 7707 | <event name="OnSetFocus"></event> | ||
| 7708 | <event name="OnSize"></event> | ||
| 7709 | <event name="OnText"></event> | ||
| 7710 | <event name="OnTextEnter"></event> | ||
| 7711 | <event name="OnTextMaxLen"></event> | ||
| 7712 | <event name="OnTextURL"></event> | ||
| 7713 | <event name="OnUpdateUI"></event> | ||
| 7714 | </object> | ||
| 7715 | </object> | ||
| 7716 | <object class="sizeritem" expanded="1"> | ||
| 7717 | <property name="border">5</property> | ||
| 7718 | <property name="flag">wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL</property> | ||
| 7719 | <property name="proportion">0</property> | ||
| 7720 | <object class="wxTextCtrl" expanded="1"> | ||
| 7721 | <property name="bg"></property> | ||
| 7722 | <property name="context_help"></property> | ||
| 7723 | <property name="enabled">1</property> | ||
| 7724 | <property name="fg"></property> | ||
| 7725 | <property name="font"></property> | ||
| 7726 | <property name="hidden">0</property> | ||
| 7727 | <property name="id">wxID_ANY</property> | ||
| 7728 | <property name="maximum_size">-1,-1</property> | ||
| 7729 | <property name="maxlength">0</property> | ||
| 7730 | <property name="minimum_size">-1,-1</property> | ||
| 7731 | <property name="name">m_textCtrlField12</property> | ||
| 7732 | <property name="permission">protected</property> | ||
| 7733 | <property name="pos"></property> | ||
| 7734 | <property name="size">-1,-1</property> | ||
| 7735 | <property name="style"></property> | ||
| 7736 | <property name="subclass"></property> | ||
| 7737 | <property name="tooltip"></property> | ||
| 7738 | <property name="value"></property> | ||
| 7739 | <property name="window_extra_style"></property> | ||
| 7740 | <property name="window_name"></property> | ||
| 7741 | <property name="window_style"></property> | ||
| 7742 | <event name="OnChar"></event> | ||
| 7743 | <event name="OnEnterWindow"></event> | ||
| 7744 | <event name="OnEraseBackground"></event> | ||
| 7745 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 7746 | <event name="OnKeyUp"></event> | ||
| 7747 | <event name="OnKillFocus"></event> | ||
| 7748 | <event name="OnLeaveWindow"></event> | ||
| 7749 | <event name="OnLeftDClick"></event> | ||
| 7750 | <event name="OnLeftDown"></event> | ||
| 7751 | <event name="OnLeftUp"></event> | ||
| 7752 | <event name="OnMiddleDClick"></event> | ||
| 7753 | <event name="OnMiddleDown"></event> | ||
| 7754 | <event name="OnMiddleUp"></event> | ||
| 7755 | <event name="OnMotion"></event> | ||
| 7756 | <event name="OnMouseEvents"></event> | ||
| 7757 | <event name="OnMouseWheel"></event> | ||
| 7758 | <event name="OnPaint"></event> | ||
| 7759 | <event name="OnRightDClick"></event> | ||
| 7760 | <event name="OnRightDown"></event> | ||
| 7761 | <event name="OnRightUp"></event> | ||
| 7762 | <event name="OnSetFocus"></event> | ||
| 7763 | <event name="OnSize"></event> | ||
| 7764 | <event name="OnText"></event> | ||
| 7765 | <event name="OnTextEnter"></event> | ||
| 7766 | <event name="OnTextMaxLen"></event> | ||
| 7767 | <event name="OnTextURL"></event> | ||
| 7768 | <event name="OnUpdateUI"></event> | ||
| 7769 | </object> | ||
| 7770 | </object> | ||
| 7771 | <object class="sizeritem" expanded="1"> | ||
| 7772 | <property name="border">5</property> | ||
| 7773 | <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property> | ||
| 7774 | <property name="proportion">0</property> | ||
| 7775 | <object class="wxButton" expanded="1"> | ||
| 7776 | <property name="bg"></property> | ||
| 7777 | <property name="context_help"></property> | ||
| 7778 | <property name="default">0</property> | ||
| 7779 | <property name="enabled">1</property> | ||
| 7780 | <property name="fg"></property> | ||
| 7781 | <property name="font"></property> | ||
| 7782 | <property name="hidden">0</property> | ||
| 7783 | <property name="id">wxID_DEL12</property> | ||
| 7784 | <property name="label">Delete</property> | ||
| 7785 | <property name="maximum_size"></property> | ||
| 7786 | <property name="minimum_size">-1,-1</property> | ||
| 7787 | <property name="name">m_buttonDel12</property> | ||
| 7788 | <property name="permission">protected</property> | ||
| 7789 | <property name="pos"></property> | ||
| 7790 | <property name="size">60,20</property> | ||
| 7791 | <property name="style"></property> | ||
| 7792 | <property name="subclass"></property> | ||
| 7793 | <property name="tooltip"></property> | ||
| 7794 | <property name="window_extra_style"></property> | ||
| 7795 | <property name="window_name"></property> | ||
| 7796 | <property name="window_style"></property> | ||
| 7797 | <event name="OnButtonClick">OnButtonDel12</event> | ||
| 7798 | <event name="OnChar"></event> | ||
| 7799 | <event name="OnEnterWindow"></event> | ||
| 7800 | <event name="OnEraseBackground"></event> | ||
| 7801 | <event name="OnKeyDown"></event> | ||
| 7802 | <event name="OnKeyUp"></event> | ||
| 7803 | <event name="OnKillFocus"></event> | ||
| 7804 | <event name="OnLeaveWindow"></event> | ||
| 7805 | <event name="OnLeftDClick"></event> | ||
| 7806 | <event name="OnLeftDown"></event> | ||
| 7807 | <event name="OnLeftUp"></event> | ||
| 7808 | <event name="OnMiddleDClick"></event> | ||
| 7809 | <event name="OnMiddleDown"></event> | ||
| 7810 | <event name="OnMiddleUp"></event> | ||
| 7811 | <event name="OnMotion"></event> | ||
| 7812 | <event name="OnMouseEvents"></event> | ||
| 7813 | <event name="OnMouseWheel"></event> | ||
| 7814 | <event name="OnPaint"></event> | ||
| 7815 | <event name="OnRightDClick"></event> | ||
| 7816 | <event name="OnRightDown"></event> | ||
| 7817 | <event name="OnRightUp"></event> | ||
| 7818 | <event name="OnSetFocus"></event> | ||
| 7819 | <event name="OnSize"></event> | ||
| 7820 | <event name="OnUpdateUI"></event> | ||
| 7821 | </object> | ||
| 7822 | </object> | ||
| 7823 | <object class="sizeritem" expanded="1"> | ||
| 7824 | <property name="border">5</property> | ||
| 7825 | <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property> | ||
| 7826 | <property name="proportion">0</property> | ||
| 7827 | <object class="wxTextCtrl" expanded="1"> | ||
| 7828 | <property name="bg"></property> | ||
| 7829 | <property name="context_help"></property> | ||
| 7830 | <property name="enabled">1</property> | ||
| 7831 | <property name="fg"></property> | ||
| 7832 | <property name="font"></property> | ||
| 7833 | <property name="hidden">0</property> | ||
| 7834 | <property name="id">wxID_ANY</property> | ||
| 7835 | <property name="maximum_size"></property> | ||
| 7836 | <property name="maxlength">0</property> | ||
| 7837 | <property name="minimum_size">150,-1</property> | ||
| 7838 | <property name="name">m_textCtrlLabel13</property> | ||
| 7839 | <property name="permission">protected</property> | ||
| 7840 | <property name="pos"></property> | ||
| 7841 | <property name="size"></property> | ||
| 7842 | <property name="style"></property> | ||
| 7843 | <property name="subclass"></property> | ||
| 7844 | <property name="tooltip"></property> | ||
| 7845 | <property name="value"></property> | ||
| 7846 | <property name="window_extra_style"></property> | ||
| 7847 | <property name="window_name"></property> | ||
| 7848 | <property name="window_style"></property> | ||
| 7849 | <event name="OnChar"></event> | ||
| 7850 | <event name="OnEnterWindow"></event> | ||
| 7851 | <event name="OnEraseBackground"></event> | ||
| 7852 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 7853 | <event name="OnKeyUp"></event> | ||
| 7854 | <event name="OnKillFocus"></event> | ||
| 7855 | <event name="OnLeaveWindow"></event> | ||
| 7856 | <event name="OnLeftDClick"></event> | ||
| 7857 | <event name="OnLeftDown"></event> | ||
| 7858 | <event name="OnLeftUp"></event> | ||
| 7859 | <event name="OnMiddleDClick"></event> | ||
| 7860 | <event name="OnMiddleDown"></event> | ||
| 7861 | <event name="OnMiddleUp"></event> | ||
| 7862 | <event name="OnMotion"></event> | ||
| 7863 | <event name="OnMouseEvents"></event> | ||
| 7864 | <event name="OnMouseWheel"></event> | ||
| 7865 | <event name="OnPaint"></event> | ||
| 7866 | <event name="OnRightDClick"></event> | ||
| 7867 | <event name="OnRightDown"></event> | ||
| 7868 | <event name="OnRightUp"></event> | ||
| 7869 | <event name="OnSetFocus"></event> | ||
| 7870 | <event name="OnSize"></event> | ||
| 7871 | <event name="OnText"></event> | ||
| 7872 | <event name="OnTextEnter"></event> | ||
| 7873 | <event name="OnTextMaxLen"></event> | ||
| 7874 | <event name="OnTextURL"></event> | ||
| 7875 | <event name="OnUpdateUI"></event> | ||
| 7876 | </object> | ||
| 7877 | </object> | ||
| 7878 | <object class="sizeritem" expanded="1"> | ||
| 7879 | <property name="border">5</property> | ||
| 7880 | <property name="flag">wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL</property> | ||
| 7881 | <property name="proportion">0</property> | ||
| 7882 | <object class="wxTextCtrl" expanded="1"> | ||
| 7883 | <property name="bg"></property> | ||
| 7884 | <property name="context_help"></property> | ||
| 7885 | <property name="enabled">1</property> | ||
| 7886 | <property name="fg"></property> | ||
| 7887 | <property name="font"></property> | ||
| 7888 | <property name="hidden">0</property> | ||
| 7889 | <property name="id">wxID_ANY</property> | ||
| 7890 | <property name="maximum_size">-1,-1</property> | ||
| 7891 | <property name="maxlength">0</property> | ||
| 7892 | <property name="minimum_size">-1,-1</property> | ||
| 7893 | <property name="name">m_textCtrlField13</property> | ||
| 7894 | <property name="permission">protected</property> | ||
| 7895 | <property name="pos"></property> | ||
| 7896 | <property name="size">-1,-1</property> | ||
| 7897 | <property name="style"></property> | ||
| 7898 | <property name="subclass"></property> | ||
| 7899 | <property name="tooltip"></property> | ||
| 7900 | <property name="value"></property> | ||
| 7901 | <property name="window_extra_style"></property> | ||
| 7902 | <property name="window_name"></property> | ||
| 7903 | <property name="window_style"></property> | ||
| 7904 | <event name="OnChar"></event> | ||
| 7905 | <event name="OnEnterWindow"></event> | ||
| 7906 | <event name="OnEraseBackground"></event> | ||
| 7907 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 7908 | <event name="OnKeyUp"></event> | ||
| 7909 | <event name="OnKillFocus"></event> | ||
| 7910 | <event name="OnLeaveWindow"></event> | ||
| 7911 | <event name="OnLeftDClick"></event> | ||
| 7912 | <event name="OnLeftDown"></event> | ||
| 7913 | <event name="OnLeftUp"></event> | ||
| 7914 | <event name="OnMiddleDClick"></event> | ||
| 7915 | <event name="OnMiddleDown"></event> | ||
| 7916 | <event name="OnMiddleUp"></event> | ||
| 7917 | <event name="OnMotion"></event> | ||
| 7918 | <event name="OnMouseEvents"></event> | ||
| 7919 | <event name="OnMouseWheel"></event> | ||
| 7920 | <event name="OnPaint"></event> | ||
| 7921 | <event name="OnRightDClick"></event> | ||
| 7922 | <event name="OnRightDown"></event> | ||
| 7923 | <event name="OnRightUp"></event> | ||
| 7924 | <event name="OnSetFocus"></event> | ||
| 7925 | <event name="OnSize"></event> | ||
| 7926 | <event name="OnText"></event> | ||
| 7927 | <event name="OnTextEnter"></event> | ||
| 7928 | <event name="OnTextMaxLen"></event> | ||
| 7929 | <event name="OnTextURL"></event> | ||
| 7930 | <event name="OnUpdateUI"></event> | ||
| 7931 | </object> | ||
| 7932 | </object> | ||
| 7933 | <object class="sizeritem" expanded="1"> | ||
| 7934 | <property name="border">5</property> | ||
| 7935 | <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property> | ||
| 7936 | <property name="proportion">0</property> | ||
| 7937 | <object class="wxButton" expanded="1"> | ||
| 7938 | <property name="bg"></property> | ||
| 7939 | <property name="context_help"></property> | ||
| 7940 | <property name="default">0</property> | ||
| 7941 | <property name="enabled">1</property> | ||
| 7942 | <property name="fg"></property> | ||
| 7943 | <property name="font"></property> | ||
| 7944 | <property name="hidden">0</property> | ||
| 7945 | <property name="id">wxID_DEL13</property> | ||
| 7946 | <property name="label">Delete</property> | ||
| 7947 | <property name="maximum_size"></property> | ||
| 7948 | <property name="minimum_size">-1,-1</property> | ||
| 7949 | <property name="name">m_buttonDel13</property> | ||
| 7950 | <property name="permission">protected</property> | ||
| 7951 | <property name="pos"></property> | ||
| 7952 | <property name="size">60,20</property> | ||
| 7953 | <property name="style"></property> | ||
| 7954 | <property name="subclass"></property> | ||
| 7955 | <property name="tooltip"></property> | ||
| 7956 | <property name="window_extra_style"></property> | ||
| 7957 | <property name="window_name"></property> | ||
| 7958 | <property name="window_style"></property> | ||
| 7959 | <event name="OnButtonClick">OnButtonDel13</event> | ||
| 7960 | <event name="OnChar"></event> | ||
| 7961 | <event name="OnEnterWindow"></event> | ||
| 7962 | <event name="OnEraseBackground"></event> | ||
| 7963 | <event name="OnKeyDown"></event> | ||
| 7964 | <event name="OnKeyUp"></event> | ||
| 7965 | <event name="OnKillFocus"></event> | ||
| 7966 | <event name="OnLeaveWindow"></event> | ||
| 7967 | <event name="OnLeftDClick"></event> | ||
| 7968 | <event name="OnLeftDown"></event> | ||
| 7969 | <event name="OnLeftUp"></event> | ||
| 7970 | <event name="OnMiddleDClick"></event> | ||
| 7971 | <event name="OnMiddleDown"></event> | ||
| 7972 | <event name="OnMiddleUp"></event> | ||
| 7973 | <event name="OnMotion"></event> | ||
| 7974 | <event name="OnMouseEvents"></event> | ||
| 7975 | <event name="OnMouseWheel"></event> | ||
| 7976 | <event name="OnPaint"></event> | ||
| 7977 | <event name="OnRightDClick"></event> | ||
| 7978 | <event name="OnRightDown"></event> | ||
| 7979 | <event name="OnRightUp"></event> | ||
| 7980 | <event name="OnSetFocus"></event> | ||
| 7981 | <event name="OnSize"></event> | ||
| 7982 | <event name="OnUpdateUI"></event> | ||
| 7983 | </object> | ||
| 7984 | </object> | ||
| 7985 | <object class="sizeritem" expanded="1"> | ||
| 7986 | <property name="border">5</property> | ||
| 7987 | <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property> | ||
| 7988 | <property name="proportion">0</property> | ||
| 7989 | <object class="wxTextCtrl" expanded="1"> | ||
| 7990 | <property name="bg"></property> | ||
| 7991 | <property name="context_help"></property> | ||
| 7992 | <property name="enabled">1</property> | ||
| 7993 | <property name="fg"></property> | ||
| 7994 | <property name="font"></property> | ||
| 7995 | <property name="hidden">0</property> | ||
| 7996 | <property name="id">wxID_ANY</property> | ||
| 7997 | <property name="maximum_size"></property> | ||
| 7998 | <property name="maxlength">0</property> | ||
| 7999 | <property name="minimum_size">150,-1</property> | ||
| 8000 | <property name="name">m_textCtrlLabel14</property> | ||
| 8001 | <property name="permission">protected</property> | ||
| 8002 | <property name="pos"></property> | ||
| 8003 | <property name="size"></property> | ||
| 8004 | <property name="style"></property> | ||
| 8005 | <property name="subclass"></property> | ||
| 8006 | <property name="tooltip"></property> | ||
| 8007 | <property name="value"></property> | ||
| 8008 | <property name="window_extra_style"></property> | ||
| 8009 | <property name="window_name"></property> | ||
| 8010 | <property name="window_style"></property> | ||
| 8011 | <event name="OnChar"></event> | ||
| 8012 | <event name="OnEnterWindow"></event> | ||
| 8013 | <event name="OnEraseBackground"></event> | ||
| 8014 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 8015 | <event name="OnKeyUp"></event> | ||
| 8016 | <event name="OnKillFocus"></event> | ||
| 8017 | <event name="OnLeaveWindow"></event> | ||
| 8018 | <event name="OnLeftDClick"></event> | ||
| 8019 | <event name="OnLeftDown"></event> | ||
| 8020 | <event name="OnLeftUp"></event> | ||
| 8021 | <event name="OnMiddleDClick"></event> | ||
| 8022 | <event name="OnMiddleDown"></event> | ||
| 8023 | <event name="OnMiddleUp"></event> | ||
| 8024 | <event name="OnMotion"></event> | ||
| 8025 | <event name="OnMouseEvents"></event> | ||
| 8026 | <event name="OnMouseWheel"></event> | ||
| 8027 | <event name="OnPaint"></event> | ||
| 8028 | <event name="OnRightDClick"></event> | ||
| 8029 | <event name="OnRightDown"></event> | ||
| 8030 | <event name="OnRightUp"></event> | ||
| 8031 | <event name="OnSetFocus"></event> | ||
| 8032 | <event name="OnSize"></event> | ||
| 8033 | <event name="OnText"></event> | ||
| 8034 | <event name="OnTextEnter"></event> | ||
| 8035 | <event name="OnTextMaxLen"></event> | ||
| 8036 | <event name="OnTextURL"></event> | ||
| 8037 | <event name="OnUpdateUI"></event> | ||
| 8038 | </object> | ||
| 8039 | </object> | ||
| 8040 | <object class="sizeritem" expanded="1"> | ||
| 8041 | <property name="border">5</property> | ||
| 8042 | <property name="flag">wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL</property> | ||
| 8043 | <property name="proportion">0</property> | ||
| 8044 | <object class="wxTextCtrl" expanded="1"> | ||
| 8045 | <property name="bg"></property> | ||
| 8046 | <property name="context_help"></property> | ||
| 8047 | <property name="enabled">1</property> | ||
| 8048 | <property name="fg"></property> | ||
| 8049 | <property name="font"></property> | ||
| 8050 | <property name="hidden">0</property> | ||
| 8051 | <property name="id">wxID_ANY</property> | ||
| 8052 | <property name="maximum_size">-1,-1</property> | ||
| 8053 | <property name="maxlength">0</property> | ||
| 8054 | <property name="minimum_size">-1,-1</property> | ||
| 8055 | <property name="name">m_textCtrlField14</property> | ||
| 8056 | <property name="permission">protected</property> | ||
| 8057 | <property name="pos"></property> | ||
| 8058 | <property name="size">-1,-1</property> | ||
| 8059 | <property name="style"></property> | ||
| 8060 | <property name="subclass"></property> | ||
| 8061 | <property name="tooltip"></property> | ||
| 8062 | <property name="value"></property> | ||
| 8063 | <property name="window_extra_style"></property> | ||
| 8064 | <property name="window_name"></property> | ||
| 8065 | <property name="window_style"></property> | ||
| 8066 | <event name="OnChar"></event> | ||
| 8067 | <event name="OnEnterWindow"></event> | ||
| 8068 | <event name="OnEraseBackground"></event> | ||
| 8069 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 8070 | <event name="OnKeyUp"></event> | ||
| 8071 | <event name="OnKillFocus"></event> | ||
| 8072 | <event name="OnLeaveWindow"></event> | ||
| 8073 | <event name="OnLeftDClick"></event> | ||
| 8074 | <event name="OnLeftDown"></event> | ||
| 8075 | <event name="OnLeftUp"></event> | ||
| 8076 | <event name="OnMiddleDClick"></event> | ||
| 8077 | <event name="OnMiddleDown"></event> | ||
| 8078 | <event name="OnMiddleUp"></event> | ||
| 8079 | <event name="OnMotion"></event> | ||
| 8080 | <event name="OnMouseEvents"></event> | ||
| 8081 | <event name="OnMouseWheel"></event> | ||
| 8082 | <event name="OnPaint"></event> | ||
| 8083 | <event name="OnRightDClick"></event> | ||
| 8084 | <event name="OnRightDown"></event> | ||
| 8085 | <event name="OnRightUp"></event> | ||
| 8086 | <event name="OnSetFocus"></event> | ||
| 8087 | <event name="OnSize"></event> | ||
| 8088 | <event name="OnText"></event> | ||
| 8089 | <event name="OnTextEnter"></event> | ||
| 8090 | <event name="OnTextMaxLen"></event> | ||
| 8091 | <event name="OnTextURL"></event> | ||
| 8092 | <event name="OnUpdateUI"></event> | ||
| 8093 | </object> | ||
| 8094 | </object> | ||
| 8095 | <object class="sizeritem" expanded="1"> | ||
| 8096 | <property name="border">5</property> | ||
| 8097 | <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property> | ||
| 8098 | <property name="proportion">0</property> | ||
| 8099 | <object class="wxButton" expanded="1"> | ||
| 8100 | <property name="bg"></property> | ||
| 8101 | <property name="context_help"></property> | ||
| 8102 | <property name="default">0</property> | ||
| 8103 | <property name="enabled">1</property> | ||
| 8104 | <property name="fg"></property> | ||
| 8105 | <property name="font"></property> | ||
| 8106 | <property name="hidden">0</property> | ||
| 8107 | <property name="id">wxID_DEL14</property> | ||
| 8108 | <property name="label">Delete</property> | ||
| 8109 | <property name="maximum_size"></property> | ||
| 8110 | <property name="minimum_size">-1,-1</property> | ||
| 8111 | <property name="name">m_buttonDel14</property> | ||
| 8112 | <property name="permission">protected</property> | ||
| 8113 | <property name="pos"></property> | ||
| 8114 | <property name="size">60,20</property> | ||
| 8115 | <property name="style"></property> | ||
| 8116 | <property name="subclass"></property> | ||
| 8117 | <property name="tooltip"></property> | ||
| 8118 | <property name="window_extra_style"></property> | ||
| 8119 | <property name="window_name"></property> | ||
| 8120 | <property name="window_style"></property> | ||
| 8121 | <event name="OnButtonClick">OnButtonDel14</event> | ||
| 8122 | <event name="OnChar"></event> | ||
| 8123 | <event name="OnEnterWindow"></event> | ||
| 8124 | <event name="OnEraseBackground"></event> | ||
| 8125 | <event name="OnKeyDown"></event> | ||
| 8126 | <event name="OnKeyUp"></event> | ||
| 8127 | <event name="OnKillFocus"></event> | ||
| 8128 | <event name="OnLeaveWindow"></event> | ||
| 8129 | <event name="OnLeftDClick"></event> | ||
| 8130 | <event name="OnLeftDown"></event> | ||
| 8131 | <event name="OnLeftUp"></event> | ||
| 8132 | <event name="OnMiddleDClick"></event> | ||
| 8133 | <event name="OnMiddleDown"></event> | ||
| 8134 | <event name="OnMiddleUp"></event> | ||
| 8135 | <event name="OnMotion"></event> | ||
| 8136 | <event name="OnMouseEvents"></event> | ||
| 8137 | <event name="OnMouseWheel"></event> | ||
| 8138 | <event name="OnPaint"></event> | ||
| 8139 | <event name="OnRightDClick"></event> | ||
| 8140 | <event name="OnRightDown"></event> | ||
| 8141 | <event name="OnRightUp"></event> | ||
| 8142 | <event name="OnSetFocus"></event> | ||
| 8143 | <event name="OnSize"></event> | ||
| 8144 | <event name="OnUpdateUI"></event> | ||
| 8145 | </object> | ||
| 8146 | </object> | ||
| 8147 | <object class="sizeritem" expanded="1"> | ||
| 8148 | <property name="border">5</property> | ||
| 8149 | <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property> | ||
| 8150 | <property name="proportion">0</property> | ||
| 8151 | <object class="wxTextCtrl" expanded="1"> | ||
| 8152 | <property name="bg"></property> | ||
| 8153 | <property name="context_help"></property> | ||
| 8154 | <property name="enabled">1</property> | ||
| 8155 | <property name="fg"></property> | ||
| 8156 | <property name="font"></property> | ||
| 8157 | <property name="hidden">0</property> | ||
| 8158 | <property name="id">wxID_ANY</property> | ||
| 8159 | <property name="maximum_size"></property> | ||
| 8160 | <property name="maxlength">0</property> | ||
| 8161 | <property name="minimum_size">150,-1</property> | ||
| 8162 | <property name="name">m_textCtrlLabel15</property> | ||
| 8163 | <property name="permission">protected</property> | ||
| 8164 | <property name="pos"></property> | ||
| 8165 | <property name="size"></property> | ||
| 8166 | <property name="style"></property> | ||
| 8167 | <property name="subclass"></property> | ||
| 8168 | <property name="tooltip"></property> | ||
| 8169 | <property name="value"></property> | ||
| 8170 | <property name="window_extra_style"></property> | ||
| 8171 | <property name="window_name"></property> | ||
| 8172 | <property name="window_style"></property> | ||
| 8173 | <event name="OnChar"></event> | ||
| 8174 | <event name="OnEnterWindow"></event> | ||
| 8175 | <event name="OnEraseBackground"></event> | ||
| 8176 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 8177 | <event name="OnKeyUp"></event> | ||
| 8178 | <event name="OnKillFocus"></event> | ||
| 8179 | <event name="OnLeaveWindow"></event> | ||
| 8180 | <event name="OnLeftDClick"></event> | ||
| 8181 | <event name="OnLeftDown"></event> | ||
| 8182 | <event name="OnLeftUp"></event> | ||
| 8183 | <event name="OnMiddleDClick"></event> | ||
| 8184 | <event name="OnMiddleDown"></event> | ||
| 8185 | <event name="OnMiddleUp"></event> | ||
| 8186 | <event name="OnMotion"></event> | ||
| 8187 | <event name="OnMouseEvents"></event> | ||
| 8188 | <event name="OnMouseWheel"></event> | ||
| 8189 | <event name="OnPaint"></event> | ||
| 8190 | <event name="OnRightDClick"></event> | ||
| 8191 | <event name="OnRightDown"></event> | ||
| 8192 | <event name="OnRightUp"></event> | ||
| 8193 | <event name="OnSetFocus"></event> | ||
| 8194 | <event name="OnSize"></event> | ||
| 8195 | <event name="OnText"></event> | ||
| 8196 | <event name="OnTextEnter"></event> | ||
| 8197 | <event name="OnTextMaxLen"></event> | ||
| 8198 | <event name="OnTextURL"></event> | ||
| 8199 | <event name="OnUpdateUI"></event> | ||
| 8200 | </object> | ||
| 8201 | </object> | ||
| 8202 | <object class="sizeritem" expanded="1"> | ||
| 8203 | <property name="border">5</property> | ||
| 8204 | <property name="flag">wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL</property> | ||
| 8205 | <property name="proportion">0</property> | ||
| 8206 | <object class="wxTextCtrl" expanded="1"> | ||
| 8207 | <property name="bg"></property> | ||
| 8208 | <property name="context_help"></property> | ||
| 8209 | <property name="enabled">1</property> | ||
| 8210 | <property name="fg"></property> | ||
| 8211 | <property name="font"></property> | ||
| 8212 | <property name="hidden">0</property> | ||
| 8213 | <property name="id">wxID_ANY</property> | ||
| 8214 | <property name="maximum_size">-1,-1</property> | ||
| 8215 | <property name="maxlength">0</property> | ||
| 8216 | <property name="minimum_size">-1,-1</property> | ||
| 8217 | <property name="name">m_textCtrlField15</property> | ||
| 8218 | <property name="permission">protected</property> | ||
| 8219 | <property name="pos"></property> | ||
| 8220 | <property name="size">-1,-1</property> | ||
| 8221 | <property name="style"></property> | ||
| 8222 | <property name="subclass"></property> | ||
| 8223 | <property name="tooltip"></property> | ||
| 8224 | <property name="value"></property> | ||
| 8225 | <property name="window_extra_style"></property> | ||
| 8226 | <property name="window_name"></property> | ||
| 8227 | <property name="window_style"></property> | ||
| 8228 | <event name="OnChar"></event> | ||
| 8229 | <event name="OnEnterWindow"></event> | ||
| 8230 | <event name="OnEraseBackground"></event> | ||
| 8231 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 8232 | <event name="OnKeyUp"></event> | ||
| 8233 | <event name="OnKillFocus"></event> | ||
| 8234 | <event name="OnLeaveWindow"></event> | ||
| 8235 | <event name="OnLeftDClick"></event> | ||
| 8236 | <event name="OnLeftDown"></event> | ||
| 8237 | <event name="OnLeftUp"></event> | ||
| 8238 | <event name="OnMiddleDClick"></event> | ||
| 8239 | <event name="OnMiddleDown"></event> | ||
| 8240 | <event name="OnMiddleUp"></event> | ||
| 8241 | <event name="OnMotion"></event> | ||
| 8242 | <event name="OnMouseEvents"></event> | ||
| 8243 | <event name="OnMouseWheel"></event> | ||
| 8244 | <event name="OnPaint"></event> | ||
| 8245 | <event name="OnRightDClick"></event> | ||
| 8246 | <event name="OnRightDown"></event> | ||
| 8247 | <event name="OnRightUp"></event> | ||
| 8248 | <event name="OnSetFocus"></event> | ||
| 8249 | <event name="OnSize"></event> | ||
| 8250 | <event name="OnText"></event> | ||
| 8251 | <event name="OnTextEnter"></event> | ||
| 8252 | <event name="OnTextMaxLen"></event> | ||
| 8253 | <event name="OnTextURL"></event> | ||
| 8254 | <event name="OnUpdateUI"></event> | ||
| 8255 | </object> | ||
| 8256 | </object> | ||
| 8257 | <object class="sizeritem" expanded="1"> | ||
| 8258 | <property name="border">5</property> | ||
| 8259 | <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property> | ||
| 8260 | <property name="proportion">0</property> | ||
| 8261 | <object class="wxButton" expanded="1"> | ||
| 8262 | <property name="bg"></property> | ||
| 8263 | <property name="context_help"></property> | ||
| 8264 | <property name="default">0</property> | ||
| 8265 | <property name="enabled">1</property> | ||
| 8266 | <property name="fg"></property> | ||
| 8267 | <property name="font"></property> | ||
| 8268 | <property name="hidden">0</property> | ||
| 8269 | <property name="id">wxID_DEL15</property> | ||
| 8270 | <property name="label">Delete</property> | ||
| 8271 | <property name="maximum_size"></property> | ||
| 8272 | <property name="minimum_size">-1,-1</property> | ||
| 8273 | <property name="name">m_buttonDel15</property> | ||
| 8274 | <property name="permission">protected</property> | ||
| 8275 | <property name="pos"></property> | ||
| 8276 | <property name="size">60,20</property> | ||
| 8277 | <property name="style"></property> | ||
| 8278 | <property name="subclass"></property> | ||
| 8279 | <property name="tooltip"></property> | ||
| 8280 | <property name="window_extra_style"></property> | ||
| 8281 | <property name="window_name"></property> | ||
| 8282 | <property name="window_style"></property> | ||
| 8283 | <event name="OnButtonClick">OnButtonDel15</event> | ||
| 8284 | <event name="OnChar"></event> | ||
| 8285 | <event name="OnEnterWindow"></event> | ||
| 8286 | <event name="OnEraseBackground"></event> | ||
| 8287 | <event name="OnKeyDown"></event> | ||
| 8288 | <event name="OnKeyUp"></event> | ||
| 8289 | <event name="OnKillFocus"></event> | ||
| 8290 | <event name="OnLeaveWindow"></event> | ||
| 8291 | <event name="OnLeftDClick"></event> | ||
| 8292 | <event name="OnLeftDown"></event> | ||
| 8293 | <event name="OnLeftUp"></event> | ||
| 8294 | <event name="OnMiddleDClick"></event> | ||
| 8295 | <event name="OnMiddleDown"></event> | ||
| 8296 | <event name="OnMiddleUp"></event> | ||
| 8297 | <event name="OnMotion"></event> | ||
| 8298 | <event name="OnMouseEvents"></event> | ||
| 8299 | <event name="OnMouseWheel"></event> | ||
| 8300 | <event name="OnPaint"></event> | ||
| 8301 | <event name="OnRightDClick"></event> | ||
| 8302 | <event name="OnRightDown"></event> | ||
| 8303 | <event name="OnRightUp"></event> | ||
| 8304 | <event name="OnSetFocus"></event> | ||
| 8305 | <event name="OnSize"></event> | ||
| 8306 | <event name="OnUpdateUI"></event> | ||
| 8307 | </object> | ||
| 8308 | </object> | ||
| 8309 | <object class="sizeritem" expanded="1"> | ||
| 8310 | <property name="border">5</property> | ||
| 8311 | <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property> | ||
| 8312 | <property name="proportion">0</property> | ||
| 8313 | <object class="wxTextCtrl" expanded="1"> | ||
| 8314 | <property name="bg"></property> | ||
| 8315 | <property name="context_help"></property> | ||
| 8316 | <property name="enabled">1</property> | ||
| 8317 | <property name="fg"></property> | ||
| 8318 | <property name="font"></property> | ||
| 8319 | <property name="hidden">0</property> | ||
| 8320 | <property name="id">wxID_ANY</property> | ||
| 8321 | <property name="maximum_size"></property> | ||
| 8322 | <property name="maxlength">0</property> | ||
| 8323 | <property name="minimum_size">150,-1</property> | ||
| 8324 | <property name="name">m_textCtrlLabel16</property> | ||
| 8325 | <property name="permission">protected</property> | ||
| 8326 | <property name="pos"></property> | ||
| 8327 | <property name="size"></property> | ||
| 8328 | <property name="style"></property> | ||
| 8329 | <property name="subclass"></property> | ||
| 8330 | <property name="tooltip"></property> | ||
| 8331 | <property name="value"></property> | ||
| 8332 | <property name="window_extra_style"></property> | ||
| 8333 | <property name="window_name"></property> | ||
| 8334 | <property name="window_style"></property> | ||
| 8335 | <event name="OnChar"></event> | ||
| 8336 | <event name="OnEnterWindow"></event> | ||
| 8337 | <event name="OnEraseBackground"></event> | ||
| 8338 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 8339 | <event name="OnKeyUp"></event> | ||
| 8340 | <event name="OnKillFocus"></event> | ||
| 8341 | <event name="OnLeaveWindow"></event> | ||
| 8342 | <event name="OnLeftDClick"></event> | ||
| 8343 | <event name="OnLeftDown"></event> | ||
| 8344 | <event name="OnLeftUp"></event> | ||
| 8345 | <event name="OnMiddleDClick"></event> | ||
| 8346 | <event name="OnMiddleDown"></event> | ||
| 8347 | <event name="OnMiddleUp"></event> | ||
| 8348 | <event name="OnMotion"></event> | ||
| 8349 | <event name="OnMouseEvents"></event> | ||
| 8350 | <event name="OnMouseWheel"></event> | ||
| 8351 | <event name="OnPaint"></event> | ||
| 8352 | <event name="OnRightDClick"></event> | ||
| 8353 | <event name="OnRightDown"></event> | ||
| 8354 | <event name="OnRightUp"></event> | ||
| 8355 | <event name="OnSetFocus"></event> | ||
| 8356 | <event name="OnSize"></event> | ||
| 8357 | <event name="OnText"></event> | ||
| 8358 | <event name="OnTextEnter"></event> | ||
| 8359 | <event name="OnTextMaxLen"></event> | ||
| 8360 | <event name="OnTextURL"></event> | ||
| 8361 | <event name="OnUpdateUI"></event> | ||
| 8362 | </object> | ||
| 8363 | </object> | ||
| 8364 | <object class="sizeritem" expanded="1"> | ||
| 8365 | <property name="border">5</property> | ||
| 8366 | <property name="flag">wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL</property> | ||
| 8367 | <property name="proportion">0</property> | ||
| 8368 | <object class="wxTextCtrl" expanded="1"> | ||
| 8369 | <property name="bg"></property> | ||
| 8370 | <property name="context_help"></property> | ||
| 8371 | <property name="enabled">1</property> | ||
| 8372 | <property name="fg"></property> | ||
| 8373 | <property name="font"></property> | ||
| 8374 | <property name="hidden">0</property> | ||
| 8375 | <property name="id">wxID_ANY</property> | ||
| 8376 | <property name="maximum_size">-1,-1</property> | ||
| 8377 | <property name="maxlength">0</property> | ||
| 8378 | <property name="minimum_size">-1,-1</property> | ||
| 8379 | <property name="name">m_textCtrlField16</property> | ||
| 8380 | <property name="permission">protected</property> | ||
| 8381 | <property name="pos"></property> | ||
| 8382 | <property name="size">-1,-1</property> | ||
| 8383 | <property name="style"></property> | ||
| 8384 | <property name="subclass"></property> | ||
| 8385 | <property name="tooltip"></property> | ||
| 8386 | <property name="value"></property> | ||
| 8387 | <property name="window_extra_style"></property> | ||
| 8388 | <property name="window_name"></property> | ||
| 8389 | <property name="window_style"></property> | ||
| 8390 | <event name="OnChar"></event> | ||
| 8391 | <event name="OnEnterWindow"></event> | ||
| 8392 | <event name="OnEraseBackground"></event> | ||
| 8393 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 8394 | <event name="OnKeyUp"></event> | ||
| 8395 | <event name="OnKillFocus"></event> | ||
| 8396 | <event name="OnLeaveWindow"></event> | ||
| 8397 | <event name="OnLeftDClick"></event> | ||
| 8398 | <event name="OnLeftDown"></event> | ||
| 8399 | <event name="OnLeftUp"></event> | ||
| 8400 | <event name="OnMiddleDClick"></event> | ||
| 8401 | <event name="OnMiddleDown"></event> | ||
| 8402 | <event name="OnMiddleUp"></event> | ||
| 8403 | <event name="OnMotion"></event> | ||
| 8404 | <event name="OnMouseEvents"></event> | ||
| 8405 | <event name="OnMouseWheel"></event> | ||
| 8406 | <event name="OnPaint"></event> | ||
| 8407 | <event name="OnRightDClick"></event> | ||
| 8408 | <event name="OnRightDown"></event> | ||
| 8409 | <event name="OnRightUp"></event> | ||
| 8410 | <event name="OnSetFocus"></event> | ||
| 8411 | <event name="OnSize"></event> | ||
| 8412 | <event name="OnText"></event> | ||
| 8413 | <event name="OnTextEnter"></event> | ||
| 8414 | <event name="OnTextMaxLen"></event> | ||
| 8415 | <event name="OnTextURL"></event> | ||
| 8416 | <event name="OnUpdateUI"></event> | ||
| 8417 | </object> | ||
| 8418 | </object> | ||
| 8419 | <object class="sizeritem" expanded="1"> | ||
| 8420 | <property name="border">5</property> | ||
| 8421 | <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property> | ||
| 8422 | <property name="proportion">0</property> | ||
| 8423 | <object class="wxButton" expanded="1"> | ||
| 8424 | <property name="bg"></property> | ||
| 8425 | <property name="context_help"></property> | ||
| 8426 | <property name="default">0</property> | ||
| 8427 | <property name="enabled">1</property> | ||
| 8428 | <property name="fg"></property> | ||
| 8429 | <property name="font"></property> | ||
| 8430 | <property name="hidden">0</property> | ||
| 8431 | <property name="id">wxID_DEL16</property> | ||
| 8432 | <property name="label">Delete</property> | ||
| 8433 | <property name="maximum_size"></property> | ||
| 8434 | <property name="minimum_size">-1,-1</property> | ||
| 8435 | <property name="name">m_buttonDel16</property> | ||
| 8436 | <property name="permission">protected</property> | ||
| 8437 | <property name="pos"></property> | ||
| 8438 | <property name="size">60,20</property> | ||
| 8439 | <property name="style"></property> | ||
| 8440 | <property name="subclass"></property> | ||
| 8441 | <property name="tooltip"></property> | ||
| 8442 | <property name="window_extra_style"></property> | ||
| 8443 | <property name="window_name"></property> | ||
| 8444 | <property name="window_style"></property> | ||
| 8445 | <event name="OnButtonClick">OnButtonDel16</event> | ||
| 8446 | <event name="OnChar"></event> | ||
| 8447 | <event name="OnEnterWindow"></event> | ||
| 8448 | <event name="OnEraseBackground"></event> | ||
| 8449 | <event name="OnKeyDown"></event> | ||
| 8450 | <event name="OnKeyUp"></event> | ||
| 8451 | <event name="OnKillFocus"></event> | ||
| 8452 | <event name="OnLeaveWindow"></event> | ||
| 8453 | <event name="OnLeftDClick"></event> | ||
| 8454 | <event name="OnLeftDown"></event> | ||
| 8455 | <event name="OnLeftUp"></event> | ||
| 8456 | <event name="OnMiddleDClick"></event> | ||
| 8457 | <event name="OnMiddleDown"></event> | ||
| 8458 | <event name="OnMiddleUp"></event> | ||
| 8459 | <event name="OnMotion"></event> | ||
| 8460 | <event name="OnMouseEvents"></event> | ||
| 8461 | <event name="OnMouseWheel"></event> | ||
| 8462 | <event name="OnPaint"></event> | ||
| 8463 | <event name="OnRightDClick"></event> | ||
| 8464 | <event name="OnRightDown"></event> | ||
| 8465 | <event name="OnRightUp"></event> | ||
| 8466 | <event name="OnSetFocus"></event> | ||
| 8467 | <event name="OnSize"></event> | ||
| 8468 | <event name="OnUpdateUI"></event> | ||
| 8469 | </object> | ||
| 8470 | </object> | ||
| 8471 | <object class="sizeritem" expanded="1"> | ||
| 8472 | <property name="border">5</property> | ||
| 8473 | <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property> | ||
| 8474 | <property name="proportion">0</property> | ||
| 8475 | <object class="wxTextCtrl" expanded="1"> | ||
| 8476 | <property name="bg"></property> | ||
| 8477 | <property name="context_help"></property> | ||
| 8478 | <property name="enabled">1</property> | ||
| 8479 | <property name="fg"></property> | ||
| 8480 | <property name="font"></property> | ||
| 8481 | <property name="hidden">0</property> | ||
| 8482 | <property name="id">wxID_ANY</property> | ||
| 8483 | <property name="maximum_size"></property> | ||
| 8484 | <property name="maxlength">0</property> | ||
| 8485 | <property name="minimum_size">150,-1</property> | ||
| 8486 | <property name="name">m_textCtrlLabel17</property> | ||
| 8487 | <property name="permission">protected</property> | ||
| 8488 | <property name="pos"></property> | ||
| 8489 | <property name="size"></property> | ||
| 8490 | <property name="style"></property> | ||
| 8491 | <property name="subclass"></property> | ||
| 8492 | <property name="tooltip"></property> | ||
| 8493 | <property name="value"></property> | ||
| 8494 | <property name="window_extra_style"></property> | ||
| 8495 | <property name="window_name"></property> | ||
| 8496 | <property name="window_style"></property> | ||
| 8497 | <event name="OnChar"></event> | ||
| 8498 | <event name="OnEnterWindow"></event> | ||
| 8499 | <event name="OnEraseBackground"></event> | ||
| 8500 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 8501 | <event name="OnKeyUp"></event> | ||
| 8502 | <event name="OnKillFocus"></event> | ||
| 8503 | <event name="OnLeaveWindow"></event> | ||
| 8504 | <event name="OnLeftDClick"></event> | ||
| 8505 | <event name="OnLeftDown"></event> | ||
| 8506 | <event name="OnLeftUp"></event> | ||
| 8507 | <event name="OnMiddleDClick"></event> | ||
| 8508 | <event name="OnMiddleDown"></event> | ||
| 8509 | <event name="OnMiddleUp"></event> | ||
| 8510 | <event name="OnMotion"></event> | ||
| 8511 | <event name="OnMouseEvents"></event> | ||
| 8512 | <event name="OnMouseWheel"></event> | ||
| 8513 | <event name="OnPaint"></event> | ||
| 8514 | <event name="OnRightDClick"></event> | ||
| 8515 | <event name="OnRightDown"></event> | ||
| 8516 | <event name="OnRightUp"></event> | ||
| 8517 | <event name="OnSetFocus"></event> | ||
| 8518 | <event name="OnSize"></event> | ||
| 8519 | <event name="OnText"></event> | ||
| 8520 | <event name="OnTextEnter"></event> | ||
| 8521 | <event name="OnTextMaxLen"></event> | ||
| 8522 | <event name="OnTextURL"></event> | ||
| 8523 | <event name="OnUpdateUI"></event> | ||
| 8524 | </object> | ||
| 8525 | </object> | ||
| 8526 | <object class="sizeritem" expanded="1"> | ||
| 8527 | <property name="border">5</property> | ||
| 8528 | <property name="flag">wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL</property> | ||
| 8529 | <property name="proportion">0</property> | ||
| 8530 | <object class="wxTextCtrl" expanded="1"> | ||
| 8531 | <property name="bg"></property> | ||
| 8532 | <property name="context_help"></property> | ||
| 8533 | <property name="enabled">1</property> | ||
| 8534 | <property name="fg"></property> | ||
| 8535 | <property name="font"></property> | ||
| 8536 | <property name="hidden">0</property> | ||
| 8537 | <property name="id">wxID_ANY</property> | ||
| 8538 | <property name="maximum_size">-1,-1</property> | ||
| 8539 | <property name="maxlength">0</property> | ||
| 8540 | <property name="minimum_size">-1,-1</property> | ||
| 8541 | <property name="name">m_textCtrlField17</property> | ||
| 8542 | <property name="permission">protected</property> | ||
| 8543 | <property name="pos"></property> | ||
| 8544 | <property name="size">-1,-1</property> | ||
| 8545 | <property name="style"></property> | ||
| 8546 | <property name="subclass"></property> | ||
| 8547 | <property name="tooltip"></property> | ||
| 8548 | <property name="value"></property> | ||
| 8549 | <property name="window_extra_style"></property> | ||
| 8550 | <property name="window_name"></property> | ||
| 8551 | <property name="window_style"></property> | ||
| 8552 | <event name="OnChar"></event> | ||
| 8553 | <event name="OnEnterWindow"></event> | ||
| 8554 | <event name="OnEraseBackground"></event> | ||
| 8555 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 8556 | <event name="OnKeyUp"></event> | ||
| 8557 | <event name="OnKillFocus"></event> | ||
| 8558 | <event name="OnLeaveWindow"></event> | ||
| 8559 | <event name="OnLeftDClick"></event> | ||
| 8560 | <event name="OnLeftDown"></event> | ||
| 8561 | <event name="OnLeftUp"></event> | ||
| 8562 | <event name="OnMiddleDClick"></event> | ||
| 8563 | <event name="OnMiddleDown"></event> | ||
| 8564 | <event name="OnMiddleUp"></event> | ||
| 8565 | <event name="OnMotion"></event> | ||
| 8566 | <event name="OnMouseEvents"></event> | ||
| 8567 | <event name="OnMouseWheel"></event> | ||
| 8568 | <event name="OnPaint"></event> | ||
| 8569 | <event name="OnRightDClick"></event> | ||
| 8570 | <event name="OnRightDown"></event> | ||
| 8571 | <event name="OnRightUp"></event> | ||
| 8572 | <event name="OnSetFocus"></event> | ||
| 8573 | <event name="OnSize"></event> | ||
| 8574 | <event name="OnText"></event> | ||
| 8575 | <event name="OnTextEnter"></event> | ||
| 8576 | <event name="OnTextMaxLen"></event> | ||
| 8577 | <event name="OnTextURL"></event> | ||
| 8578 | <event name="OnUpdateUI"></event> | ||
| 8579 | </object> | ||
| 8580 | </object> | ||
| 8581 | <object class="sizeritem" expanded="1"> | ||
| 8582 | <property name="border">5</property> | ||
| 8583 | <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property> | ||
| 8584 | <property name="proportion">0</property> | ||
| 8585 | <object class="wxButton" expanded="1"> | ||
| 8586 | <property name="bg"></property> | ||
| 8587 | <property name="context_help"></property> | ||
| 8588 | <property name="default">0</property> | ||
| 8589 | <property name="enabled">1</property> | ||
| 8590 | <property name="fg"></property> | ||
| 8591 | <property name="font"></property> | ||
| 8592 | <property name="hidden">0</property> | ||
| 8593 | <property name="id">wxID_DEL17</property> | ||
| 8594 | <property name="label">Delete</property> | ||
| 8595 | <property name="maximum_size"></property> | ||
| 8596 | <property name="minimum_size">-1,-1</property> | ||
| 8597 | <property name="name">m_buttonDel17</property> | ||
| 8598 | <property name="permission">protected</property> | ||
| 8599 | <property name="pos"></property> | ||
| 8600 | <property name="size">60,20</property> | ||
| 8601 | <property name="style"></property> | ||
| 8602 | <property name="subclass"></property> | ||
| 8603 | <property name="tooltip"></property> | ||
| 8604 | <property name="window_extra_style"></property> | ||
| 8605 | <property name="window_name"></property> | ||
| 8606 | <property name="window_style"></property> | ||
| 8607 | <event name="OnButtonClick">OnButtonDel17</event> | ||
| 8608 | <event name="OnChar"></event> | ||
| 8609 | <event name="OnEnterWindow"></event> | ||
| 8610 | <event name="OnEraseBackground"></event> | ||
| 8611 | <event name="OnKeyDown"></event> | ||
| 8612 | <event name="OnKeyUp"></event> | ||
| 8613 | <event name="OnKillFocus"></event> | ||
| 8614 | <event name="OnLeaveWindow"></event> | ||
| 8615 | <event name="OnLeftDClick"></event> | ||
| 8616 | <event name="OnLeftDown"></event> | ||
| 8617 | <event name="OnLeftUp"></event> | ||
| 8618 | <event name="OnMiddleDClick"></event> | ||
| 8619 | <event name="OnMiddleDown"></event> | ||
| 8620 | <event name="OnMiddleUp"></event> | ||
| 8621 | <event name="OnMotion"></event> | ||
| 8622 | <event name="OnMouseEvents"></event> | ||
| 8623 | <event name="OnMouseWheel"></event> | ||
| 8624 | <event name="OnPaint"></event> | ||
| 8625 | <event name="OnRightDClick"></event> | ||
| 8626 | <event name="OnRightDown"></event> | ||
| 8627 | <event name="OnRightUp"></event> | ||
| 8628 | <event name="OnSetFocus"></event> | ||
| 8629 | <event name="OnSize"></event> | ||
| 8630 | <event name="OnUpdateUI"></event> | ||
| 8631 | </object> | ||
| 8632 | </object> | ||
| 8633 | <object class="sizeritem" expanded="1"> | ||
| 8634 | <property name="border">5</property> | ||
| 8635 | <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property> | ||
| 8636 | <property name="proportion">0</property> | ||
| 8637 | <object class="wxTextCtrl" expanded="1"> | ||
| 8638 | <property name="bg"></property> | ||
| 8639 | <property name="context_help"></property> | ||
| 8640 | <property name="enabled">1</property> | ||
| 8641 | <property name="fg"></property> | ||
| 8642 | <property name="font"></property> | ||
| 8643 | <property name="hidden">0</property> | ||
| 8644 | <property name="id">wxID_ANY</property> | ||
| 8645 | <property name="maximum_size"></property> | ||
| 8646 | <property name="maxlength">0</property> | ||
| 8647 | <property name="minimum_size">150,-1</property> | ||
| 8648 | <property name="name">m_textCtrlLabel18</property> | ||
| 8649 | <property name="permission">protected</property> | ||
| 8650 | <property name="pos"></property> | ||
| 8651 | <property name="size"></property> | ||
| 8652 | <property name="style"></property> | ||
| 8653 | <property name="subclass"></property> | ||
| 8654 | <property name="tooltip"></property> | ||
| 8655 | <property name="value"></property> | ||
| 8656 | <property name="window_extra_style"></property> | ||
| 8657 | <property name="window_name"></property> | ||
| 8658 | <property name="window_style"></property> | ||
| 8659 | <event name="OnChar"></event> | ||
| 8660 | <event name="OnEnterWindow"></event> | ||
| 8661 | <event name="OnEraseBackground"></event> | ||
| 8662 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 8663 | <event name="OnKeyUp"></event> | ||
| 8664 | <event name="OnKillFocus"></event> | ||
| 8665 | <event name="OnLeaveWindow"></event> | ||
| 8666 | <event name="OnLeftDClick"></event> | ||
| 8667 | <event name="OnLeftDown"></event> | ||
| 8668 | <event name="OnLeftUp"></event> | ||
| 8669 | <event name="OnMiddleDClick"></event> | ||
| 8670 | <event name="OnMiddleDown"></event> | ||
| 8671 | <event name="OnMiddleUp"></event> | ||
| 8672 | <event name="OnMotion"></event> | ||
| 8673 | <event name="OnMouseEvents"></event> | ||
| 8674 | <event name="OnMouseWheel"></event> | ||
| 8675 | <event name="OnPaint"></event> | ||
| 8676 | <event name="OnRightDClick"></event> | ||
| 8677 | <event name="OnRightDown"></event> | ||
| 8678 | <event name="OnRightUp"></event> | ||
| 8679 | <event name="OnSetFocus"></event> | ||
| 8680 | <event name="OnSize"></event> | ||
| 8681 | <event name="OnText"></event> | ||
| 8682 | <event name="OnTextEnter"></event> | ||
| 8683 | <event name="OnTextMaxLen"></event> | ||
| 8684 | <event name="OnTextURL"></event> | ||
| 8685 | <event name="OnUpdateUI"></event> | ||
| 8686 | </object> | ||
| 8687 | </object> | ||
| 8688 | <object class="sizeritem" expanded="1"> | ||
| 8689 | <property name="border">5</property> | ||
| 8690 | <property name="flag">wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL</property> | ||
| 8691 | <property name="proportion">0</property> | ||
| 8692 | <object class="wxTextCtrl" expanded="1"> | ||
| 8693 | <property name="bg"></property> | ||
| 8694 | <property name="context_help"></property> | ||
| 8695 | <property name="enabled">1</property> | ||
| 8696 | <property name="fg"></property> | ||
| 8697 | <property name="font"></property> | ||
| 8698 | <property name="hidden">0</property> | ||
| 8699 | <property name="id">wxID_ANY</property> | ||
| 8700 | <property name="maximum_size">-1,-1</property> | ||
| 8701 | <property name="maxlength">0</property> | ||
| 8702 | <property name="minimum_size">-1,-1</property> | ||
| 8703 | <property name="name">m_textCtrlField18</property> | ||
| 8704 | <property name="permission">protected</property> | ||
| 8705 | <property name="pos"></property> | ||
| 8706 | <property name="size">-1,-1</property> | ||
| 8707 | <property name="style"></property> | ||
| 8708 | <property name="subclass"></property> | ||
| 8709 | <property name="tooltip"></property> | ||
| 8710 | <property name="value"></property> | ||
| 8711 | <property name="window_extra_style"></property> | ||
| 8712 | <property name="window_name"></property> | ||
| 8713 | <property name="window_style"></property> | ||
| 8714 | <event name="OnChar"></event> | ||
| 8715 | <event name="OnEnterWindow"></event> | ||
| 8716 | <event name="OnEraseBackground"></event> | ||
| 8717 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 8718 | <event name="OnKeyUp"></event> | ||
| 8719 | <event name="OnKillFocus"></event> | ||
| 8720 | <event name="OnLeaveWindow"></event> | ||
| 8721 | <event name="OnLeftDClick"></event> | ||
| 8722 | <event name="OnLeftDown"></event> | ||
| 8723 | <event name="OnLeftUp"></event> | ||
| 8724 | <event name="OnMiddleDClick"></event> | ||
| 8725 | <event name="OnMiddleDown"></event> | ||
| 8726 | <event name="OnMiddleUp"></event> | ||
| 8727 | <event name="OnMotion"></event> | ||
| 8728 | <event name="OnMouseEvents"></event> | ||
| 8729 | <event name="OnMouseWheel"></event> | ||
| 8730 | <event name="OnPaint"></event> | ||
| 8731 | <event name="OnRightDClick"></event> | ||
| 8732 | <event name="OnRightDown"></event> | ||
| 8733 | <event name="OnRightUp"></event> | ||
| 8734 | <event name="OnSetFocus"></event> | ||
| 8735 | <event name="OnSize"></event> | ||
| 8736 | <event name="OnText"></event> | ||
| 8737 | <event name="OnTextEnter"></event> | ||
| 8738 | <event name="OnTextMaxLen"></event> | ||
| 8739 | <event name="OnTextURL"></event> | ||
| 8740 | <event name="OnUpdateUI"></event> | ||
| 8741 | </object> | ||
| 8742 | </object> | ||
| 8743 | <object class="sizeritem" expanded="1"> | ||
| 8744 | <property name="border">5</property> | ||
| 8745 | <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property> | ||
| 8746 | <property name="proportion">0</property> | ||
| 8747 | <object class="wxButton" expanded="1"> | ||
| 8748 | <property name="bg"></property> | ||
| 8749 | <property name="context_help"></property> | ||
| 8750 | <property name="default">0</property> | ||
| 8751 | <property name="enabled">1</property> | ||
| 8752 | <property name="fg"></property> | ||
| 8753 | <property name="font"></property> | ||
| 8754 | <property name="hidden">0</property> | ||
| 8755 | <property name="id">wxID_DEL18</property> | ||
| 8756 | <property name="label">Delete</property> | ||
| 8757 | <property name="maximum_size"></property> | ||
| 8758 | <property name="minimum_size">-1,-1</property> | ||
| 8759 | <property name="name">m_buttonDel18</property> | ||
| 8760 | <property name="permission">protected</property> | ||
| 8761 | <property name="pos"></property> | ||
| 8762 | <property name="size">60,20</property> | ||
| 8763 | <property name="style"></property> | ||
| 8764 | <property name="subclass"></property> | ||
| 8765 | <property name="tooltip"></property> | ||
| 8766 | <property name="window_extra_style"></property> | ||
| 8767 | <property name="window_name"></property> | ||
| 8768 | <property name="window_style"></property> | ||
| 8769 | <event name="OnButtonClick">OnButtonDel18</event> | ||
| 8770 | <event name="OnChar"></event> | ||
| 8771 | <event name="OnEnterWindow"></event> | ||
| 8772 | <event name="OnEraseBackground"></event> | ||
| 8773 | <event name="OnKeyDown"></event> | ||
| 8774 | <event name="OnKeyUp"></event> | ||
| 8775 | <event name="OnKillFocus"></event> | ||
| 8776 | <event name="OnLeaveWindow"></event> | ||
| 8777 | <event name="OnLeftDClick"></event> | ||
| 8778 | <event name="OnLeftDown"></event> | ||
| 8779 | <event name="OnLeftUp"></event> | ||
| 8780 | <event name="OnMiddleDClick"></event> | ||
| 8781 | <event name="OnMiddleDown"></event> | ||
| 8782 | <event name="OnMiddleUp"></event> | ||
| 8783 | <event name="OnMotion"></event> | ||
| 8784 | <event name="OnMouseEvents"></event> | ||
| 8785 | <event name="OnMouseWheel"></event> | ||
| 8786 | <event name="OnPaint"></event> | ||
| 8787 | <event name="OnRightDClick"></event> | ||
| 8788 | <event name="OnRightDown"></event> | ||
| 8789 | <event name="OnRightUp"></event> | ||
| 8790 | <event name="OnSetFocus"></event> | ||
| 8791 | <event name="OnSize"></event> | ||
| 8792 | <event name="OnUpdateUI"></event> | ||
| 8793 | </object> | ||
| 8794 | </object> | ||
| 8795 | <object class="sizeritem" expanded="1"> | ||
| 8796 | <property name="border">5</property> | ||
| 8797 | <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property> | ||
| 8798 | <property name="proportion">0</property> | ||
| 8799 | <object class="wxTextCtrl" expanded="1"> | ||
| 8800 | <property name="bg"></property> | ||
| 8801 | <property name="context_help"></property> | ||
| 8802 | <property name="enabled">1</property> | ||
| 8803 | <property name="fg"></property> | ||
| 8804 | <property name="font"></property> | ||
| 8805 | <property name="hidden">0</property> | ||
| 8806 | <property name="id">wxID_ANY</property> | ||
| 8807 | <property name="maximum_size"></property> | ||
| 8808 | <property name="maxlength">0</property> | ||
| 8809 | <property name="minimum_size">150,-1</property> | ||
| 8810 | <property name="name">m_textCtrlLabel19</property> | ||
| 8811 | <property name="permission">protected</property> | ||
| 8812 | <property name="pos"></property> | ||
| 8813 | <property name="size"></property> | ||
| 8814 | <property name="style"></property> | ||
| 8815 | <property name="subclass"></property> | ||
| 8816 | <property name="tooltip"></property> | ||
| 8817 | <property name="value"></property> | ||
| 8818 | <property name="window_extra_style"></property> | ||
| 8819 | <property name="window_name"></property> | ||
| 8820 | <property name="window_style"></property> | ||
| 8821 | <event name="OnChar"></event> | ||
| 8822 | <event name="OnEnterWindow"></event> | ||
| 8823 | <event name="OnEraseBackground"></event> | ||
| 8824 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 8825 | <event name="OnKeyUp"></event> | ||
| 8826 | <event name="OnKillFocus"></event> | ||
| 8827 | <event name="OnLeaveWindow"></event> | ||
| 8828 | <event name="OnLeftDClick"></event> | ||
| 8829 | <event name="OnLeftDown"></event> | ||
| 8830 | <event name="OnLeftUp"></event> | ||
| 8831 | <event name="OnMiddleDClick"></event> | ||
| 8832 | <event name="OnMiddleDown"></event> | ||
| 8833 | <event name="OnMiddleUp"></event> | ||
| 8834 | <event name="OnMotion"></event> | ||
| 8835 | <event name="OnMouseEvents"></event> | ||
| 8836 | <event name="OnMouseWheel"></event> | ||
| 8837 | <event name="OnPaint"></event> | ||
| 8838 | <event name="OnRightDClick"></event> | ||
| 8839 | <event name="OnRightDown"></event> | ||
| 8840 | <event name="OnRightUp"></event> | ||
| 8841 | <event name="OnSetFocus"></event> | ||
| 8842 | <event name="OnSize"></event> | ||
| 8843 | <event name="OnText"></event> | ||
| 8844 | <event name="OnTextEnter"></event> | ||
| 8845 | <event name="OnTextMaxLen"></event> | ||
| 8846 | <event name="OnTextURL"></event> | ||
| 8847 | <event name="OnUpdateUI"></event> | ||
| 8848 | </object> | ||
| 8849 | </object> | ||
| 8850 | <object class="sizeritem" expanded="1"> | ||
| 8851 | <property name="border">5</property> | ||
| 8852 | <property name="flag">wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL</property> | ||
| 8853 | <property name="proportion">0</property> | ||
| 8854 | <object class="wxTextCtrl" expanded="1"> | ||
| 8855 | <property name="bg"></property> | ||
| 8856 | <property name="context_help"></property> | ||
| 8857 | <property name="enabled">1</property> | ||
| 8858 | <property name="fg"></property> | ||
| 8859 | <property name="font"></property> | ||
| 8860 | <property name="hidden">0</property> | ||
| 8861 | <property name="id">wxID_ANY</property> | ||
| 8862 | <property name="maximum_size">-1,-1</property> | ||
| 8863 | <property name="maxlength">0</property> | ||
| 8864 | <property name="minimum_size">-1,-1</property> | ||
| 8865 | <property name="name">m_textCtrlField19</property> | ||
| 8866 | <property name="permission">protected</property> | ||
| 8867 | <property name="pos"></property> | ||
| 8868 | <property name="size">-1,-1</property> | ||
| 8869 | <property name="style"></property> | ||
| 8870 | <property name="subclass"></property> | ||
| 8871 | <property name="tooltip"></property> | ||
| 8872 | <property name="value"></property> | ||
| 8873 | <property name="window_extra_style"></property> | ||
| 8874 | <property name="window_name"></property> | ||
| 8875 | <property name="window_style"></property> | ||
| 8876 | <event name="OnChar"></event> | ||
| 8877 | <event name="OnEnterWindow"></event> | ||
| 8878 | <event name="OnEraseBackground"></event> | ||
| 8879 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 8880 | <event name="OnKeyUp"></event> | ||
| 8881 | <event name="OnKillFocus"></event> | ||
| 8882 | <event name="OnLeaveWindow"></event> | ||
| 8883 | <event name="OnLeftDClick"></event> | ||
| 8884 | <event name="OnLeftDown"></event> | ||
| 8885 | <event name="OnLeftUp"></event> | ||
| 8886 | <event name="OnMiddleDClick"></event> | ||
| 8887 | <event name="OnMiddleDown"></event> | ||
| 8888 | <event name="OnMiddleUp"></event> | ||
| 8889 | <event name="OnMotion"></event> | ||
| 8890 | <event name="OnMouseEvents"></event> | ||
| 8891 | <event name="OnMouseWheel"></event> | ||
| 8892 | <event name="OnPaint"></event> | ||
| 8893 | <event name="OnRightDClick"></event> | ||
| 8894 | <event name="OnRightDown"></event> | ||
| 8895 | <event name="OnRightUp"></event> | ||
| 8896 | <event name="OnSetFocus"></event> | ||
| 8897 | <event name="OnSize"></event> | ||
| 8898 | <event name="OnText"></event> | ||
| 8899 | <event name="OnTextEnter"></event> | ||
| 8900 | <event name="OnTextMaxLen"></event> | ||
| 8901 | <event name="OnTextURL"></event> | ||
| 8902 | <event name="OnUpdateUI"></event> | ||
| 8903 | </object> | ||
| 8904 | </object> | ||
| 8905 | <object class="sizeritem" expanded="1"> | ||
| 8906 | <property name="border">5</property> | ||
| 8907 | <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property> | ||
| 8908 | <property name="proportion">0</property> | ||
| 8909 | <object class="wxButton" expanded="1"> | ||
| 8910 | <property name="bg"></property> | ||
| 8911 | <property name="context_help"></property> | ||
| 8912 | <property name="default">0</property> | ||
| 8913 | <property name="enabled">1</property> | ||
| 8914 | <property name="fg"></property> | ||
| 8915 | <property name="font"></property> | ||
| 8916 | <property name="hidden">0</property> | ||
| 8917 | <property name="id">wxID_DEL19</property> | ||
| 8918 | <property name="label">Delete</property> | ||
| 8919 | <property name="maximum_size"></property> | ||
| 8920 | <property name="minimum_size">-1,-1</property> | ||
| 8921 | <property name="name">m_buttonDel19</property> | ||
| 8922 | <property name="permission">protected</property> | ||
| 8923 | <property name="pos"></property> | ||
| 8924 | <property name="size">60,20</property> | ||
| 8925 | <property name="style"></property> | ||
| 8926 | <property name="subclass"></property> | ||
| 8927 | <property name="tooltip"></property> | ||
| 8928 | <property name="window_extra_style"></property> | ||
| 8929 | <property name="window_name"></property> | ||
| 8930 | <property name="window_style"></property> | ||
| 8931 | <event name="OnButtonClick">OnButtonDel19</event> | ||
| 8932 | <event name="OnChar"></event> | ||
| 8933 | <event name="OnEnterWindow"></event> | ||
| 8934 | <event name="OnEraseBackground"></event> | ||
| 8935 | <event name="OnKeyDown"></event> | ||
| 8936 | <event name="OnKeyUp"></event> | ||
| 8937 | <event name="OnKillFocus"></event> | ||
| 8938 | <event name="OnLeaveWindow"></event> | ||
| 8939 | <event name="OnLeftDClick"></event> | ||
| 8940 | <event name="OnLeftDown"></event> | ||
| 8941 | <event name="OnLeftUp"></event> | ||
| 8942 | <event name="OnMiddleDClick"></event> | ||
| 8943 | <event name="OnMiddleDown"></event> | ||
| 8944 | <event name="OnMiddleUp"></event> | ||
| 8945 | <event name="OnMotion"></event> | ||
| 8946 | <event name="OnMouseEvents"></event> | ||
| 8947 | <event name="OnMouseWheel"></event> | ||
| 8948 | <event name="OnPaint"></event> | ||
| 8949 | <event name="OnRightDClick"></event> | ||
| 8950 | <event name="OnRightDown"></event> | ||
| 8951 | <event name="OnRightUp"></event> | ||
| 8952 | <event name="OnSetFocus"></event> | ||
| 8953 | <event name="OnSize"></event> | ||
| 8954 | <event name="OnUpdateUI"></event> | ||
| 8955 | </object> | ||
| 8956 | </object> | ||
| 8957 | </object> | ||
| 8958 | </object> | ||
| 8959 | <object class="sizeritem" expanded="1"> | ||
| 8960 | <property name="border">5</property> | ||
| 8961 | <property name="flag">wxALIGN_CENTER_HORIZONTAL</property> | ||
| 8962 | <property name="proportion">0</property> | ||
| 8963 | <object class="wxBoxSizer" expanded="1"> | ||
| 8964 | <property name="minimum_size"></property> | ||
| 8965 | <property name="name">bSizer25</property> | ||
| 8966 | <property name="orient">wxHORIZONTAL</property> | ||
| 8967 | <property name="permission">none</property> | ||
| 8968 | <object class="sizeritem" expanded="1"> | ||
| 8969 | <property name="border">5</property> | ||
| 8970 | <property name="flag">wxALL</property> | ||
| 8971 | <property name="proportion">0</property> | ||
| 8972 | <object class="wxButton" expanded="1"> | ||
| 8973 | <property name="bg"></property> | ||
| 8974 | <property name="context_help"></property> | ||
| 8975 | <property name="default">0</property> | ||
| 8976 | <property name="enabled">1</property> | ||
| 8977 | <property name="fg"></property> | ||
| 8978 | <property name="font"></property> | ||
| 8979 | <property name="hidden">0</property> | ||
| 8980 | <property name="id">wxID_ANY</property> | ||
| 8981 | <property name="label">&Add Field</property> | ||
| 8982 | <property name="maximum_size"></property> | ||
| 8983 | <property name="minimum_size"></property> | ||
| 8984 | <property name="name">m_buttonAddField</property> | ||
| 8985 | <property name="permission">protected</property> | ||
| 8986 | <property name="pos"></property> | ||
| 8987 | <property name="size"></property> | ||
| 8988 | <property name="style"></property> | ||
| 8989 | <property name="subclass"></property> | ||
| 8990 | <property name="tooltip"></property> | ||
| 8991 | <property name="window_extra_style"></property> | ||
| 8992 | <property name="window_name"></property> | ||
| 8993 | <property name="window_style"></property> | ||
| 8994 | <event name="OnButtonClick">OnButtonAddField</event> | ||
| 8995 | <event name="OnChar"></event> | ||
| 8996 | <event name="OnEnterWindow"></event> | ||
| 8997 | <event name="OnEraseBackground"></event> | ||
| 8998 | <event name="OnKeyDown"></event> | ||
| 8999 | <event name="OnKeyUp"></event> | ||
| 9000 | <event name="OnKillFocus"></event> | ||
| 9001 | <event name="OnLeaveWindow"></event> | ||
| 9002 | <event name="OnLeftDClick"></event> | ||
| 9003 | <event name="OnLeftDown"></event> | ||
| 9004 | <event name="OnLeftUp"></event> | ||
| 9005 | <event name="OnMiddleDClick"></event> | ||
| 9006 | <event name="OnMiddleDown"></event> | ||
| 9007 | <event name="OnMiddleUp"></event> | ||
| 9008 | <event name="OnMotion"></event> | ||
| 9009 | <event name="OnMouseEvents"></event> | ||
| 9010 | <event name="OnMouseWheel"></event> | ||
| 9011 | <event name="OnPaint"></event> | ||
| 9012 | <event name="OnRightDClick"></event> | ||
| 9013 | <event name="OnRightDown"></event> | ||
| 9014 | <event name="OnRightUp"></event> | ||
| 9015 | <event name="OnSetFocus"></event> | ||
| 9016 | <event name="OnSize"></event> | ||
| 9017 | <event name="OnUpdateUI"></event> | ||
| 9018 | </object> | ||
| 9019 | </object> | ||
| 9020 | </object> | ||
| 9021 | </object> | ||
| 9022 | </object> | ||
| 9023 | </object> | ||
| 9024 | </object> | ||
| 9025 | <object class="sizeritem" expanded="1"> | ||
| 9026 | <property name="border">5</property> | ||
| 9027 | <property name="flag">wxALIGN_RIGHT</property> | ||
| 9028 | <property name="proportion">0</property> | ||
| 9029 | <object class="wxBoxSizer" expanded="1"> | ||
| 9030 | <property name="minimum_size"></property> | ||
| 9031 | <property name="name">bSizer26</property> | ||
| 9032 | <property name="orient">wxHORIZONTAL</property> | ||
| 9033 | <property name="permission">none</property> | ||
| 9034 | <object class="sizeritem" expanded="1"> | ||
| 9035 | <property name="border">5</property> | ||
| 9036 | <property name="flag">wxALL</property> | ||
| 9037 | <property name="proportion">0</property> | ||
| 9038 | <object class="wxButton" expanded="1"> | ||
| 9039 | <property name="bg"></property> | ||
| 9040 | <property name="context_help"></property> | ||
| 9041 | <property name="default">0</property> | ||
| 9042 | <property name="enabled">1</property> | ||
| 9043 | <property name="fg"></property> | ||
| 9044 | <property name="font"></property> | ||
| 9045 | <property name="hidden">0</property> | ||
| 9046 | <property name="id">wxID_BUTTONSEND</property> | ||
| 9047 | <property name="label">&Send</property> | ||
| 9048 | <property name="maximum_size"></property> | ||
| 9049 | <property name="minimum_size">85,25</property> | ||
| 9050 | <property name="name">m_buttonOK</property> | ||
| 9051 | <property name="permission">protected</property> | ||
| 9052 | <property name="pos"></property> | ||
| 9053 | <property name="size"></property> | ||
| 9054 | <property name="style"></property> | ||
| 9055 | <property name="subclass"></property> | ||
| 9056 | <property name="tooltip"></property> | ||
| 9057 | <property name="window_extra_style"></property> | ||
| 9058 | <property name="window_name"></property> | ||
| 9059 | <property name="window_style"></property> | ||
| 9060 | <event name="OnButtonClick">OnButtonSend</event> | ||
| 9061 | <event name="OnChar"></event> | ||
| 9062 | <event name="OnEnterWindow"></event> | ||
| 9063 | <event name="OnEraseBackground"></event> | ||
| 9064 | <event name="OnKeyDown"></event> | ||
| 9065 | <event name="OnKeyUp"></event> | ||
| 9066 | <event name="OnKillFocus"></event> | ||
| 9067 | <event name="OnLeaveWindow"></event> | ||
| 9068 | <event name="OnLeftDClick"></event> | ||
| 9069 | <event name="OnLeftDown"></event> | ||
| 9070 | <event name="OnLeftUp"></event> | ||
| 9071 | <event name="OnMiddleDClick"></event> | ||
| 9072 | <event name="OnMiddleDown"></event> | ||
| 9073 | <event name="OnMiddleUp"></event> | ||
| 9074 | <event name="OnMotion"></event> | ||
| 9075 | <event name="OnMouseEvents"></event> | ||
| 9076 | <event name="OnMouseWheel"></event> | ||
| 9077 | <event name="OnPaint"></event> | ||
| 9078 | <event name="OnRightDClick"></event> | ||
| 9079 | <event name="OnRightDown"></event> | ||
| 9080 | <event name="OnRightUp"></event> | ||
| 9081 | <event name="OnSetFocus"></event> | ||
| 9082 | <event name="OnSize"></event> | ||
| 9083 | <event name="OnUpdateUI"></event> | ||
| 9084 | </object> | ||
| 9085 | </object> | ||
| 9086 | <object class="sizeritem" expanded="1"> | ||
| 9087 | <property name="border">5</property> | ||
| 9088 | <property name="flag">wxALL</property> | ||
| 9089 | <property name="proportion">0</property> | ||
| 9090 | <object class="wxButton" expanded="1"> | ||
| 9091 | <property name="bg"></property> | ||
| 9092 | <property name="context_help"></property> | ||
| 9093 | <property name="default">0</property> | ||
| 9094 | <property name="enabled">1</property> | ||
| 9095 | <property name="fg"></property> | ||
| 9096 | <property name="font"></property> | ||
| 9097 | <property name="hidden">0</property> | ||
| 9098 | <property name="id">wxID_BUTTONPREVIEW</property> | ||
| 9099 | <property name="label">&Preview</property> | ||
| 9100 | <property name="maximum_size"></property> | ||
| 9101 | <property name="minimum_size">85,25</property> | ||
| 9102 | <property name="name">m_buttonPreview</property> | ||
| 9103 | <property name="permission">protected</property> | ||
| 9104 | <property name="pos"></property> | ||
| 9105 | <property name="size"></property> | ||
| 9106 | <property name="style"></property> | ||
| 9107 | <property name="subclass"></property> | ||
| 9108 | <property name="tooltip"></property> | ||
| 9109 | <property name="window_extra_style"></property> | ||
| 9110 | <property name="window_name"></property> | ||
| 9111 | <property name="window_style"></property> | ||
| 9112 | <event name="OnButtonClick">OnButtonPreview</event> | ||
| 9113 | <event name="OnChar"></event> | ||
| 9114 | <event name="OnEnterWindow"></event> | ||
| 9115 | <event name="OnEraseBackground"></event> | ||
| 9116 | <event name="OnKeyDown"></event> | ||
| 9117 | <event name="OnKeyUp"></event> | ||
| 9118 | <event name="OnKillFocus"></event> | ||
| 9119 | <event name="OnLeaveWindow"></event> | ||
| 9120 | <event name="OnLeftDClick"></event> | ||
| 9121 | <event name="OnLeftDown"></event> | ||
| 9122 | <event name="OnLeftUp"></event> | ||
| 9123 | <event name="OnMiddleDClick"></event> | ||
| 9124 | <event name="OnMiddleDown"></event> | ||
| 9125 | <event name="OnMiddleUp"></event> | ||
| 9126 | <event name="OnMotion"></event> | ||
| 9127 | <event name="OnMouseEvents"></event> | ||
| 9128 | <event name="OnMouseWheel"></event> | ||
| 9129 | <event name="OnPaint"></event> | ||
| 9130 | <event name="OnRightDClick"></event> | ||
| 9131 | <event name="OnRightDown"></event> | ||
| 9132 | <event name="OnRightUp"></event> | ||
| 9133 | <event name="OnSetFocus"></event> | ||
| 9134 | <event name="OnSize"></event> | ||
| 9135 | <event name="OnUpdateUI"></event> | ||
| 9136 | </object> | ||
| 9137 | </object> | ||
| 9138 | <object class="sizeritem" expanded="1"> | ||
| 9139 | <property name="border">5</property> | ||
| 9140 | <property name="flag">wxALL</property> | ||
| 9141 | <property name="proportion">0</property> | ||
| 9142 | <object class="wxButton" expanded="1"> | ||
| 9143 | <property name="bg"></property> | ||
| 9144 | <property name="context_help"></property> | ||
| 9145 | <property name="default">0</property> | ||
| 9146 | <property name="enabled">1</property> | ||
| 9147 | <property name="fg"></property> | ||
| 9148 | <property name="font"></property> | ||
| 9149 | <property name="hidden">0</property> | ||
| 9150 | <property name="id">wxID_CANCEL</property> | ||
| 9151 | <property name="label">Cancel</property> | ||
| 9152 | <property name="maximum_size"></property> | ||
| 9153 | <property name="minimum_size">85,25</property> | ||
| 9154 | <property name="name">m_buttonCancel</property> | ||
| 9155 | <property name="permission">protected</property> | ||
| 9156 | <property name="pos"></property> | ||
| 9157 | <property name="size"></property> | ||
| 9158 | <property name="style"></property> | ||
| 9159 | <property name="subclass"></property> | ||
| 9160 | <property name="tooltip"></property> | ||
| 9161 | <property name="window_extra_style"></property> | ||
| 9162 | <property name="window_name"></property> | ||
| 9163 | <property name="window_style"></property> | ||
| 9164 | <event name="OnButtonClick">OnButtonCancel</event> | ||
| 9165 | <event name="OnChar"></event> | ||
| 9166 | <event name="OnEnterWindow"></event> | ||
| 9167 | <event name="OnEraseBackground"></event> | ||
| 9168 | <event name="OnKeyDown"></event> | ||
| 9169 | <event name="OnKeyUp"></event> | ||
| 9170 | <event name="OnKillFocus"></event> | ||
| 9171 | <event name="OnLeaveWindow"></event> | ||
| 9172 | <event name="OnLeftDClick"></event> | ||
| 9173 | <event name="OnLeftDown"></event> | ||
| 9174 | <event name="OnLeftUp"></event> | ||
| 9175 | <event name="OnMiddleDClick"></event> | ||
| 9176 | <event name="OnMiddleDown"></event> | ||
| 9177 | <event name="OnMiddleUp"></event> | ||
| 9178 | <event name="OnMotion"></event> | ||
| 9179 | <event name="OnMouseEvents"></event> | ||
| 9180 | <event name="OnMouseWheel"></event> | ||
| 9181 | <event name="OnPaint"></event> | ||
| 9182 | <event name="OnRightDClick"></event> | ||
| 9183 | <event name="OnRightDown"></event> | ||
| 9184 | <event name="OnRightUp"></event> | ||
| 9185 | <event name="OnSetFocus"></event> | ||
| 9186 | <event name="OnSize"></event> | ||
| 9187 | <event name="OnUpdateUI"></event> | ||
| 9188 | </object> | ||
| 9189 | </object> | ||
| 9190 | </object> | ||
| 9191 | </object> | ||
| 9192 | </object> | ||
| 9193 | </object> | ||
| 9194 | <object class="Frame" expanded="0"> | ||
| 9195 | <property name="bg">wxSYS_COLOUR_MENU</property> | ||
| 9196 | <property name="center"></property> | ||
| 9197 | <property name="context_help"></property> | ||
| 9198 | <property name="enabled">1</property> | ||
| 9199 | <property name="extra_style"></property> | ||
| 9200 | <property name="fg"></property> | ||
| 9201 | <property name="font"></property> | ||
| 9202 | <property name="hidden">0</property> | ||
| 9203 | <property name="id">wxID_ANY</property> | ||
| 9204 | <property name="maximum_size"></property> | ||
| 9205 | <property name="minimum_size"></property> | ||
| 9206 | <property name="name">CViewProductDialogBase</property> | ||
| 9207 | <property name="pos"></property> | ||
| 9208 | <property name="size">630,520</property> | ||
| 9209 | <property name="style">wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER</property> | ||
| 9210 | <property name="subclass"></property> | ||
| 9211 | <property name="title">Order Form</property> | ||
| 9212 | <property name="tooltip"></property> | ||
| 9213 | <property name="window_extra_style"></property> | ||
| 9214 | <property name="window_name"></property> | ||
| 9215 | <property name="window_style">wxTAB_TRAVERSAL</property> | ||
| 9216 | <property name="xrc_skip_sizer">1</property> | ||
| 9217 | <event name="OnActivate"></event> | ||
| 9218 | <event name="OnActivateApp"></event> | ||
| 9219 | <event name="OnChar"></event> | ||
| 9220 | <event name="OnClose"></event> | ||
| 9221 | <event name="OnEnterWindow"></event> | ||
| 9222 | <event name="OnEraseBackground"></event> | ||
| 9223 | <event name="OnHibernate"></event> | ||
| 9224 | <event name="OnIconize"></event> | ||
| 9225 | <event name="OnIdle"></event> | ||
| 9226 | <event name="OnKeyDown"></event> | ||
| 9227 | <event name="OnKeyUp"></event> | ||
| 9228 | <event name="OnKillFocus"></event> | ||
| 9229 | <event name="OnLeaveWindow"></event> | ||
| 9230 | <event name="OnLeftDClick"></event> | ||
| 9231 | <event name="OnLeftDown"></event> | ||
| 9232 | <event name="OnLeftUp"></event> | ||
| 9233 | <event name="OnMiddleDClick"></event> | ||
| 9234 | <event name="OnMiddleDown"></event> | ||
| 9235 | <event name="OnMiddleUp"></event> | ||
| 9236 | <event name="OnMotion"></event> | ||
| 9237 | <event name="OnMouseEvents"></event> | ||
| 9238 | <event name="OnMouseWheel"></event> | ||
| 9239 | <event name="OnPaint"></event> | ||
| 9240 | <event name="OnRightDClick"></event> | ||
| 9241 | <event name="OnRightDown"></event> | ||
| 9242 | <event name="OnRightUp"></event> | ||
| 9243 | <event name="OnSetFocus"></event> | ||
| 9244 | <event name="OnSize"></event> | ||
| 9245 | <event name="OnUpdateUI"></event> | ||
| 9246 | <object class="wxBoxSizer" expanded="1"> | ||
| 9247 | <property name="minimum_size"></property> | ||
| 9248 | <property name="name">bSizer20</property> | ||
| 9249 | <property name="orient">wxVERTICAL</property> | ||
| 9250 | <property name="permission">none</property> | ||
| 9251 | <object class="sizeritem" expanded="1"> | ||
| 9252 | <property name="border">5</property> | ||
| 9253 | <property name="flag">wxEXPAND</property> | ||
| 9254 | <property name="proportion">1</property> | ||
| 9255 | <object class="wxBoxSizer" expanded="1"> | ||
| 9256 | <property name="minimum_size"></property> | ||
| 9257 | <property name="name">bSizer116</property> | ||
| 9258 | <property name="orient">wxHORIZONTAL</property> | ||
| 9259 | <property name="permission">none</property> | ||
| 9260 | <object class="sizeritem" expanded="1"> | ||
| 9261 | <property name="border">5</property> | ||
| 9262 | <property name="flag">wxALL|wxEXPAND</property> | ||
| 9263 | <property name="proportion">1</property> | ||
| 9264 | <object class="wxHtmlWindow" expanded="1"> | ||
| 9265 | <property name="bg"></property> | ||
| 9266 | <property name="context_help"></property> | ||
| 9267 | <property name="enabled">1</property> | ||
| 9268 | <property name="fg"></property> | ||
| 9269 | <property name="font"></property> | ||
| 9270 | <property name="hidden">1</property> | ||
| 9271 | <property name="id">wxID_ANY</property> | ||
| 9272 | <property name="maximum_size"></property> | ||
| 9273 | <property name="minimum_size"></property> | ||
| 9274 | <property name="name">m_htmlWinReviews</property> | ||
| 9275 | <property name="permission">protected</property> | ||
| 9276 | <property name="pos"></property> | ||
| 9277 | <property name="size"></property> | ||
| 9278 | <property name="style">wxHW_SCROLLBAR_AUTO</property> | ||
| 9279 | <property name="subclass"></property> | ||
| 9280 | <property name="tooltip"></property> | ||
| 9281 | <property name="window_extra_style"></property> | ||
| 9282 | <property name="window_name"></property> | ||
| 9283 | <property name="window_style"></property> | ||
| 9284 | <event name="OnChar"></event> | ||
| 9285 | <event name="OnEnterWindow"></event> | ||
| 9286 | <event name="OnEraseBackground"></event> | ||
| 9287 | <event name="OnHtmlCellClicked"></event> | ||
| 9288 | <event name="OnHtmlCellHover"></event> | ||
| 9289 | <event name="OnHtmlLinkClicked"></event> | ||
| 9290 | <event name="OnKeyDown"></event> | ||
| 9291 | <event name="OnKeyUp"></event> | ||
| 9292 | <event name="OnKillFocus"></event> | ||
| 9293 | <event name="OnLeaveWindow"></event> | ||
| 9294 | <event name="OnLeftDClick"></event> | ||
| 9295 | <event name="OnLeftDown"></event> | ||
| 9296 | <event name="OnLeftUp"></event> | ||
| 9297 | <event name="OnMiddleDClick"></event> | ||
| 9298 | <event name="OnMiddleDown"></event> | ||
| 9299 | <event name="OnMiddleUp"></event> | ||
| 9300 | <event name="OnMotion"></event> | ||
| 9301 | <event name="OnMouseEvents"></event> | ||
| 9302 | <event name="OnMouseWheel"></event> | ||
| 9303 | <event name="OnPaint"></event> | ||
| 9304 | <event name="OnRightDClick"></event> | ||
| 9305 | <event name="OnRightDown"></event> | ||
| 9306 | <event name="OnRightUp"></event> | ||
| 9307 | <event name="OnSetFocus"></event> | ||
| 9308 | <event name="OnSize"></event> | ||
| 9309 | <event name="OnUpdateUI"></event> | ||
| 9310 | </object> | ||
| 9311 | </object> | ||
| 9312 | <object class="sizeritem" expanded="1"> | ||
| 9313 | <property name="border">5</property> | ||
| 9314 | <property name="flag">wxEXPAND|wxALL</property> | ||
| 9315 | <property name="proportion">1</property> | ||
| 9316 | <object class="wxScrolledWindow" expanded="1"> | ||
| 9317 | <property name="bg">wxSYS_COLOUR_WINDOW</property> | ||
| 9318 | <property name="context_help"></property> | ||
| 9319 | <property name="enabled">1</property> | ||
| 9320 | <property name="fg"></property> | ||
| 9321 | <property name="font"></property> | ||
| 9322 | <property name="hidden">0</property> | ||
| 9323 | <property name="id">wxID_ANY</property> | ||
| 9324 | <property name="maximum_size"></property> | ||
| 9325 | <property name="minimum_size"></property> | ||
| 9326 | <property name="name">m_scrolledWindow</property> | ||
| 9327 | <property name="permission">protected</property> | ||
| 9328 | <property name="pos"></property> | ||
| 9329 | <property name="scroll_rate_x">5</property> | ||
| 9330 | <property name="scroll_rate_y">5</property> | ||
| 9331 | <property name="size"></property> | ||
| 9332 | <property name="subclass"></property> | ||
| 9333 | <property name="tooltip"></property> | ||
| 9334 | <property name="window_extra_style"></property> | ||
| 9335 | <property name="window_name"></property> | ||
| 9336 | <property name="window_style">wxHSCROLL|wxTAB_TRAVERSAL|wxVSCROLL</property> | ||
| 9337 | <event name="OnChar"></event> | ||
| 9338 | <event name="OnEnterWindow"></event> | ||
| 9339 | <event name="OnEraseBackground"></event> | ||
| 9340 | <event name="OnKeyDown"></event> | ||
| 9341 | <event name="OnKeyUp"></event> | ||
| 9342 | <event name="OnKillFocus"></event> | ||
| 9343 | <event name="OnLeaveWindow"></event> | ||
| 9344 | <event name="OnLeftDClick"></event> | ||
| 9345 | <event name="OnLeftDown"></event> | ||
| 9346 | <event name="OnLeftUp"></event> | ||
| 9347 | <event name="OnMiddleDClick"></event> | ||
| 9348 | <event name="OnMiddleDown"></event> | ||
| 9349 | <event name="OnMiddleUp"></event> | ||
| 9350 | <event name="OnMotion"></event> | ||
| 9351 | <event name="OnMouseEvents"></event> | ||
| 9352 | <event name="OnMouseWheel"></event> | ||
| 9353 | <event name="OnPaint"></event> | ||
| 9354 | <event name="OnRightDClick"></event> | ||
| 9355 | <event name="OnRightDown"></event> | ||
| 9356 | <event name="OnRightUp"></event> | ||
| 9357 | <event name="OnSetFocus"></event> | ||
| 9358 | <event name="OnSize"></event> | ||
| 9359 | <event name="OnUpdateUI"></event> | ||
| 9360 | <object class="wxBoxSizer" expanded="1"> | ||
| 9361 | <property name="minimum_size"></property> | ||
| 9362 | <property name="name">bSizer21</property> | ||
| 9363 | <property name="orient">wxVERTICAL</property> | ||
| 9364 | <property name="permission">none</property> | ||
| 9365 | <object class="sizeritem" expanded="1"> | ||
| 9366 | <property name="border">5</property> | ||
| 9367 | <property name="flag">wxEXPAND</property> | ||
| 9368 | <property name="proportion">0</property> | ||
| 9369 | <object class="wxRichTextCtrl" expanded="1"> | ||
| 9370 | <property name="bg"></property> | ||
| 9371 | <property name="context_help"></property> | ||
| 9372 | <property name="enabled">1</property> | ||
| 9373 | <property name="fg"></property> | ||
| 9374 | <property name="font"></property> | ||
| 9375 | <property name="hidden">0</property> | ||
| 9376 | <property name="id">wxID_ANY</property> | ||
| 9377 | <property name="maximum_size"></property> | ||
| 9378 | <property name="minimum_size">-1,-1</property> | ||
| 9379 | <property name="name">m_richTextHeading</property> | ||
| 9380 | <property name="permission">protected</property> | ||
| 9381 | <property name="pos"></property> | ||
| 9382 | <property name="size">-1,50</property> | ||
| 9383 | <property name="style">wxTE_READONLY</property> | ||
| 9384 | <property name="subclass"></property> | ||
| 9385 | <property name="tooltip"></property> | ||
| 9386 | <property name="window_extra_style"></property> | ||
| 9387 | <property name="window_name"></property> | ||
| 9388 | <property name="window_style">wxNO_BORDER</property> | ||
| 9389 | <event name="OnChar"></event> | ||
| 9390 | <event name="OnEnterWindow"></event> | ||
| 9391 | <event name="OnEraseBackground"></event> | ||
| 9392 | <event name="OnKeyDown"></event> | ||
| 9393 | <event name="OnKeyUp"></event> | ||
| 9394 | <event name="OnKillFocus"></event> | ||
| 9395 | <event name="OnLeaveWindow"></event> | ||
| 9396 | <event name="OnLeftDClick"></event> | ||
| 9397 | <event name="OnLeftDown"></event> | ||
| 9398 | <event name="OnLeftUp"></event> | ||
| 9399 | <event name="OnMiddleDClick"></event> | ||
| 9400 | <event name="OnMiddleDown"></event> | ||
| 9401 | <event name="OnMiddleUp"></event> | ||
| 9402 | <event name="OnMotion"></event> | ||
| 9403 | <event name="OnMouseEvents"></event> | ||
| 9404 | <event name="OnMouseWheel"></event> | ||
| 9405 | <event name="OnPaint"></event> | ||
| 9406 | <event name="OnRichTextCharacter"></event> | ||
| 9407 | <event name="OnRichTextContentDeleted"></event> | ||
| 9408 | <event name="OnRichTextContentInserted"></event> | ||
| 9409 | <event name="OnRichTextDelete"></event> | ||
| 9410 | <event name="OnRichTextReturn"></event> | ||
| 9411 | <event name="OnRichTextStyleChanged"></event> | ||
| 9412 | <event name="OnRichTextStyleSheetChanged"></event> | ||
| 9413 | <event name="OnRichTextStyleSheetReplaced"></event> | ||
| 9414 | <event name="OnRichTextStyleSheetReplacing"></event> | ||
| 9415 | <event name="OnRightDClick"></event> | ||
| 9416 | <event name="OnRightDown"></event> | ||
| 9417 | <event name="OnRightUp"></event> | ||
| 9418 | <event name="OnSetFocus"></event> | ||
| 9419 | <event name="OnSize"></event> | ||
| 9420 | <event name="OnText"></event> | ||
| 9421 | <event name="OnTextEnter"></event> | ||
| 9422 | <event name="OnTextMaxLen"></event> | ||
| 9423 | <event name="OnTextURL"></event> | ||
| 9424 | <event name="OnUpdateUI"></event> | ||
| 9425 | </object> | ||
| 9426 | </object> | ||
| 9427 | <object class="sizeritem" expanded="1"> | ||
| 9428 | <property name="border">5</property> | ||
| 9429 | <property name="flag">wxALL|wxEXPAND</property> | ||
| 9430 | <property name="proportion">0</property> | ||
| 9431 | <object class="wxStaticText" expanded="1"> | ||
| 9432 | <property name="bg"></property> | ||
| 9433 | <property name="context_help"></property> | ||
| 9434 | <property name="enabled">1</property> | ||
| 9435 | <property name="fg"></property> | ||
| 9436 | <property name="font"></property> | ||
| 9437 | <property name="hidden">0</property> | ||
| 9438 | <property name="id">wxID_ANY</property> | ||
| 9439 | <property name="label">Order Form instructions here
multiple lines
1
2
3
4
5
6</property> | ||
| 9440 | <property name="maximum_size"></property> | ||
| 9441 | <property name="minimum_size"></property> | ||
| 9442 | <property name="name">m_staticTextInstructions</property> | ||
| 9443 | <property name="permission">protected</property> | ||
| 9444 | <property name="pos"></property> | ||
| 9445 | <property name="size"></property> | ||
| 9446 | <property name="style"></property> | ||
| 9447 | <property name="subclass"></property> | ||
| 9448 | <property name="tooltip"></property> | ||
| 9449 | <property name="window_extra_style"></property> | ||
| 9450 | <property name="window_name"></property> | ||
| 9451 | <property name="window_style"></property> | ||
| 9452 | <property name="wrap">-1</property> | ||
| 9453 | <event name="OnChar"></event> | ||
| 9454 | <event name="OnEnterWindow"></event> | ||
| 9455 | <event name="OnEraseBackground"></event> | ||
| 9456 | <event name="OnKeyDown"></event> | ||
| 9457 | <event name="OnKeyUp"></event> | ||
| 9458 | <event name="OnKillFocus"></event> | ||
| 9459 | <event name="OnLeaveWindow"></event> | ||
| 9460 | <event name="OnLeftDClick"></event> | ||
| 9461 | <event name="OnLeftDown"></event> | ||
| 9462 | <event name="OnLeftUp"></event> | ||
| 9463 | <event name="OnMiddleDClick"></event> | ||
| 9464 | <event name="OnMiddleDown"></event> | ||
| 9465 | <event name="OnMiddleUp"></event> | ||
| 9466 | <event name="OnMotion"></event> | ||
| 9467 | <event name="OnMouseEvents"></event> | ||
| 9468 | <event name="OnMouseWheel"></event> | ||
| 9469 | <event name="OnPaint"></event> | ||
| 9470 | <event name="OnRightDClick"></event> | ||
| 9471 | <event name="OnRightDown"></event> | ||
| 9472 | <event name="OnRightUp"></event> | ||
| 9473 | <event name="OnSetFocus"></event> | ||
| 9474 | <event name="OnSize"></event> | ||
| 9475 | <event name="OnUpdateUI"></event> | ||
| 9476 | </object> | ||
| 9477 | </object> | ||
| 9478 | <object class="sizeritem" expanded="1"> | ||
| 9479 | <property name="border">5</property> | ||
| 9480 | <property name="flag">wxALIGN_CENTER_HORIZONTAL</property> | ||
| 9481 | <property name="proportion">0</property> | ||
| 9482 | <object class="wxBoxSizer" expanded="1"> | ||
| 9483 | <property name="minimum_size"></property> | ||
| 9484 | <property name="name">bSizer25</property> | ||
| 9485 | <property name="orient">wxHORIZONTAL</property> | ||
| 9486 | <property name="permission">none</property> | ||
| 9487 | <object class="sizeritem" expanded="1"> | ||
| 9488 | <property name="border">5</property> | ||
| 9489 | <property name="flag">wxALL</property> | ||
| 9490 | <property name="proportion">0</property> | ||
| 9491 | <object class="wxButton" expanded="1"> | ||
| 9492 | <property name="bg"></property> | ||
| 9493 | <property name="context_help"></property> | ||
| 9494 | <property name="default">0</property> | ||
| 9495 | <property name="enabled">1</property> | ||
| 9496 | <property name="fg"></property> | ||
| 9497 | <property name="font"></property> | ||
| 9498 | <property name="hidden">0</property> | ||
| 9499 | <property name="id">wxID_BUTTONSAMPLE</property> | ||
| 9500 | <property name="label">&Submit</property> | ||
| 9501 | <property name="maximum_size"></property> | ||
| 9502 | <property name="minimum_size">-1,-1</property> | ||
| 9503 | <property name="name">m_buttonSubmitForm</property> | ||
| 9504 | <property name="permission">protected</property> | ||
| 9505 | <property name="pos"></property> | ||
| 9506 | <property name="size"></property> | ||
| 9507 | <property name="style"></property> | ||
| 9508 | <property name="subclass"></property> | ||
| 9509 | <property name="tooltip"></property> | ||
| 9510 | <property name="window_extra_style"></property> | ||
| 9511 | <property name="window_name"></property> | ||
| 9512 | <property name="window_style"></property> | ||
| 9513 | <event name="OnButtonClick">OnButtonSubmitForm</event> | ||
| 9514 | <event name="OnChar"></event> | ||
| 9515 | <event name="OnEnterWindow"></event> | ||
| 9516 | <event name="OnEraseBackground"></event> | ||
| 9517 | <event name="OnKeyDown"></event> | ||
| 9518 | <event name="OnKeyUp"></event> | ||
| 9519 | <event name="OnKillFocus"></event> | ||
| 9520 | <event name="OnLeaveWindow"></event> | ||
| 9521 | <event name="OnLeftDClick"></event> | ||
| 9522 | <event name="OnLeftDown"></event> | ||
| 9523 | <event name="OnLeftUp"></event> | ||
| 9524 | <event name="OnMiddleDClick"></event> | ||
| 9525 | <event name="OnMiddleDown"></event> | ||
| 9526 | <event name="OnMiddleUp"></event> | ||
| 9527 | <event name="OnMotion"></event> | ||
| 9528 | <event name="OnMouseEvents"></event> | ||
| 9529 | <event name="OnMouseWheel"></event> | ||
| 9530 | <event name="OnPaint"></event> | ||
| 9531 | <event name="OnRightDClick"></event> | ||
| 9532 | <event name="OnRightDown"></event> | ||
| 9533 | <event name="OnRightUp"></event> | ||
| 9534 | <event name="OnSetFocus"></event> | ||
| 9535 | <event name="OnSize"></event> | ||
| 9536 | <event name="OnUpdateUI"></event> | ||
| 9537 | </object> | ||
| 9538 | </object> | ||
| 9539 | <object class="sizeritem" expanded="1"> | ||
| 9540 | <property name="border">5</property> | ||
| 9541 | <property name="flag">wxALL</property> | ||
| 9542 | <property name="proportion">0</property> | ||
| 9543 | <object class="wxButton" expanded="1"> | ||
| 9544 | <property name="bg"></property> | ||
| 9545 | <property name="context_help"></property> | ||
| 9546 | <property name="default">0</property> | ||
| 9547 | <property name="enabled">1</property> | ||
| 9548 | <property name="fg"></property> | ||
| 9549 | <property name="font"></property> | ||
| 9550 | <property name="hidden">0</property> | ||
| 9551 | <property name="id">wxID_CANCEL2</property> | ||
| 9552 | <property name="label">Cancel</property> | ||
| 9553 | <property name="maximum_size"></property> | ||
| 9554 | <property name="minimum_size"></property> | ||
| 9555 | <property name="name">m_buttonCancelForm</property> | ||
| 9556 | <property name="permission">protected</property> | ||
| 9557 | <property name="pos"></property> | ||
| 9558 | <property name="size"></property> | ||
| 9559 | <property name="style"></property> | ||
| 9560 | <property name="subclass"></property> | ||
| 9561 | <property name="tooltip"></property> | ||
| 9562 | <property name="window_extra_style"></property> | ||
| 9563 | <property name="window_name"></property> | ||
| 9564 | <property name="window_style"></property> | ||
| 9565 | <event name="OnButtonClick">OnButtonCancelForm</event> | ||
| 9566 | <event name="OnChar"></event> | ||
| 9567 | <event name="OnEnterWindow"></event> | ||
| 9568 | <event name="OnEraseBackground"></event> | ||
| 9569 | <event name="OnKeyDown"></event> | ||
| 9570 | <event name="OnKeyUp"></event> | ||
| 9571 | <event name="OnKillFocus"></event> | ||
| 9572 | <event name="OnLeaveWindow"></event> | ||
| 9573 | <event name="OnLeftDClick"></event> | ||
| 9574 | <event name="OnLeftDown"></event> | ||
| 9575 | <event name="OnLeftUp"></event> | ||
| 9576 | <event name="OnMiddleDClick"></event> | ||
| 9577 | <event name="OnMiddleDown"></event> | ||
| 9578 | <event name="OnMiddleUp"></event> | ||
| 9579 | <event name="OnMotion"></event> | ||
| 9580 | <event name="OnMouseEvents"></event> | ||
| 9581 | <event name="OnMouseWheel"></event> | ||
| 9582 | <event name="OnPaint"></event> | ||
| 9583 | <event name="OnRightDClick"></event> | ||
| 9584 | <event name="OnRightDown"></event> | ||
| 9585 | <event name="OnRightUp"></event> | ||
| 9586 | <event name="OnSetFocus"></event> | ||
| 9587 | <event name="OnSize"></event> | ||
| 9588 | <event name="OnUpdateUI"></event> | ||
| 9589 | </object> | ||
| 9590 | </object> | ||
| 9591 | </object> | ||
| 9592 | </object> | ||
| 9593 | </object> | ||
| 9594 | </object> | ||
| 9595 | </object> | ||
| 9596 | </object> | ||
| 9597 | </object> | ||
| 9598 | <object class="sizeritem" expanded="1"> | ||
| 9599 | <property name="border">5</property> | ||
| 9600 | <property name="flag">wxALIGN_RIGHT</property> | ||
| 9601 | <property name="proportion">0</property> | ||
| 9602 | <object class="wxBoxSizer" expanded="1"> | ||
| 9603 | <property name="minimum_size"></property> | ||
| 9604 | <property name="name">bSizer26</property> | ||
| 9605 | <property name="orient">wxHORIZONTAL</property> | ||
| 9606 | <property name="permission">none</property> | ||
| 9607 | <object class="sizeritem" expanded="1"> | ||
| 9608 | <property name="border">5</property> | ||
| 9609 | <property name="flag">wxALL</property> | ||
| 9610 | <property name="proportion">0</property> | ||
| 9611 | <object class="wxButton" expanded="1"> | ||
| 9612 | <property name="bg"></property> | ||
| 9613 | <property name="context_help"></property> | ||
| 9614 | <property name="default">0</property> | ||
| 9615 | <property name="enabled">0</property> | ||
| 9616 | <property name="fg"></property> | ||
| 9617 | <property name="font"></property> | ||
| 9618 | <property name="hidden">0</property> | ||
| 9619 | <property name="id">wxID_BUTTONBACK</property> | ||
| 9620 | <property name="label">< &Back </property> | ||
| 9621 | <property name="maximum_size"></property> | ||
| 9622 | <property name="minimum_size">85,25</property> | ||
| 9623 | <property name="name">m_buttonBack</property> | ||
| 9624 | <property name="permission">protected</property> | ||
| 9625 | <property name="pos"></property> | ||
| 9626 | <property name="size"></property> | ||
| 9627 | <property name="style"></property> | ||
| 9628 | <property name="subclass"></property> | ||
| 9629 | <property name="tooltip"></property> | ||
| 9630 | <property name="window_extra_style"></property> | ||
| 9631 | <property name="window_name"></property> | ||
| 9632 | <property name="window_style"></property> | ||
| 9633 | <event name="OnButtonClick">OnButtonBack</event> | ||
| 9634 | <event name="OnChar"></event> | ||
| 9635 | <event name="OnEnterWindow"></event> | ||
| 9636 | <event name="OnEraseBackground"></event> | ||
| 9637 | <event name="OnKeyDown"></event> | ||
| 9638 | <event name="OnKeyUp"></event> | ||
| 9639 | <event name="OnKillFocus"></event> | ||
| 9640 | <event name="OnLeaveWindow"></event> | ||
| 9641 | <event name="OnLeftDClick"></event> | ||
| 9642 | <event name="OnLeftDown"></event> | ||
| 9643 | <event name="OnLeftUp"></event> | ||
| 9644 | <event name="OnMiddleDClick"></event> | ||
| 9645 | <event name="OnMiddleDown"></event> | ||
| 9646 | <event name="OnMiddleUp"></event> | ||
| 9647 | <event name="OnMotion"></event> | ||
| 9648 | <event name="OnMouseEvents"></event> | ||
| 9649 | <event name="OnMouseWheel"></event> | ||
| 9650 | <event name="OnPaint"></event> | ||
| 9651 | <event name="OnRightDClick"></event> | ||
| 9652 | <event name="OnRightDown"></event> | ||
| 9653 | <event name="OnRightUp"></event> | ||
| 9654 | <event name="OnSetFocus"></event> | ||
| 9655 | <event name="OnSize"></event> | ||
| 9656 | <event name="OnUpdateUI"></event> | ||
| 9657 | </object> | ||
| 9658 | </object> | ||
| 9659 | <object class="sizeritem" expanded="1"> | ||
| 9660 | <property name="border">5</property> | ||
| 9661 | <property name="flag">wxALL</property> | ||
| 9662 | <property name="proportion">0</property> | ||
| 9663 | <object class="wxButton" expanded="1"> | ||
| 9664 | <property name="bg"></property> | ||
| 9665 | <property name="context_help"></property> | ||
| 9666 | <property name="default">0</property> | ||
| 9667 | <property name="enabled">1</property> | ||
| 9668 | <property name="fg"></property> | ||
| 9669 | <property name="font"></property> | ||
| 9670 | <property name="hidden">0</property> | ||
| 9671 | <property name="id">wxID_BUTTONNEXT</property> | ||
| 9672 | <property name="label"> &Next ></property> | ||
| 9673 | <property name="maximum_size"></property> | ||
| 9674 | <property name="minimum_size">85,25</property> | ||
| 9675 | <property name="name">m_buttonNext</property> | ||
| 9676 | <property name="permission">protected</property> | ||
| 9677 | <property name="pos"></property> | ||
| 9678 | <property name="size"></property> | ||
| 9679 | <property name="style"></property> | ||
| 9680 | <property name="subclass"></property> | ||
| 9681 | <property name="tooltip"></property> | ||
| 9682 | <property name="window_extra_style"></property> | ||
| 9683 | <property name="window_name"></property> | ||
| 9684 | <property name="window_style"></property> | ||
| 9685 | <event name="OnButtonClick">OnButtonNext</event> | ||
| 9686 | <event name="OnChar"></event> | ||
| 9687 | <event name="OnEnterWindow"></event> | ||
| 9688 | <event name="OnEraseBackground"></event> | ||
| 9689 | <event name="OnKeyDown"></event> | ||
| 9690 | <event name="OnKeyUp"></event> | ||
| 9691 | <event name="OnKillFocus"></event> | ||
| 9692 | <event name="OnLeaveWindow"></event> | ||
| 9693 | <event name="OnLeftDClick"></event> | ||
| 9694 | <event name="OnLeftDown"></event> | ||
| 9695 | <event name="OnLeftUp"></event> | ||
| 9696 | <event name="OnMiddleDClick"></event> | ||
| 9697 | <event name="OnMiddleDown"></event> | ||
| 9698 | <event name="OnMiddleUp"></event> | ||
| 9699 | <event name="OnMotion"></event> | ||
| 9700 | <event name="OnMouseEvents"></event> | ||
| 9701 | <event name="OnMouseWheel"></event> | ||
| 9702 | <event name="OnPaint"></event> | ||
| 9703 | <event name="OnRightDClick"></event> | ||
| 9704 | <event name="OnRightDown"></event> | ||
| 9705 | <event name="OnRightUp"></event> | ||
| 9706 | <event name="OnSetFocus"></event> | ||
| 9707 | <event name="OnSize"></event> | ||
| 9708 | <event name="OnUpdateUI"></event> | ||
| 9709 | </object> | ||
| 9710 | </object> | ||
| 9711 | <object class="sizeritem" expanded="1"> | ||
| 9712 | <property name="border">5</property> | ||
| 9713 | <property name="flag">wxALL</property> | ||
| 9714 | <property name="proportion">0</property> | ||
| 9715 | <object class="wxButton" expanded="1"> | ||
| 9716 | <property name="bg"></property> | ||
| 9717 | <property name="context_help"></property> | ||
| 9718 | <property name="default">0</property> | ||
| 9719 | <property name="enabled">1</property> | ||
| 9720 | <property name="fg"></property> | ||
| 9721 | <property name="font"></property> | ||
| 9722 | <property name="hidden">0</property> | ||
| 9723 | <property name="id">wxID_CANCEL</property> | ||
| 9724 | <property name="label">Cancel</property> | ||
| 9725 | <property name="maximum_size"></property> | ||
| 9726 | <property name="minimum_size">85,25</property> | ||
| 9727 | <property name="name">m_buttonCancel</property> | ||
| 9728 | <property name="permission">protected</property> | ||
| 9729 | <property name="pos"></property> | ||
| 9730 | <property name="size"></property> | ||
| 9731 | <property name="style"></property> | ||
| 9732 | <property name="subclass"></property> | ||
| 9733 | <property name="tooltip"></property> | ||
| 9734 | <property name="window_extra_style"></property> | ||
| 9735 | <property name="window_name"></property> | ||
| 9736 | <property name="window_style"></property> | ||
| 9737 | <event name="OnButtonClick">OnButtonCancel</event> | ||
| 9738 | <event name="OnChar"></event> | ||
| 9739 | <event name="OnEnterWindow"></event> | ||
| 9740 | <event name="OnEraseBackground"></event> | ||
| 9741 | <event name="OnKeyDown"></event> | ||
| 9742 | <event name="OnKeyUp"></event> | ||
| 9743 | <event name="OnKillFocus"></event> | ||
| 9744 | <event name="OnLeaveWindow"></event> | ||
| 9745 | <event name="OnLeftDClick"></event> | ||
| 9746 | <event name="OnLeftDown"></event> | ||
| 9747 | <event name="OnLeftUp"></event> | ||
| 9748 | <event name="OnMiddleDClick"></event> | ||
| 9749 | <event name="OnMiddleDown"></event> | ||
| 9750 | <event name="OnMiddleUp"></event> | ||
| 9751 | <event name="OnMotion"></event> | ||
| 9752 | <event name="OnMouseEvents"></event> | ||
| 9753 | <event name="OnMouseWheel"></event> | ||
| 9754 | <event name="OnPaint"></event> | ||
| 9755 | <event name="OnRightDClick"></event> | ||
| 9756 | <event name="OnRightDown"></event> | ||
| 9757 | <event name="OnRightUp"></event> | ||
| 9758 | <event name="OnSetFocus"></event> | ||
| 9759 | <event name="OnSize"></event> | ||
| 9760 | <event name="OnUpdateUI"></event> | ||
| 9761 | </object> | ||
| 9762 | </object> | ||
| 9763 | </object> | ||
| 9764 | </object> | ||
| 9765 | </object> | ||
| 9766 | </object> | ||
| 9767 | <object class="Frame" expanded="0"> | ||
| 9768 | <property name="bg">wxSYS_COLOUR_MENU</property> | ||
| 9769 | <property name="center"></property> | ||
| 9770 | <property name="context_help"></property> | ||
| 9771 | <property name="enabled">1</property> | ||
| 9772 | <property name="extra_style"></property> | ||
| 9773 | <property name="fg"></property> | ||
| 9774 | <property name="font"></property> | ||
| 9775 | <property name="hidden">0</property> | ||
| 9776 | <property name="id">wxID_ANY</property> | ||
| 9777 | <property name="maximum_size"></property> | ||
| 9778 | <property name="minimum_size"></property> | ||
| 9779 | <property name="name">CViewOrderDialogBase</property> | ||
| 9780 | <property name="pos"></property> | ||
| 9781 | <property name="size">630,520</property> | ||
| 9782 | <property name="style">wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER</property> | ||
| 9783 | <property name="subclass"></property> | ||
| 9784 | <property name="title">View Order</property> | ||
| 9785 | <property name="tooltip"></property> | ||
| 9786 | <property name="window_extra_style"></property> | ||
| 9787 | <property name="window_name"></property> | ||
| 9788 | <property name="window_style">wxTAB_TRAVERSAL</property> | ||
| 9789 | <property name="xrc_skip_sizer">1</property> | ||
| 9790 | <event name="OnActivate"></event> | ||
| 9791 | <event name="OnActivateApp"></event> | ||
| 9792 | <event name="OnChar"></event> | ||
| 9793 | <event name="OnClose"></event> | ||
| 9794 | <event name="OnEnterWindow"></event> | ||
| 9795 | <event name="OnEraseBackground"></event> | ||
| 9796 | <event name="OnHibernate"></event> | ||
| 9797 | <event name="OnIconize"></event> | ||
| 9798 | <event name="OnIdle"></event> | ||
| 9799 | <event name="OnKeyDown"></event> | ||
| 9800 | <event name="OnKeyUp"></event> | ||
| 9801 | <event name="OnKillFocus"></event> | ||
| 9802 | <event name="OnLeaveWindow"></event> | ||
| 9803 | <event name="OnLeftDClick"></event> | ||
| 9804 | <event name="OnLeftDown"></event> | ||
| 9805 | <event name="OnLeftUp"></event> | ||
| 9806 | <event name="OnMiddleDClick"></event> | ||
| 9807 | <event name="OnMiddleDown"></event> | ||
| 9808 | <event name="OnMiddleUp"></event> | ||
| 9809 | <event name="OnMotion"></event> | ||
| 9810 | <event name="OnMouseEvents"></event> | ||
| 9811 | <event name="OnMouseWheel"></event> | ||
| 9812 | <event name="OnPaint"></event> | ||
| 9813 | <event name="OnRightDClick"></event> | ||
| 9814 | <event name="OnRightDown"></event> | ||
| 9815 | <event name="OnRightUp"></event> | ||
| 9816 | <event name="OnSetFocus"></event> | ||
| 9817 | <event name="OnSize"></event> | ||
| 9818 | <event name="OnUpdateUI"></event> | ||
| 9819 | <object class="wxBoxSizer" expanded="1"> | ||
| 9820 | <property name="minimum_size"></property> | ||
| 9821 | <property name="name">bSizer20</property> | ||
| 9822 | <property name="orient">wxVERTICAL</property> | ||
| 9823 | <property name="permission">none</property> | ||
| 9824 | <object class="sizeritem" expanded="1"> | ||
| 9825 | <property name="border">5</property> | ||
| 9826 | <property name="flag">wxEXPAND</property> | ||
| 9827 | <property name="proportion">1</property> | ||
| 9828 | <object class="wxBoxSizer" expanded="1"> | ||
| 9829 | <property name="minimum_size"></property> | ||
| 9830 | <property name="name">bSizer116</property> | ||
| 9831 | <property name="orient">wxHORIZONTAL</property> | ||
| 9832 | <property name="permission">none</property> | ||
| 9833 | <object class="sizeritem" expanded="1"> | ||
| 9834 | <property name="border">5</property> | ||
| 9835 | <property name="flag">wxALL|wxEXPAND</property> | ||
| 9836 | <property name="proportion">1</property> | ||
| 9837 | <object class="wxHtmlWindow" expanded="1"> | ||
| 9838 | <property name="bg"></property> | ||
| 9839 | <property name="context_help"></property> | ||
| 9840 | <property name="enabled">1</property> | ||
| 9841 | <property name="fg"></property> | ||
| 9842 | <property name="font"></property> | ||
| 9843 | <property name="hidden">0</property> | ||
| 9844 | <property name="id">wxID_ANY</property> | ||
| 9845 | <property name="maximum_size"></property> | ||
| 9846 | <property name="minimum_size"></property> | ||
| 9847 | <property name="name">m_htmlWin</property> | ||
| 9848 | <property name="permission">protected</property> | ||
| 9849 | <property name="pos"></property> | ||
| 9850 | <property name="size"></property> | ||
| 9851 | <property name="style">wxHW_SCROLLBAR_AUTO</property> | ||
| 9852 | <property name="subclass"></property> | ||
| 9853 | <property name="tooltip"></property> | ||
| 9854 | <property name="window_extra_style"></property> | ||
| 9855 | <property name="window_name"></property> | ||
| 9856 | <property name="window_style"></property> | ||
| 9857 | <event name="OnChar"></event> | ||
| 9858 | <event name="OnEnterWindow"></event> | ||
| 9859 | <event name="OnEraseBackground"></event> | ||
| 9860 | <event name="OnHtmlCellClicked"></event> | ||
| 9861 | <event name="OnHtmlCellHover"></event> | ||
| 9862 | <event name="OnHtmlLinkClicked"></event> | ||
| 9863 | <event name="OnKeyDown"></event> | ||
| 9864 | <event name="OnKeyUp"></event> | ||
| 9865 | <event name="OnKillFocus"></event> | ||
| 9866 | <event name="OnLeaveWindow"></event> | ||
| 9867 | <event name="OnLeftDClick"></event> | ||
| 9868 | <event name="OnLeftDown"></event> | ||
| 9869 | <event name="OnLeftUp"></event> | ||
| 9870 | <event name="OnMiddleDClick"></event> | ||
| 9871 | <event name="OnMiddleDown"></event> | ||
| 9872 | <event name="OnMiddleUp"></event> | ||
| 9873 | <event name="OnMotion"></event> | ||
| 9874 | <event name="OnMouseEvents"></event> | ||
| 9875 | <event name="OnMouseWheel"></event> | ||
| 9876 | <event name="OnPaint"></event> | ||
| 9877 | <event name="OnRightDClick"></event> | ||
| 9878 | <event name="OnRightDown"></event> | ||
| 9879 | <event name="OnRightUp"></event> | ||
| 9880 | <event name="OnSetFocus"></event> | ||
| 9881 | <event name="OnSize"></event> | ||
| 9882 | <event name="OnUpdateUI"></event> | ||
| 9883 | </object> | ||
| 9884 | </object> | ||
| 9885 | </object> | ||
| 9886 | </object> | ||
| 9887 | <object class="sizeritem" expanded="1"> | ||
| 9888 | <property name="border">5</property> | ||
| 9889 | <property name="flag">wxALIGN_RIGHT</property> | ||
| 9890 | <property name="proportion">0</property> | ||
| 9891 | <object class="wxBoxSizer" expanded="1"> | ||
| 9892 | <property name="minimum_size"></property> | ||
| 9893 | <property name="name">bSizer26</property> | ||
| 9894 | <property name="orient">wxHORIZONTAL</property> | ||
| 9895 | <property name="permission">none</property> | ||
| 9896 | <object class="sizeritem" expanded="1"> | ||
| 9897 | <property name="border">5</property> | ||
| 9898 | <property name="flag">wxALL</property> | ||
| 9899 | <property name="proportion">0</property> | ||
| 9900 | <object class="wxButton" expanded="1"> | ||
| 9901 | <property name="bg"></property> | ||
| 9902 | <property name="context_help"></property> | ||
| 9903 | <property name="default">0</property> | ||
| 9904 | <property name="enabled">1</property> | ||
| 9905 | <property name="fg"></property> | ||
| 9906 | <property name="font"></property> | ||
| 9907 | <property name="hidden">0</property> | ||
| 9908 | <property name="id">wxID_OK</property> | ||
| 9909 | <property name="label">OK</property> | ||
| 9910 | <property name="maximum_size"></property> | ||
| 9911 | <property name="minimum_size">85,25</property> | ||
| 9912 | <property name="name">m_buttonOK</property> | ||
| 9913 | <property name="permission">protected</property> | ||
| 9914 | <property name="pos"></property> | ||
| 9915 | <property name="size"></property> | ||
| 9916 | <property name="style"></property> | ||
| 9917 | <property name="subclass"></property> | ||
| 9918 | <property name="tooltip"></property> | ||
| 9919 | <property name="window_extra_style"></property> | ||
| 9920 | <property name="window_name"></property> | ||
| 9921 | <property name="window_style"></property> | ||
| 9922 | <event name="OnButtonClick">OnButtonOK</event> | ||
| 9923 | <event name="OnChar"></event> | ||
| 9924 | <event name="OnEnterWindow"></event> | ||
| 9925 | <event name="OnEraseBackground"></event> | ||
| 9926 | <event name="OnKeyDown"></event> | ||
| 9927 | <event name="OnKeyUp"></event> | ||
| 9928 | <event name="OnKillFocus"></event> | ||
| 9929 | <event name="OnLeaveWindow"></event> | ||
| 9930 | <event name="OnLeftDClick"></event> | ||
| 9931 | <event name="OnLeftDown"></event> | ||
| 9932 | <event name="OnLeftUp"></event> | ||
| 9933 | <event name="OnMiddleDClick"></event> | ||
| 9934 | <event name="OnMiddleDown"></event> | ||
| 9935 | <event name="OnMiddleUp"></event> | ||
| 9936 | <event name="OnMotion"></event> | ||
| 9937 | <event name="OnMouseEvents"></event> | ||
| 9938 | <event name="OnMouseWheel"></event> | ||
| 9939 | <event name="OnPaint"></event> | ||
| 9940 | <event name="OnRightDClick"></event> | ||
| 9941 | <event name="OnRightDown"></event> | ||
| 9942 | <event name="OnRightUp"></event> | ||
| 9943 | <event name="OnSetFocus"></event> | ||
| 9944 | <event name="OnSize"></event> | ||
| 9945 | <event name="OnUpdateUI"></event> | ||
| 9946 | </object> | ||
| 9947 | </object> | ||
| 9948 | </object> | ||
| 9949 | </object> | ||
| 9950 | </object> | ||
| 9951 | </object> | ||
| 9952 | <object class="Frame" expanded="0"> | ||
| 9953 | <property name="bg">wxSYS_COLOUR_MENU</property> | ||
| 9954 | <property name="center"></property> | ||
| 9955 | <property name="context_help"></property> | ||
| 9956 | <property name="enabled">1</property> | ||
| 9957 | <property name="extra_style"></property> | ||
| 9958 | <property name="fg"></property> | ||
| 9959 | <property name="font"></property> | ||
| 9960 | <property name="hidden">0</property> | ||
| 9961 | <property name="id">wxID_ANY</property> | ||
| 9962 | <property name="maximum_size"></property> | ||
| 9963 | <property name="minimum_size"></property> | ||
| 9964 | <property name="name">CEditReviewDialogBase</property> | ||
| 9965 | <property name="pos"></property> | ||
| 9966 | <property name="size">630,440</property> | ||
| 9967 | <property name="style">wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER</property> | ||
| 9968 | <property name="subclass"></property> | ||
| 9969 | <property name="title">Enter Review</property> | ||
| 9970 | <property name="tooltip"></property> | ||
| 9971 | <property name="window_extra_style"></property> | ||
| 9972 | <property name="window_name"></property> | ||
| 9973 | <property name="window_style">wxTAB_TRAVERSAL</property> | ||
| 9974 | <property name="xrc_skip_sizer">1</property> | ||
| 9975 | <event name="OnActivate"></event> | ||
| 9976 | <event name="OnActivateApp"></event> | ||
| 9977 | <event name="OnChar"></event> | ||
| 9978 | <event name="OnClose"></event> | ||
| 9979 | <event name="OnEnterWindow"></event> | ||
| 9980 | <event name="OnEraseBackground"></event> | ||
| 9981 | <event name="OnHibernate"></event> | ||
| 9982 | <event name="OnIconize"></event> | ||
| 9983 | <event name="OnIdle"></event> | ||
| 9984 | <event name="OnKeyDown"></event> | ||
| 9985 | <event name="OnKeyUp"></event> | ||
| 9986 | <event name="OnKillFocus"></event> | ||
| 9987 | <event name="OnLeaveWindow"></event> | ||
| 9988 | <event name="OnLeftDClick"></event> | ||
| 9989 | <event name="OnLeftDown"></event> | ||
| 9990 | <event name="OnLeftUp"></event> | ||
| 9991 | <event name="OnMiddleDClick"></event> | ||
| 9992 | <event name="OnMiddleDown"></event> | ||
| 9993 | <event name="OnMiddleUp"></event> | ||
| 9994 | <event name="OnMotion"></event> | ||
| 9995 | <event name="OnMouseEvents"></event> | ||
| 9996 | <event name="OnMouseWheel"></event> | ||
| 9997 | <event name="OnPaint"></event> | ||
| 9998 | <event name="OnRightDClick"></event> | ||
| 9999 | <event name="OnRightDown"></event> | ||
| 10000 | <event name="OnRightUp"></event> | ||
| 10001 | <event name="OnSetFocus"></event> | ||
| 10002 | <event name="OnSize"></event> | ||
| 10003 | <event name="OnUpdateUI"></event> | ||
| 10004 | <object class="wxBoxSizer" expanded="1"> | ||
| 10005 | <property name="minimum_size"></property> | ||
| 10006 | <property name="name">bSizer112</property> | ||
| 10007 | <property name="orient">wxVERTICAL</property> | ||
| 10008 | <property name="permission">none</property> | ||
| 10009 | <object class="sizeritem" expanded="1"> | ||
| 10010 | <property name="border">5</property> | ||
| 10011 | <property name="flag"></property> | ||
| 10012 | <property name="proportion">0</property> | ||
| 10013 | <object class="spacer" expanded="1"> | ||
| 10014 | <property name="height">3</property> | ||
| 10015 | <property name="permission">protected</property> | ||
| 10016 | <property name="width">0</property> | ||
| 10017 | </object> | ||
| 10018 | </object> | ||
| 10019 | <object class="sizeritem" expanded="1"> | ||
| 10020 | <property name="border">5</property> | ||
| 10021 | <property name="flag">wxALL|wxEXPAND</property> | ||
| 10022 | <property name="proportion">0</property> | ||
| 10023 | <object class="wxStaticText" expanded="1"> | ||
| 10024 | <property name="bg"></property> | ||
| 10025 | <property name="context_help"></property> | ||
| 10026 | <property name="enabled">1</property> | ||
| 10027 | <property name="fg"></property> | ||
| 10028 | <property name="font"></property> | ||
| 10029 | <property name="hidden">0</property> | ||
| 10030 | <property name="id">wxID_ANY</property> | ||
| 10031 | <property name="label"></property> | ||
| 10032 | <property name="maximum_size"></property> | ||
| 10033 | <property name="minimum_size"></property> | ||
| 10034 | <property name="name">m_staticTextSeller</property> | ||
| 10035 | <property name="permission">protected</property> | ||
| 10036 | <property name="pos"></property> | ||
| 10037 | <property name="size"></property> | ||
| 10038 | <property name="style"></property> | ||
| 10039 | <property name="subclass"></property> | ||
| 10040 | <property name="tooltip"></property> | ||
| 10041 | <property name="window_extra_style"></property> | ||
| 10042 | <property name="window_name"></property> | ||
| 10043 | <property name="window_style"></property> | ||
| 10044 | <property name="wrap">-1</property> | ||
| 10045 | <event name="OnChar"></event> | ||
| 10046 | <event name="OnEnterWindow"></event> | ||
| 10047 | <event name="OnEraseBackground"></event> | ||
| 10048 | <event name="OnKeyDown"></event> | ||
| 10049 | <event name="OnKeyUp"></event> | ||
| 10050 | <event name="OnKillFocus"></event> | ||
| 10051 | <event name="OnLeaveWindow"></event> | ||
| 10052 | <event name="OnLeftDClick"></event> | ||
| 10053 | <event name="OnLeftDown"></event> | ||
| 10054 | <event name="OnLeftUp"></event> | ||
| 10055 | <event name="OnMiddleDClick"></event> | ||
| 10056 | <event name="OnMiddleDown"></event> | ||
| 10057 | <event name="OnMiddleUp"></event> | ||
| 10058 | <event name="OnMotion"></event> | ||
| 10059 | <event name="OnMouseEvents"></event> | ||
| 10060 | <event name="OnMouseWheel"></event> | ||
| 10061 | <event name="OnPaint"></event> | ||
| 10062 | <event name="OnRightDClick"></event> | ||
| 10063 | <event name="OnRightDown"></event> | ||
| 10064 | <event name="OnRightUp"></event> | ||
| 10065 | <event name="OnSetFocus"></event> | ||
| 10066 | <event name="OnSize"></event> | ||
| 10067 | <event name="OnUpdateUI"></event> | ||
| 10068 | </object> | ||
| 10069 | </object> | ||
| 10070 | <object class="sizeritem" expanded="1"> | ||
| 10071 | <property name="border">5</property> | ||
| 10072 | <property name="flag"></property> | ||
| 10073 | <property name="proportion">0</property> | ||
| 10074 | <object class="spacer" expanded="1"> | ||
| 10075 | <property name="height">3</property> | ||
| 10076 | <property name="permission">protected</property> | ||
| 10077 | <property name="width">0</property> | ||
| 10078 | </object> | ||
| 10079 | </object> | ||
| 10080 | <object class="sizeritem" expanded="1"> | ||
| 10081 | <property name="border">5</property> | ||
| 10082 | <property name="flag">wxTOP|wxRIGHT|wxLEFT</property> | ||
| 10083 | <property name="proportion">0</property> | ||
| 10084 | <object class="wxStaticText" expanded="1"> | ||
| 10085 | <property name="bg"></property> | ||
| 10086 | <property name="context_help"></property> | ||
| 10087 | <property name="enabled">1</property> | ||
| 10088 | <property name="fg"></property> | ||
| 10089 | <property name="font"></property> | ||
| 10090 | <property name="hidden">0</property> | ||
| 10091 | <property name="id">wxID_ANY</property> | ||
| 10092 | <property name="label">Rating</property> | ||
| 10093 | <property name="maximum_size"></property> | ||
| 10094 | <property name="minimum_size"></property> | ||
| 10095 | <property name="name">m_staticText110</property> | ||
| 10096 | <property name="permission">protected</property> | ||
| 10097 | <property name="pos"></property> | ||
| 10098 | <property name="size"></property> | ||
| 10099 | <property name="style"></property> | ||
| 10100 | <property name="subclass"></property> | ||
| 10101 | <property name="tooltip"></property> | ||
| 10102 | <property name="window_extra_style"></property> | ||
| 10103 | <property name="window_name"></property> | ||
| 10104 | <property name="window_style"></property> | ||
| 10105 | <property name="wrap">-1</property> | ||
| 10106 | <event name="OnChar"></event> | ||
| 10107 | <event name="OnEnterWindow"></event> | ||
| 10108 | <event name="OnEraseBackground"></event> | ||
| 10109 | <event name="OnKeyDown"></event> | ||
| 10110 | <event name="OnKeyUp"></event> | ||
| 10111 | <event name="OnKillFocus"></event> | ||
| 10112 | <event name="OnLeaveWindow"></event> | ||
| 10113 | <event name="OnLeftDClick"></event> | ||
| 10114 | <event name="OnLeftDown"></event> | ||
| 10115 | <event name="OnLeftUp"></event> | ||
| 10116 | <event name="OnMiddleDClick"></event> | ||
| 10117 | <event name="OnMiddleDown"></event> | ||
| 10118 | <event name="OnMiddleUp"></event> | ||
| 10119 | <event name="OnMotion"></event> | ||
| 10120 | <event name="OnMouseEvents"></event> | ||
| 10121 | <event name="OnMouseWheel"></event> | ||
| 10122 | <event name="OnPaint"></event> | ||
| 10123 | <event name="OnRightDClick"></event> | ||
| 10124 | <event name="OnRightDown"></event> | ||
| 10125 | <event name="OnRightUp"></event> | ||
| 10126 | <event name="OnSetFocus"></event> | ||
| 10127 | <event name="OnSize"></event> | ||
| 10128 | <event name="OnUpdateUI"></event> | ||
| 10129 | </object> | ||
| 10130 | </object> | ||
| 10131 | <object class="sizeritem" expanded="1"> | ||
| 10132 | <property name="border">5</property> | ||
| 10133 | <property name="flag">wxALL</property> | ||
| 10134 | <property name="proportion">0</property> | ||
| 10135 | <object class="wxChoice" expanded="1"> | ||
| 10136 | <property name="bg"></property> | ||
| 10137 | <property name="choices">" 1 star" " 2 stars" " 3 stars" " 4 stars" " 5 stars"</property> | ||
| 10138 | <property name="context_help"></property> | ||
| 10139 | <property name="enabled">1</property> | ||
| 10140 | <property name="fg"></property> | ||
| 10141 | <property name="font"></property> | ||
| 10142 | <property name="hidden">0</property> | ||
| 10143 | <property name="id">wxID_ANY</property> | ||
| 10144 | <property name="maximum_size"></property> | ||
| 10145 | <property name="minimum_size"></property> | ||
| 10146 | <property name="name">m_choiceStars</property> | ||
| 10147 | <property name="permission">protected</property> | ||
| 10148 | <property name="pos"></property> | ||
| 10149 | <property name="selection">0</property> | ||
| 10150 | <property name="size"></property> | ||
| 10151 | <property name="subclass"></property> | ||
| 10152 | <property name="tooltip"></property> | ||
| 10153 | <property name="window_extra_style"></property> | ||
| 10154 | <property name="window_name"></property> | ||
| 10155 | <property name="window_style"></property> | ||
| 10156 | <event name="OnChar"></event> | ||
| 10157 | <event name="OnChoice"></event> | ||
| 10158 | <event name="OnEnterWindow"></event> | ||
| 10159 | <event name="OnEraseBackground"></event> | ||
| 10160 | <event name="OnKeyDown"></event> | ||
| 10161 | <event name="OnKeyUp"></event> | ||
| 10162 | <event name="OnKillFocus"></event> | ||
| 10163 | <event name="OnLeaveWindow"></event> | ||
| 10164 | <event name="OnLeftDClick"></event> | ||
| 10165 | <event name="OnLeftDown"></event> | ||
| 10166 | <event name="OnLeftUp"></event> | ||
| 10167 | <event name="OnMiddleDClick"></event> | ||
| 10168 | <event name="OnMiddleDown"></event> | ||
| 10169 | <event name="OnMiddleUp"></event> | ||
| 10170 | <event name="OnMotion"></event> | ||
| 10171 | <event name="OnMouseEvents"></event> | ||
| 10172 | <event name="OnMouseWheel"></event> | ||
| 10173 | <event name="OnPaint"></event> | ||
| 10174 | <event name="OnRightDClick"></event> | ||
| 10175 | <event name="OnRightDown"></event> | ||
| 10176 | <event name="OnRightUp"></event> | ||
| 10177 | <event name="OnSetFocus"></event> | ||
| 10178 | <event name="OnSize"></event> | ||
| 10179 | <event name="OnUpdateUI"></event> | ||
| 10180 | </object> | ||
| 10181 | </object> | ||
| 10182 | <object class="sizeritem" expanded="1"> | ||
| 10183 | <property name="border">5</property> | ||
| 10184 | <property name="flag">wxTOP|wxRIGHT|wxLEFT</property> | ||
| 10185 | <property name="proportion">0</property> | ||
| 10186 | <object class="wxStaticText" expanded="1"> | ||
| 10187 | <property name="bg"></property> | ||
| 10188 | <property name="context_help"></property> | ||
| 10189 | <property name="enabled">1</property> | ||
| 10190 | <property name="fg"></property> | ||
| 10191 | <property name="font"></property> | ||
| 10192 | <property name="hidden">0</property> | ||
| 10193 | <property name="id">wxID_ANY</property> | ||
| 10194 | <property name="label">Review</property> | ||
| 10195 | <property name="maximum_size"></property> | ||
| 10196 | <property name="minimum_size"></property> | ||
| 10197 | <property name="name">m_staticText43</property> | ||
| 10198 | <property name="permission">protected</property> | ||
| 10199 | <property name="pos"></property> | ||
| 10200 | <property name="size"></property> | ||
| 10201 | <property name="style"></property> | ||
| 10202 | <property name="subclass"></property> | ||
| 10203 | <property name="tooltip"></property> | ||
| 10204 | <property name="window_extra_style"></property> | ||
| 10205 | <property name="window_name"></property> | ||
| 10206 | <property name="window_style"></property> | ||
| 10207 | <property name="wrap">-1</property> | ||
| 10208 | <event name="OnChar"></event> | ||
| 10209 | <event name="OnEnterWindow"></event> | ||
| 10210 | <event name="OnEraseBackground"></event> | ||
| 10211 | <event name="OnKeyDown"></event> | ||
| 10212 | <event name="OnKeyUp"></event> | ||
| 10213 | <event name="OnKillFocus"></event> | ||
| 10214 | <event name="OnLeaveWindow"></event> | ||
| 10215 | <event name="OnLeftDClick"></event> | ||
| 10216 | <event name="OnLeftDown"></event> | ||
| 10217 | <event name="OnLeftUp"></event> | ||
| 10218 | <event name="OnMiddleDClick"></event> | ||
| 10219 | <event name="OnMiddleDown"></event> | ||
| 10220 | <event name="OnMiddleUp"></event> | ||
| 10221 | <event name="OnMotion"></event> | ||
| 10222 | <event name="OnMouseEvents"></event> | ||
| 10223 | <event name="OnMouseWheel"></event> | ||
| 10224 | <event name="OnPaint"></event> | ||
| 10225 | <event name="OnRightDClick"></event> | ||
| 10226 | <event name="OnRightDown"></event> | ||
| 10227 | <event name="OnRightUp"></event> | ||
| 10228 | <event name="OnSetFocus"></event> | ||
| 10229 | <event name="OnSize"></event> | ||
| 10230 | <event name="OnUpdateUI"></event> | ||
| 10231 | </object> | ||
| 10232 | </object> | ||
| 10233 | <object class="sizeritem" expanded="1"> | ||
| 10234 | <property name="border">5</property> | ||
| 10235 | <property name="flag">wxALL|wxEXPAND</property> | ||
| 10236 | <property name="proportion">1</property> | ||
| 10237 | <object class="wxTextCtrl" expanded="1"> | ||
| 10238 | <property name="bg"></property> | ||
| 10239 | <property name="context_help"></property> | ||
| 10240 | <property name="enabled">1</property> | ||
| 10241 | <property name="fg"></property> | ||
| 10242 | <property name="font"></property> | ||
| 10243 | <property name="hidden">0</property> | ||
| 10244 | <property name="id">wxID_ANY</property> | ||
| 10245 | <property name="maximum_size"></property> | ||
| 10246 | <property name="maxlength">0</property> | ||
| 10247 | <property name="minimum_size"></property> | ||
| 10248 | <property name="name">m_textCtrlReview</property> | ||
| 10249 | <property name="permission">protected</property> | ||
| 10250 | <property name="pos"></property> | ||
| 10251 | <property name="size"></property> | ||
| 10252 | <property name="style">wxTE_MULTILINE</property> | ||
| 10253 | <property name="subclass"></property> | ||
| 10254 | <property name="tooltip"></property> | ||
| 10255 | <property name="value"></property> | ||
| 10256 | <property name="window_extra_style"></property> | ||
| 10257 | <property name="window_name"></property> | ||
| 10258 | <property name="window_style"></property> | ||
| 10259 | <event name="OnChar"></event> | ||
| 10260 | <event name="OnEnterWindow"></event> | ||
| 10261 | <event name="OnEraseBackground"></event> | ||
| 10262 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 10263 | <event name="OnKeyUp"></event> | ||
| 10264 | <event name="OnKillFocus"></event> | ||
| 10265 | <event name="OnLeaveWindow"></event> | ||
| 10266 | <event name="OnLeftDClick"></event> | ||
| 10267 | <event name="OnLeftDown"></event> | ||
| 10268 | <event name="OnLeftUp"></event> | ||
| 10269 | <event name="OnMiddleDClick"></event> | ||
| 10270 | <event name="OnMiddleDown"></event> | ||
| 10271 | <event name="OnMiddleUp"></event> | ||
| 10272 | <event name="OnMotion"></event> | ||
| 10273 | <event name="OnMouseEvents"></event> | ||
| 10274 | <event name="OnMouseWheel"></event> | ||
| 10275 | <event name="OnPaint"></event> | ||
| 10276 | <event name="OnRightDClick"></event> | ||
| 10277 | <event name="OnRightDown"></event> | ||
| 10278 | <event name="OnRightUp"></event> | ||
| 10279 | <event name="OnSetFocus"></event> | ||
| 10280 | <event name="OnSize"></event> | ||
| 10281 | <event name="OnText"></event> | ||
| 10282 | <event name="OnTextEnter"></event> | ||
| 10283 | <event name="OnTextMaxLen"></event> | ||
| 10284 | <event name="OnTextURL"></event> | ||
| 10285 | <event name="OnUpdateUI"></event> | ||
| 10286 | </object> | ||
| 10287 | </object> | ||
| 10288 | <object class="sizeritem" expanded="1"> | ||
| 10289 | <property name="border">5</property> | ||
| 10290 | <property name="flag">wxALIGN_RIGHT</property> | ||
| 10291 | <property name="proportion">0</property> | ||
| 10292 | <object class="wxBoxSizer" expanded="1"> | ||
| 10293 | <property name="minimum_size"></property> | ||
| 10294 | <property name="name">bSizer113</property> | ||
| 10295 | <property name="orient">wxHORIZONTAL</property> | ||
| 10296 | <property name="permission">none</property> | ||
| 10297 | <object class="sizeritem" expanded="1"> | ||
| 10298 | <property name="border">5</property> | ||
| 10299 | <property name="flag">wxALL</property> | ||
| 10300 | <property name="proportion">0</property> | ||
| 10301 | <object class="wxButton" expanded="1"> | ||
| 10302 | <property name="bg"></property> | ||
| 10303 | <property name="context_help"></property> | ||
| 10304 | <property name="default">0</property> | ||
| 10305 | <property name="enabled">1</property> | ||
| 10306 | <property name="fg"></property> | ||
| 10307 | <property name="font"></property> | ||
| 10308 | <property name="hidden">0</property> | ||
| 10309 | <property name="id">wxID_SUBMIT</property> | ||
| 10310 | <property name="label">&Submit</property> | ||
| 10311 | <property name="maximum_size"></property> | ||
| 10312 | <property name="minimum_size">85,25</property> | ||
| 10313 | <property name="name">m_buttonSubmit</property> | ||
| 10314 | <property name="permission">protected</property> | ||
| 10315 | <property name="pos"></property> | ||
| 10316 | <property name="size"></property> | ||
| 10317 | <property name="style"></property> | ||
| 10318 | <property name="subclass"></property> | ||
| 10319 | <property name="tooltip"></property> | ||
| 10320 | <property name="window_extra_style"></property> | ||
| 10321 | <property name="window_name"></property> | ||
| 10322 | <property name="window_style"></property> | ||
| 10323 | <event name="OnButtonClick">OnButtonSubmit</event> | ||
| 10324 | <event name="OnChar"></event> | ||
| 10325 | <event name="OnEnterWindow"></event> | ||
| 10326 | <event name="OnEraseBackground"></event> | ||
| 10327 | <event name="OnKeyDown"></event> | ||
| 10328 | <event name="OnKeyUp"></event> | ||
| 10329 | <event name="OnKillFocus"></event> | ||
| 10330 | <event name="OnLeaveWindow"></event> | ||
| 10331 | <event name="OnLeftDClick"></event> | ||
| 10332 | <event name="OnLeftDown"></event> | ||
| 10333 | <event name="OnLeftUp"></event> | ||
| 10334 | <event name="OnMiddleDClick"></event> | ||
| 10335 | <event name="OnMiddleDown"></event> | ||
| 10336 | <event name="OnMiddleUp"></event> | ||
| 10337 | <event name="OnMotion"></event> | ||
| 10338 | <event name="OnMouseEvents"></event> | ||
| 10339 | <event name="OnMouseWheel"></event> | ||
| 10340 | <event name="OnPaint"></event> | ||
| 10341 | <event name="OnRightDClick"></event> | ||
| 10342 | <event name="OnRightDown"></event> | ||
| 10343 | <event name="OnRightUp"></event> | ||
| 10344 | <event name="OnSetFocus"></event> | ||
| 10345 | <event name="OnSize"></event> | ||
| 10346 | <event name="OnUpdateUI"></event> | ||
| 10347 | </object> | ||
| 10348 | </object> | ||
| 10349 | <object class="sizeritem" expanded="1"> | ||
| 10350 | <property name="border">5</property> | ||
| 10351 | <property name="flag">wxALL</property> | ||
| 10352 | <property name="proportion">0</property> | ||
| 10353 | <object class="wxButton" expanded="1"> | ||
| 10354 | <property name="bg"></property> | ||
| 10355 | <property name="context_help"></property> | ||
| 10356 | <property name="default">0</property> | ||
| 10357 | <property name="enabled">1</property> | ||
| 10358 | <property name="fg"></property> | ||
| 10359 | <property name="font"></property> | ||
| 10360 | <property name="hidden">0</property> | ||
| 10361 | <property name="id">wxID_CANCEL</property> | ||
| 10362 | <property name="label">Cancel</property> | ||
| 10363 | <property name="maximum_size"></property> | ||
| 10364 | <property name="minimum_size">85,25</property> | ||
| 10365 | <property name="name">m_buttonCancel</property> | ||
| 10366 | <property name="permission">protected</property> | ||
| 10367 | <property name="pos"></property> | ||
| 10368 | <property name="size"></property> | ||
| 10369 | <property name="style"></property> | ||
| 10370 | <property name="subclass"></property> | ||
| 10371 | <property name="tooltip"></property> | ||
| 10372 | <property name="window_extra_style"></property> | ||
| 10373 | <property name="window_name"></property> | ||
| 10374 | <property name="window_style"></property> | ||
| 10375 | <event name="OnButtonClick">OnButtonCancel</event> | ||
| 10376 | <event name="OnChar"></event> | ||
| 10377 | <event name="OnEnterWindow"></event> | ||
| 10378 | <event name="OnEraseBackground"></event> | ||
| 10379 | <event name="OnKeyDown"></event> | ||
| 10380 | <event name="OnKeyUp"></event> | ||
| 10381 | <event name="OnKillFocus"></event> | ||
| 10382 | <event name="OnLeaveWindow"></event> | ||
| 10383 | <event name="OnLeftDClick"></event> | ||
| 10384 | <event name="OnLeftDown"></event> | ||
| 10385 | <event name="OnLeftUp"></event> | ||
| 10386 | <event name="OnMiddleDClick"></event> | ||
| 10387 | <event name="OnMiddleDown"></event> | ||
| 10388 | <event name="OnMiddleUp"></event> | ||
| 10389 | <event name="OnMotion"></event> | ||
| 10390 | <event name="OnMouseEvents"></event> | ||
| 10391 | <event name="OnMouseWheel"></event> | ||
| 10392 | <event name="OnPaint"></event> | ||
| 10393 | <event name="OnRightDClick"></event> | ||
| 10394 | <event name="OnRightDown"></event> | ||
| 10395 | <event name="OnRightUp"></event> | ||
| 10396 | <event name="OnSetFocus"></event> | ||
| 10397 | <event name="OnSize"></event> | ||
| 10398 | <event name="OnUpdateUI"></event> | ||
| 10399 | </object> | ||
| 10400 | </object> | ||
| 10401 | </object> | ||
| 10402 | </object> | ||
| 10403 | </object> | ||
| 10404 | </object> | ||
| 10405 | <object class="Frame" expanded="0"> | ||
| 10406 | <property name="bg">wxSYS_COLOUR_BTNFACE</property> | ||
| 10407 | <property name="center"></property> | ||
| 10408 | <property name="context_help"></property> | ||
| 10409 | <property name="enabled">1</property> | ||
| 10410 | <property name="extra_style"></property> | ||
| 10411 | <property name="fg"></property> | ||
| 10412 | <property name="font"></property> | ||
| 10413 | <property name="hidden">0</property> | ||
| 10414 | <property name="id">wxID_ANY</property> | ||
| 10415 | <property name="maximum_size"></property> | ||
| 10416 | <property name="minimum_size"></property> | ||
| 10417 | <property name="name">CPokerLobbyDialogBase</property> | ||
| 10418 | <property name="pos"></property> | ||
| 10419 | <property name="size">586,457</property> | ||
| 10420 | <property name="style">wxDEFAULT_FRAME_STYLE</property> | ||
| 10421 | <property name="subclass"></property> | ||
| 10422 | <property name="title">Poker Lobby</property> | ||
| 10423 | <property name="tooltip"></property> | ||
| 10424 | <property name="window_extra_style"></property> | ||
| 10425 | <property name="window_name"></property> | ||
| 10426 | <property name="window_style">wxTAB_TRAVERSAL</property> | ||
| 10427 | <property name="xrc_skip_sizer">1</property> | ||
| 10428 | <event name="OnActivate"></event> | ||
| 10429 | <event name="OnActivateApp"></event> | ||
| 10430 | <event name="OnChar"></event> | ||
| 10431 | <event name="OnClose"></event> | ||
| 10432 | <event name="OnEnterWindow"></event> | ||
| 10433 | <event name="OnEraseBackground"></event> | ||
| 10434 | <event name="OnHibernate"></event> | ||
| 10435 | <event name="OnIconize"></event> | ||
| 10436 | <event name="OnIdle"></event> | ||
| 10437 | <event name="OnKeyDown"></event> | ||
| 10438 | <event name="OnKeyUp"></event> | ||
| 10439 | <event name="OnKillFocus"></event> | ||
| 10440 | <event name="OnLeaveWindow"></event> | ||
| 10441 | <event name="OnLeftDClick"></event> | ||
| 10442 | <event name="OnLeftDown"></event> | ||
| 10443 | <event name="OnLeftUp"></event> | ||
| 10444 | <event name="OnMiddleDClick"></event> | ||
| 10445 | <event name="OnMiddleDown"></event> | ||
| 10446 | <event name="OnMiddleUp"></event> | ||
| 10447 | <event name="OnMotion"></event> | ||
| 10448 | <event name="OnMouseEvents"></event> | ||
| 10449 | <event name="OnMouseWheel"></event> | ||
| 10450 | <event name="OnPaint"></event> | ||
| 10451 | <event name="OnRightDClick"></event> | ||
| 10452 | <event name="OnRightDown"></event> | ||
| 10453 | <event name="OnRightUp"></event> | ||
| 10454 | <event name="OnSetFocus"></event> | ||
| 10455 | <event name="OnSize"></event> | ||
| 10456 | <event name="OnUpdateUI"></event> | ||
| 10457 | <object class="wxBoxSizer" expanded="1"> | ||
| 10458 | <property name="minimum_size"></property> | ||
| 10459 | <property name="name">bSizer156</property> | ||
| 10460 | <property name="orient">wxHORIZONTAL</property> | ||
| 10461 | <property name="permission">none</property> | ||
| 10462 | <object class="sizeritem" expanded="1"> | ||
| 10463 | <property name="border">5</property> | ||
| 10464 | <property name="flag">wxEXPAND|wxTOP|wxBOTTOM|wxLEFT</property> | ||
| 10465 | <property name="proportion">0</property> | ||
| 10466 | <object class="wxTreeCtrl" expanded="1"> | ||
| 10467 | <property name="bg"></property> | ||
| 10468 | <property name="context_help"></property> | ||
| 10469 | <property name="enabled">1</property> | ||
| 10470 | <property name="fg"></property> | ||
| 10471 | <property name="font"></property> | ||
| 10472 | <property name="hidden">0</property> | ||
| 10473 | <property name="id">wxID_ANY</property> | ||
| 10474 | <property name="maximum_size"></property> | ||
| 10475 | <property name="minimum_size">130,-1</property> | ||
| 10476 | <property name="name">m_treeCtrl</property> | ||
| 10477 | <property name="permission">protected</property> | ||
| 10478 | <property name="pos"></property> | ||
| 10479 | <property name="size"></property> | ||
| 10480 | <property name="style">wxTR_HAS_BUTTONS|wxTR_HIDE_ROOT|wxTR_LINES_AT_ROOT</property> | ||
| 10481 | <property name="subclass"></property> | ||
| 10482 | <property name="tooltip"></property> | ||
| 10483 | <property name="window_extra_style"></property> | ||
| 10484 | <property name="window_name"></property> | ||
| 10485 | <property name="window_style"></property> | ||
| 10486 | <event name="OnChar"></event> | ||
| 10487 | <event name="OnEnterWindow"></event> | ||
| 10488 | <event name="OnEraseBackground"></event> | ||
| 10489 | <event name="OnKeyDown"></event> | ||
| 10490 | <event name="OnKeyUp"></event> | ||
| 10491 | <event name="OnKillFocus"></event> | ||
| 10492 | <event name="OnLeaveWindow"></event> | ||
| 10493 | <event name="OnLeftDClick"></event> | ||
| 10494 | <event name="OnLeftDown"></event> | ||
| 10495 | <event name="OnLeftUp"></event> | ||
| 10496 | <event name="OnMiddleDClick"></event> | ||
| 10497 | <event name="OnMiddleDown"></event> | ||
| 10498 | <event name="OnMiddleUp"></event> | ||
| 10499 | <event name="OnMotion"></event> | ||
| 10500 | <event name="OnMouseEvents"></event> | ||
| 10501 | <event name="OnMouseWheel"></event> | ||
| 10502 | <event name="OnPaint"></event> | ||
| 10503 | <event name="OnRightDClick"></event> | ||
| 10504 | <event name="OnRightDown"></event> | ||
| 10505 | <event name="OnRightUp"></event> | ||
| 10506 | <event name="OnSetFocus"></event> | ||
| 10507 | <event name="OnSize"></event> | ||
| 10508 | <event name="OnTreeBeginDrag"></event> | ||
| 10509 | <event name="OnTreeBeginLabelEdit"></event> | ||
| 10510 | <event name="OnTreeBeginRDrag"></event> | ||
| 10511 | <event name="OnTreeDeleteItem"></event> | ||
| 10512 | <event name="OnTreeEndDrag"></event> | ||
| 10513 | <event name="OnTreeEndLabelEdit"></event> | ||
| 10514 | <event name="OnTreeGetInfo"></event> | ||
| 10515 | <event name="OnTreeItemActivated"></event> | ||
| 10516 | <event name="OnTreeItemCollapsed"></event> | ||
| 10517 | <event name="OnTreeItemCollapsing"></event> | ||
| 10518 | <event name="OnTreeItemExpanded"></event> | ||
| 10519 | <event name="OnTreeItemExpanding"></event> | ||
| 10520 | <event name="OnTreeItemGetTooltip"></event> | ||
| 10521 | <event name="OnTreeItemMenu"></event> | ||
| 10522 | <event name="OnTreeItemMiddleClick"></event> | ||
| 10523 | <event name="OnTreeItemRightClick"></event> | ||
| 10524 | <event name="OnTreeKeyDown"></event> | ||
| 10525 | <event name="OnTreeSelChanged">OnTreeSelChanged</event> | ||
| 10526 | <event name="OnTreeSelChanging"></event> | ||
| 10527 | <event name="OnTreeSetInfo"></event> | ||
| 10528 | <event name="OnTreeStateImageClick"></event> | ||
| 10529 | <event name="OnUpdateUI"></event> | ||
| 10530 | </object> | ||
| 10531 | </object> | ||
| 10532 | <object class="sizeritem" expanded="1"> | ||
| 10533 | <property name="border">5</property> | ||
| 10534 | <property name="flag">wxEXPAND</property> | ||
| 10535 | <property name="proportion">1</property> | ||
| 10536 | <object class="wxBoxSizer" expanded="1"> | ||
| 10537 | <property name="minimum_size"></property> | ||
| 10538 | <property name="name">bSizer172</property> | ||
| 10539 | <property name="orient">wxVERTICAL</property> | ||
| 10540 | <property name="permission">none</property> | ||
| 10541 | <object class="sizeritem" expanded="1"> | ||
| 10542 | <property name="border">5</property> | ||
| 10543 | <property name="flag">wxEXPAND|wxALL</property> | ||
| 10544 | <property name="proportion">1</property> | ||
| 10545 | <object class="wxListCtrl" expanded="1"> | ||
| 10546 | <property name="bg"></property> | ||
| 10547 | <property name="context_help"></property> | ||
| 10548 | <property name="enabled">1</property> | ||
| 10549 | <property name="fg"></property> | ||
| 10550 | <property name="font"></property> | ||
| 10551 | <property name="hidden">0</property> | ||
| 10552 | <property name="id">wxID_ANY</property> | ||
| 10553 | <property name="maximum_size"></property> | ||
| 10554 | <property name="minimum_size"></property> | ||
| 10555 | <property name="name">m_listCtrl</property> | ||
| 10556 | <property name="permission">protected</property> | ||
| 10557 | <property name="pos"></property> | ||
| 10558 | <property name="size"></property> | ||
| 10559 | <property name="style">wxLC_NO_SORT_HEADER|wxLC_REPORT</property> | ||
| 10560 | <property name="subclass"></property> | ||
| 10561 | <property name="tooltip"></property> | ||
| 10562 | <property name="window_extra_style"></property> | ||
| 10563 | <property name="window_name"></property> | ||
| 10564 | <property name="window_style"></property> | ||
| 10565 | <event name="OnChar"></event> | ||
| 10566 | <event name="OnEnterWindow"></event> | ||
| 10567 | <event name="OnEraseBackground"></event> | ||
| 10568 | <event name="OnKeyDown"></event> | ||
| 10569 | <event name="OnKeyUp"></event> | ||
| 10570 | <event name="OnKillFocus"></event> | ||
| 10571 | <event name="OnLeaveWindow"></event> | ||
| 10572 | <event name="OnLeftDClick"></event> | ||
| 10573 | <event name="OnLeftDown"></event> | ||
| 10574 | <event name="OnLeftUp"></event> | ||
| 10575 | <event name="OnListBeginDrag"></event> | ||
| 10576 | <event name="OnListBeginLabelEdit"></event> | ||
| 10577 | <event name="OnListBeginRDrag"></event> | ||
| 10578 | <event name="OnListCacheHint"></event> | ||
| 10579 | <event name="OnListColBeginDrag"></event> | ||
| 10580 | <event name="OnListColClick"></event> | ||
| 10581 | <event name="OnListColDragging"></event> | ||
| 10582 | <event name="OnListColEndDrag"></event> | ||
| 10583 | <event name="OnListColRightClick"></event> | ||
| 10584 | <event name="OnListDeleteAllItems"></event> | ||
| 10585 | <event name="OnListDeleteItem"></event> | ||
| 10586 | <event name="OnListEndLabelEdit"></event> | ||
| 10587 | <event name="OnListInsertItem"></event> | ||
| 10588 | <event name="OnListItemActivated">OnListItemActivated</event> | ||
| 10589 | <event name="OnListItemDeselected"></event> | ||
| 10590 | <event name="OnListItemFocused"></event> | ||
| 10591 | <event name="OnListItemMiddleClick"></event> | ||
| 10592 | <event name="OnListItemRightClick"></event> | ||
| 10593 | <event name="OnListItemSelected">OnListItemSelected</event> | ||
| 10594 | <event name="OnListKeyDown"></event> | ||
| 10595 | <event name="OnMiddleDClick"></event> | ||
| 10596 | <event name="OnMiddleDown"></event> | ||
| 10597 | <event name="OnMiddleUp"></event> | ||
| 10598 | <event name="OnMotion"></event> | ||
| 10599 | <event name="OnMouseEvents"></event> | ||
| 10600 | <event name="OnMouseWheel"></event> | ||
| 10601 | <event name="OnPaint"></event> | ||
| 10602 | <event name="OnRightDClick"></event> | ||
| 10603 | <event name="OnRightDown"></event> | ||
| 10604 | <event name="OnRightUp"></event> | ||
| 10605 | <event name="OnSetFocus"></event> | ||
| 10606 | <event name="OnSize"></event> | ||
| 10607 | <event name="OnUpdateUI"></event> | ||
| 10608 | </object> | ||
| 10609 | </object> | ||
| 10610 | <object class="sizeritem" expanded="1"> | ||
| 10611 | <property name="border">5</property> | ||
| 10612 | <property name="flag">wxALL</property> | ||
| 10613 | <property name="proportion">0</property> | ||
| 10614 | <object class="wxButton" expanded="1"> | ||
| 10615 | <property name="bg"></property> | ||
| 10616 | <property name="context_help"></property> | ||
| 10617 | <property name="default">0</property> | ||
| 10618 | <property name="enabled">1</property> | ||
| 10619 | <property name="fg"></property> | ||
| 10620 | <property name="font"></property> | ||
| 10621 | <property name="hidden">0</property> | ||
| 10622 | <property name="id">wxID_OPENNEWTABLE</property> | ||
| 10623 | <property name="label">&Open New Table</property> | ||
| 10624 | <property name="maximum_size"></property> | ||
| 10625 | <property name="minimum_size"></property> | ||
| 10626 | <property name="name">m_buttonNewTable</property> | ||
| 10627 | <property name="permission">protected</property> | ||
| 10628 | <property name="pos"></property> | ||
| 10629 | <property name="size"></property> | ||
| 10630 | <property name="style"></property> | ||
| 10631 | <property name="subclass"></property> | ||
| 10632 | <property name="tooltip"></property> | ||
| 10633 | <property name="window_extra_style"></property> | ||
| 10634 | <property name="window_name"></property> | ||
| 10635 | <property name="window_style"></property> | ||
| 10636 | <event name="OnButtonClick">OnButtonNewTable</event> | ||
| 10637 | <event name="OnChar"></event> | ||
| 10638 | <event name="OnEnterWindow"></event> | ||
| 10639 | <event name="OnEraseBackground"></event> | ||
| 10640 | <event name="OnKeyDown"></event> | ||
| 10641 | <event name="OnKeyUp"></event> | ||
| 10642 | <event name="OnKillFocus"></event> | ||
| 10643 | <event name="OnLeaveWindow"></event> | ||
| 10644 | <event name="OnLeftDClick"></event> | ||
| 10645 | <event name="OnLeftDown"></event> | ||
| 10646 | <event name="OnLeftUp"></event> | ||
| 10647 | <event name="OnMiddleDClick"></event> | ||
| 10648 | <event name="OnMiddleDown"></event> | ||
| 10649 | <event name="OnMiddleUp"></event> | ||
| 10650 | <event name="OnMotion"></event> | ||
| 10651 | <event name="OnMouseEvents"></event> | ||
| 10652 | <event name="OnMouseWheel"></event> | ||
| 10653 | <event name="OnPaint"></event> | ||
| 10654 | <event name="OnRightDClick"></event> | ||
| 10655 | <event name="OnRightDown"></event> | ||
| 10656 | <event name="OnRightUp"></event> | ||
| 10657 | <event name="OnSetFocus"></event> | ||
| 10658 | <event name="OnSize"></event> | ||
| 10659 | <event name="OnUpdateUI"></event> | ||
| 10660 | </object> | ||
| 10661 | </object> | ||
| 10662 | </object> | ||
| 10663 | </object> | ||
| 10664 | </object> | ||
| 10665 | </object> | ||
| 10666 | <object class="Frame" expanded="0"> | ||
| 10667 | <property name="bg"></property> | ||
| 10668 | <property name="center"></property> | ||
| 10669 | <property name="context_help"></property> | ||
| 10670 | <property name="enabled">1</property> | ||
| 10671 | <property name="extra_style"></property> | ||
| 10672 | <property name="fg"></property> | ||
| 10673 | <property name="font"></property> | ||
| 10674 | <property name="hidden">0</property> | ||
| 10675 | <property name="id">wxID_ANY</property> | ||
| 10676 | <property name="maximum_size"></property> | ||
| 10677 | <property name="minimum_size"></property> | ||
| 10678 | <property name="name">CPokerDialogBase</property> | ||
| 10679 | <property name="pos"></property> | ||
| 10680 | <property name="size">806,550</property> | ||
| 10681 | <property name="style">wxDEFAULT_FRAME_STYLE|wxFRAME_NO_TASKBAR</property> | ||
| 10682 | <property name="subclass"></property> | ||
| 10683 | <property name="title">Poker</property> | ||
| 10684 | <property name="tooltip"></property> | ||
| 10685 | <property name="window_extra_style"></property> | ||
| 10686 | <property name="window_name"></property> | ||
| 10687 | <property name="window_style">wxFULL_REPAINT_ON_RESIZE|wxTAB_TRAVERSAL</property> | ||
| 10688 | <property name="xrc_skip_sizer">1</property> | ||
| 10689 | <event name="OnActivate"></event> | ||
| 10690 | <event name="OnActivateApp"></event> | ||
| 10691 | <event name="OnChar"></event> | ||
| 10692 | <event name="OnClose">OnClose</event> | ||
| 10693 | <event name="OnEnterWindow"></event> | ||
| 10694 | <event name="OnEraseBackground"></event> | ||
| 10695 | <event name="OnHibernate"></event> | ||
| 10696 | <event name="OnIconize"></event> | ||
| 10697 | <event name="OnIdle"></event> | ||
| 10698 | <event name="OnKeyDown"></event> | ||
| 10699 | <event name="OnKeyUp"></event> | ||
| 10700 | <event name="OnKillFocus"></event> | ||
| 10701 | <event name="OnLeaveWindow"></event> | ||
| 10702 | <event name="OnLeftDClick"></event> | ||
| 10703 | <event name="OnLeftDown"></event> | ||
| 10704 | <event name="OnLeftUp"></event> | ||
| 10705 | <event name="OnMiddleDClick"></event> | ||
| 10706 | <event name="OnMiddleDown"></event> | ||
| 10707 | <event name="OnMiddleUp"></event> | ||
| 10708 | <event name="OnMotion"></event> | ||
| 10709 | <event name="OnMouseEvents">OnMouseEvents</event> | ||
| 10710 | <event name="OnMouseWheel"></event> | ||
| 10711 | <event name="OnPaint">OnPaint</event> | ||
| 10712 | <event name="OnRightDClick"></event> | ||
| 10713 | <event name="OnRightDown"></event> | ||
| 10714 | <event name="OnRightUp"></event> | ||
| 10715 | <event name="OnSetFocus"></event> | ||
| 10716 | <event name="OnSize">OnSize</event> | ||
| 10717 | <event name="OnUpdateUI"></event> | ||
| 10718 | <object class="wxBoxSizer" expanded="1"> | ||
| 10719 | <property name="minimum_size"></property> | ||
| 10720 | <property name="name">bSizer174</property> | ||
| 10721 | <property name="orient">wxVERTICAL</property> | ||
| 10722 | <property name="permission">none</property> | ||
| 10723 | <object class="sizeritem" expanded="1"> | ||
| 10724 | <property name="border">5</property> | ||
| 10725 | <property name="flag">wxALL</property> | ||
| 10726 | <property name="proportion">0</property> | ||
| 10727 | <object class="wxCheckBox" expanded="1"> | ||
| 10728 | <property name="bg"></property> | ||
| 10729 | <property name="checked">0</property> | ||
| 10730 | <property name="context_help"></property> | ||
| 10731 | <property name="enabled">1</property> | ||
| 10732 | <property name="fg"></property> | ||
| 10733 | <property name="font"></property> | ||
| 10734 | <property name="hidden">0</property> | ||
| 10735 | <property name="id">wxID_ANY</property> | ||
| 10736 | <property name="label">Deal Me Out</property> | ||
| 10737 | <property name="maximum_size"></property> | ||
| 10738 | <property name="minimum_size"></property> | ||
| 10739 | <property name="name">m_checkSitOut</property> | ||
| 10740 | <property name="permission">public</property> | ||
| 10741 | <property name="pos"></property> | ||
| 10742 | <property name="size"></property> | ||
| 10743 | <property name="style"></property> | ||
| 10744 | <property name="subclass"></property> | ||
| 10745 | <property name="tooltip"></property> | ||
| 10746 | <property name="window_extra_style"></property> | ||
| 10747 | <property name="window_name"></property> | ||
| 10748 | <property name="window_style"></property> | ||
| 10749 | <event name="OnChar"></event> | ||
| 10750 | <event name="OnCheckBox">OnCheckSitOut</event> | ||
| 10751 | <event name="OnEnterWindow"></event> | ||
| 10752 | <event name="OnEraseBackground"></event> | ||
| 10753 | <event name="OnKeyDown"></event> | ||
| 10754 | <event name="OnKeyUp"></event> | ||
| 10755 | <event name="OnKillFocus"></event> | ||
| 10756 | <event name="OnLeaveWindow"></event> | ||
| 10757 | <event name="OnLeftDClick"></event> | ||
| 10758 | <event name="OnLeftDown"></event> | ||
| 10759 | <event name="OnLeftUp"></event> | ||
| 10760 | <event name="OnMiddleDClick"></event> | ||
| 10761 | <event name="OnMiddleDown"></event> | ||
| 10762 | <event name="OnMiddleUp"></event> | ||
| 10763 | <event name="OnMotion"></event> | ||
| 10764 | <event name="OnMouseEvents"></event> | ||
| 10765 | <event name="OnMouseWheel"></event> | ||
| 10766 | <event name="OnPaint"></event> | ||
| 10767 | <event name="OnRightDClick"></event> | ||
| 10768 | <event name="OnRightDown"></event> | ||
| 10769 | <event name="OnRightUp"></event> | ||
| 10770 | <event name="OnSetFocus"></event> | ||
| 10771 | <event name="OnSize"></event> | ||
| 10772 | <event name="OnUpdateUI"></event> | ||
| 10773 | </object> | ||
| 10774 | </object> | ||
| 10775 | <object class="sizeritem" expanded="1"> | ||
| 10776 | <property name="border">5</property> | ||
| 10777 | <property name="flag">wxALL</property> | ||
| 10778 | <property name="proportion">0</property> | ||
| 10779 | <object class="wxButton" expanded="1"> | ||
| 10780 | <property name="bg"></property> | ||
| 10781 | <property name="context_help"></property> | ||
| 10782 | <property name="default">0</property> | ||
| 10783 | <property name="enabled">1</property> | ||
| 10784 | <property name="fg"></property> | ||
| 10785 | <property name="font"></property> | ||
| 10786 | <property name="hidden">0</property> | ||
| 10787 | <property name="id">wxID_DEALHAND</property> | ||
| 10788 | <property name="label">&Deal Hand</property> | ||
| 10789 | <property name="maximum_size"></property> | ||
| 10790 | <property name="minimum_size"></property> | ||
| 10791 | <property name="name">m_buttonDealHand</property> | ||
| 10792 | <property name="permission">protected</property> | ||
| 10793 | <property name="pos"></property> | ||
| 10794 | <property name="size">150,25</property> | ||
| 10795 | <property name="style"></property> | ||
| 10796 | <property name="subclass"></property> | ||
| 10797 | <property name="tooltip"></property> | ||
| 10798 | <property name="window_extra_style"></property> | ||
| 10799 | <property name="window_name"></property> | ||
| 10800 | <property name="window_style"></property> | ||
| 10801 | <event name="OnButtonClick">OnButtonDealHand</event> | ||
| 10802 | <event name="OnChar"></event> | ||
| 10803 | <event name="OnEnterWindow"></event> | ||
| 10804 | <event name="OnEraseBackground"></event> | ||
| 10805 | <event name="OnKeyDown"></event> | ||
| 10806 | <event name="OnKeyUp"></event> | ||
| 10807 | <event name="OnKillFocus"></event> | ||
| 10808 | <event name="OnLeaveWindow"></event> | ||
| 10809 | <event name="OnLeftDClick"></event> | ||
| 10810 | <event name="OnLeftDown"></event> | ||
| 10811 | <event name="OnLeftUp"></event> | ||
| 10812 | <event name="OnMiddleDClick"></event> | ||
| 10813 | <event name="OnMiddleDown"></event> | ||
| 10814 | <event name="OnMiddleUp"></event> | ||
| 10815 | <event name="OnMotion"></event> | ||
| 10816 | <event name="OnMouseEvents"></event> | ||
| 10817 | <event name="OnMouseWheel"></event> | ||
| 10818 | <event name="OnPaint"></event> | ||
| 10819 | <event name="OnRightDClick"></event> | ||
| 10820 | <event name="OnRightDown"></event> | ||
| 10821 | <event name="OnRightUp"></event> | ||
| 10822 | <event name="OnSetFocus"></event> | ||
| 10823 | <event name="OnSize"></event> | ||
| 10824 | <event name="OnUpdateUI"></event> | ||
| 10825 | </object> | ||
| 10826 | </object> | ||
| 10827 | <object class="sizeritem" expanded="1"> | ||
| 10828 | <property name="border">5</property> | ||
| 10829 | <property name="flag">wxALL</property> | ||
| 10830 | <property name="proportion">0</property> | ||
| 10831 | <object class="wxButton" expanded="1"> | ||
| 10832 | <property name="bg"></property> | ||
| 10833 | <property name="context_help"></property> | ||
| 10834 | <property name="default">0</property> | ||
| 10835 | <property name="enabled">1</property> | ||
| 10836 | <property name="fg"></property> | ||
| 10837 | <property name="font"></property> | ||
| 10838 | <property name="hidden">0</property> | ||
| 10839 | <property name="id">wxID_FOLD</property> | ||
| 10840 | <property name="label">&Fold</property> | ||
| 10841 | <property name="maximum_size"></property> | ||
| 10842 | <property name="minimum_size"></property> | ||
| 10843 | <property name="name">m_buttonFold</property> | ||
| 10844 | <property name="permission">protected</property> | ||
| 10845 | <property name="pos"></property> | ||
| 10846 | <property name="size">80,25</property> | ||
| 10847 | <property name="style"></property> | ||
| 10848 | <property name="subclass"></property> | ||
| 10849 | <property name="tooltip"></property> | ||
| 10850 | <property name="window_extra_style"></property> | ||
| 10851 | <property name="window_name"></property> | ||
| 10852 | <property name="window_style"></property> | ||
| 10853 | <event name="OnButtonClick">OnButtonFold</event> | ||
| 10854 | <event name="OnChar"></event> | ||
| 10855 | <event name="OnEnterWindow"></event> | ||
| 10856 | <event name="OnEraseBackground"></event> | ||
| 10857 | <event name="OnKeyDown"></event> | ||
| 10858 | <event name="OnKeyUp"></event> | ||
| 10859 | <event name="OnKillFocus"></event> | ||
| 10860 | <event name="OnLeaveWindow"></event> | ||
| 10861 | <event name="OnLeftDClick"></event> | ||
| 10862 | <event name="OnLeftDown"></event> | ||
| 10863 | <event name="OnLeftUp"></event> | ||
| 10864 | <event name="OnMiddleDClick"></event> | ||
| 10865 | <event name="OnMiddleDown"></event> | ||
| 10866 | <event name="OnMiddleUp"></event> | ||
| 10867 | <event name="OnMotion"></event> | ||
| 10868 | <event name="OnMouseEvents"></event> | ||
| 10869 | <event name="OnMouseWheel"></event> | ||
| 10870 | <event name="OnPaint"></event> | ||
| 10871 | <event name="OnRightDClick"></event> | ||
| 10872 | <event name="OnRightDown"></event> | ||
| 10873 | <event name="OnRightUp"></event> | ||
| 10874 | <event name="OnSetFocus"></event> | ||
| 10875 | <event name="OnSize"></event> | ||
| 10876 | <event name="OnUpdateUI"></event> | ||
| 10877 | </object> | ||
| 10878 | </object> | ||
| 10879 | <object class="sizeritem" expanded="1"> | ||
| 10880 | <property name="border">5</property> | ||
| 10881 | <property name="flag">wxALL</property> | ||
| 10882 | <property name="proportion">0</property> | ||
| 10883 | <object class="wxButton" expanded="1"> | ||
| 10884 | <property name="bg"></property> | ||
| 10885 | <property name="context_help"></property> | ||
| 10886 | <property name="default">0</property> | ||
| 10887 | <property name="enabled">1</property> | ||
| 10888 | <property name="fg"></property> | ||
| 10889 | <property name="font"></property> | ||
| 10890 | <property name="hidden">0</property> | ||
| 10891 | <property name="id">wxID_CALL</property> | ||
| 10892 | <property name="label">&Call</property> | ||
| 10893 | <property name="maximum_size"></property> | ||
| 10894 | <property name="minimum_size"></property> | ||
| 10895 | <property name="name">m_buttonCall</property> | ||
| 10896 | <property name="permission">protected</property> | ||
| 10897 | <property name="pos"></property> | ||
| 10898 | <property name="size">80,25</property> | ||
| 10899 | <property name="style"></property> | ||
| 10900 | <property name="subclass"></property> | ||
| 10901 | <property name="tooltip"></property> | ||
| 10902 | <property name="window_extra_style"></property> | ||
| 10903 | <property name="window_name"></property> | ||
| 10904 | <property name="window_style"></property> | ||
| 10905 | <event name="OnButtonClick">OnButtonCall</event> | ||
| 10906 | <event name="OnChar"></event> | ||
| 10907 | <event name="OnEnterWindow"></event> | ||
| 10908 | <event name="OnEraseBackground"></event> | ||
| 10909 | <event name="OnKeyDown"></event> | ||
| 10910 | <event name="OnKeyUp"></event> | ||
| 10911 | <event name="OnKillFocus"></event> | ||
| 10912 | <event name="OnLeaveWindow"></event> | ||
| 10913 | <event name="OnLeftDClick"></event> | ||
| 10914 | <event name="OnLeftDown"></event> | ||
| 10915 | <event name="OnLeftUp"></event> | ||
| 10916 | <event name="OnMiddleDClick"></event> | ||
| 10917 | <event name="OnMiddleDown"></event> | ||
| 10918 | <event name="OnMiddleUp"></event> | ||
| 10919 | <event name="OnMotion"></event> | ||
| 10920 | <event name="OnMouseEvents"></event> | ||
| 10921 | <event name="OnMouseWheel"></event> | ||
| 10922 | <event name="OnPaint"></event> | ||
| 10923 | <event name="OnRightDClick"></event> | ||
| 10924 | <event name="OnRightDown"></event> | ||
| 10925 | <event name="OnRightUp"></event> | ||
| 10926 | <event name="OnSetFocus"></event> | ||
| 10927 | <event name="OnSize"></event> | ||
| 10928 | <event name="OnUpdateUI"></event> | ||
| 10929 | </object> | ||
| 10930 | </object> | ||
| 10931 | <object class="sizeritem" expanded="1"> | ||
| 10932 | <property name="border">5</property> | ||
| 10933 | <property name="flag">wxALL</property> | ||
| 10934 | <property name="proportion">0</property> | ||
| 10935 | <object class="wxButton" expanded="1"> | ||
| 10936 | <property name="bg"></property> | ||
| 10937 | <property name="context_help"></property> | ||
| 10938 | <property name="default">0</property> | ||
| 10939 | <property name="enabled">1</property> | ||
| 10940 | <property name="fg"></property> | ||
| 10941 | <property name="font"></property> | ||
| 10942 | <property name="hidden">0</property> | ||
| 10943 | <property name="id">wxID_RAISE</property> | ||
| 10944 | <property name="label">&Raise</property> | ||
| 10945 | <property name="maximum_size"></property> | ||
| 10946 | <property name="minimum_size"></property> | ||
| 10947 | <property name="name">m_buttonRaise</property> | ||
| 10948 | <property name="permission">protected</property> | ||
| 10949 | <property name="pos"></property> | ||
| 10950 | <property name="size">80,25</property> | ||
| 10951 | <property name="style"></property> | ||
| 10952 | <property name="subclass"></property> | ||
| 10953 | <property name="tooltip"></property> | ||
| 10954 | <property name="window_extra_style"></property> | ||
| 10955 | <property name="window_name"></property> | ||
| 10956 | <property name="window_style"></property> | ||
| 10957 | <event name="OnButtonClick">OnButtonRaise</event> | ||
| 10958 | <event name="OnChar"></event> | ||
| 10959 | <event name="OnEnterWindow"></event> | ||
| 10960 | <event name="OnEraseBackground"></event> | ||
| 10961 | <event name="OnKeyDown"></event> | ||
| 10962 | <event name="OnKeyUp"></event> | ||
| 10963 | <event name="OnKillFocus"></event> | ||
| 10964 | <event name="OnLeaveWindow"></event> | ||
| 10965 | <event name="OnLeftDClick"></event> | ||
| 10966 | <event name="OnLeftDown"></event> | ||
| 10967 | <event name="OnLeftUp"></event> | ||
| 10968 | <event name="OnMiddleDClick"></event> | ||
| 10969 | <event name="OnMiddleDown"></event> | ||
| 10970 | <event name="OnMiddleUp"></event> | ||
| 10971 | <event name="OnMotion"></event> | ||
| 10972 | <event name="OnMouseEvents"></event> | ||
| 10973 | <event name="OnMouseWheel"></event> | ||
| 10974 | <event name="OnPaint"></event> | ||
| 10975 | <event name="OnRightDClick"></event> | ||
| 10976 | <event name="OnRightDown"></event> | ||
| 10977 | <event name="OnRightUp"></event> | ||
| 10978 | <event name="OnSetFocus"></event> | ||
| 10979 | <event name="OnSize"></event> | ||
| 10980 | <event name="OnUpdateUI"></event> | ||
| 10981 | </object> | ||
| 10982 | </object> | ||
| 10983 | <object class="sizeritem" expanded="1"> | ||
| 10984 | <property name="border">5</property> | ||
| 10985 | <property name="flag">wxALL</property> | ||
| 10986 | <property name="proportion">0</property> | ||
| 10987 | <object class="wxButton" expanded="1"> | ||
| 10988 | <property name="bg"></property> | ||
| 10989 | <property name="context_help"></property> | ||
| 10990 | <property name="default">0</property> | ||
| 10991 | <property name="enabled">1</property> | ||
| 10992 | <property name="fg"></property> | ||
| 10993 | <property name="font"></property> | ||
| 10994 | <property name="hidden">0</property> | ||
| 10995 | <property name="id">wxID_LEAVETABLE</property> | ||
| 10996 | <property name="label">&Leave Table</property> | ||
| 10997 | <property name="maximum_size"></property> | ||
| 10998 | <property name="minimum_size"></property> | ||
| 10999 | <property name="name">m_buttonLeaveTable</property> | ||
| 11000 | <property name="permission">protected</property> | ||
| 11001 | <property name="pos"></property> | ||
| 11002 | <property name="size">90,25</property> | ||
| 11003 | <property name="style"></property> | ||
| 11004 | <property name="subclass"></property> | ||
| 11005 | <property name="tooltip"></property> | ||
| 11006 | <property name="window_extra_style"></property> | ||
| 11007 | <property name="window_name"></property> | ||
| 11008 | <property name="window_style"></property> | ||
| 11009 | <event name="OnButtonClick">OnButtonLeaveTable</event> | ||
| 11010 | <event name="OnChar"></event> | ||
| 11011 | <event name="OnEnterWindow"></event> | ||
| 11012 | <event name="OnEraseBackground"></event> | ||
| 11013 | <event name="OnKeyDown"></event> | ||
| 11014 | <event name="OnKeyUp"></event> | ||
| 11015 | <event name="OnKillFocus"></event> | ||
| 11016 | <event name="OnLeaveWindow"></event> | ||
| 11017 | <event name="OnLeftDClick"></event> | ||
| 11018 | <event name="OnLeftDown"></event> | ||
| 11019 | <event name="OnLeftUp"></event> | ||
| 11020 | <event name="OnMiddleDClick"></event> | ||
| 11021 | <event name="OnMiddleDown"></event> | ||
| 11022 | <event name="OnMiddleUp"></event> | ||
| 11023 | <event name="OnMotion"></event> | ||
| 11024 | <event name="OnMouseEvents"></event> | ||
| 11025 | <event name="OnMouseWheel"></event> | ||
| 11026 | <event name="OnPaint"></event> | ||
| 11027 | <event name="OnRightDClick"></event> | ||
| 11028 | <event name="OnRightDown"></event> | ||
| 11029 | <event name="OnRightUp"></event> | ||
| 11030 | <event name="OnSetFocus"></event> | ||
| 11031 | <event name="OnSize"></event> | ||
| 11032 | <event name="OnUpdateUI"></event> | ||
| 11033 | </object> | ||
| 11034 | </object> | ||
| 11035 | <object class="sizeritem" expanded="1"> | ||
| 11036 | <property name="border">5</property> | ||
| 11037 | <property name="flag">wxALL</property> | ||
| 11038 | <property name="proportion">0</property> | ||
| 11039 | <object class="wxTextCtrl" expanded="1"> | ||
| 11040 | <property name="bg"></property> | ||
| 11041 | <property name="context_help"></property> | ||
| 11042 | <property name="enabled">1</property> | ||
| 11043 | <property name="fg"></property> | ||
| 11044 | <property name="font"></property> | ||
| 11045 | <property name="hidden">0</property> | ||
| 11046 | <property name="id">wxID_DITCHPLAYER</property> | ||
| 11047 | <property name="maximum_size"></property> | ||
| 11048 | <property name="maxlength">0</property> | ||
| 11049 | <property name="minimum_size"></property> | ||
| 11050 | <property name="name">m_textDitchPlayer</property> | ||
| 11051 | <property name="permission">protected</property> | ||
| 11052 | <property name="pos"></property> | ||
| 11053 | <property name="size">45,-1</property> | ||
| 11054 | <property name="style">wxTE_PROCESS_ENTER</property> | ||
| 11055 | <property name="subclass"></property> | ||
| 11056 | <property name="tooltip"></property> | ||
| 11057 | <property name="value"></property> | ||
| 11058 | <property name="window_extra_style"></property> | ||
| 11059 | <property name="window_name"></property> | ||
| 11060 | <property name="window_style"></property> | ||
| 11061 | <event name="OnChar"></event> | ||
| 11062 | <event name="OnEnterWindow"></event> | ||
| 11063 | <event name="OnEraseBackground"></event> | ||
| 11064 | <event name="OnKeyDown"></event> | ||
| 11065 | <event name="OnKeyUp"></event> | ||
| 11066 | <event name="OnKillFocus"></event> | ||
| 11067 | <event name="OnLeaveWindow"></event> | ||
| 11068 | <event name="OnLeftDClick"></event> | ||
| 11069 | <event name="OnLeftDown"></event> | ||
| 11070 | <event name="OnLeftUp"></event> | ||
| 11071 | <event name="OnMiddleDClick"></event> | ||
| 11072 | <event name="OnMiddleDown"></event> | ||
| 11073 | <event name="OnMiddleUp"></event> | ||
| 11074 | <event name="OnMotion"></event> | ||
| 11075 | <event name="OnMouseEvents"></event> | ||
| 11076 | <event name="OnMouseWheel"></event> | ||
| 11077 | <event name="OnPaint"></event> | ||
| 11078 | <event name="OnRightDClick"></event> | ||
| 11079 | <event name="OnRightDown"></event> | ||
| 11080 | <event name="OnRightUp"></event> | ||
| 11081 | <event name="OnSetFocus"></event> | ||
| 11082 | <event name="OnSize"></event> | ||
| 11083 | <event name="OnText"></event> | ||
| 11084 | <event name="OnTextEnter">OnDitchPlayer</event> | ||
| 11085 | <event name="OnTextMaxLen"></event> | ||
| 11086 | <event name="OnTextURL"></event> | ||
| 11087 | <event name="OnUpdateUI"></event> | ||
| 11088 | </object> | ||
| 11089 | </object> | ||
| 11090 | <object class="sizeritem" expanded="1"> | ||
| 11091 | <property name="border">5</property> | ||
| 11092 | <property name="flag">wxALL</property> | ||
| 11093 | <property name="proportion">0</property> | ||
| 11094 | <object class="wxCheckBox" expanded="1"> | ||
| 11095 | <property name="bg"></property> | ||
| 11096 | <property name="checked">0</property> | ||
| 11097 | <property name="context_help"></property> | ||
| 11098 | <property name="enabled">1</property> | ||
| 11099 | <property name="fg"></property> | ||
| 11100 | <property name="font"></property> | ||
| 11101 | <property name="hidden">0</property> | ||
| 11102 | <property name="id">wxID_ANY</property> | ||
| 11103 | <property name="label">FOLD</property> | ||
| 11104 | <property name="maximum_size"></property> | ||
| 11105 | <property name="minimum_size"></property> | ||
| 11106 | <property name="name">m_checkPreFold</property> | ||
| 11107 | <property name="permission">public</property> | ||
| 11108 | <property name="pos"></property> | ||
| 11109 | <property name="size">100,-1</property> | ||
| 11110 | <property name="style"></property> | ||
| 11111 | <property name="subclass"></property> | ||
| 11112 | <property name="tooltip"></property> | ||
| 11113 | <property name="window_extra_style"></property> | ||
| 11114 | <property name="window_name"></property> | ||
| 11115 | <property name="window_style"></property> | ||
| 11116 | <event name="OnChar"></event> | ||
| 11117 | <event name="OnCheckBox">OnCheckPreFold</event> | ||
| 11118 | <event name="OnEnterWindow"></event> | ||
| 11119 | <event name="OnEraseBackground"></event> | ||
| 11120 | <event name="OnKeyDown"></event> | ||
| 11121 | <event name="OnKeyUp"></event> | ||
| 11122 | <event name="OnKillFocus"></event> | ||
| 11123 | <event name="OnLeaveWindow"></event> | ||
| 11124 | <event name="OnLeftDClick"></event> | ||
| 11125 | <event name="OnLeftDown"></event> | ||
| 11126 | <event name="OnLeftUp"></event> | ||
| 11127 | <event name="OnMiddleDClick"></event> | ||
| 11128 | <event name="OnMiddleDown"></event> | ||
| 11129 | <event name="OnMiddleUp"></event> | ||
| 11130 | <event name="OnMotion"></event> | ||
| 11131 | <event name="OnMouseEvents"></event> | ||
| 11132 | <event name="OnMouseWheel"></event> | ||
| 11133 | <event name="OnPaint"></event> | ||
| 11134 | <event name="OnRightDClick"></event> | ||
| 11135 | <event name="OnRightDown"></event> | ||
| 11136 | <event name="OnRightUp"></event> | ||
| 11137 | <event name="OnSetFocus"></event> | ||
| 11138 | <event name="OnSize"></event> | ||
| 11139 | <event name="OnUpdateUI"></event> | ||
| 11140 | </object> | ||
| 11141 | </object> | ||
| 11142 | <object class="sizeritem" expanded="1"> | ||
| 11143 | <property name="border">5</property> | ||
| 11144 | <property name="flag">wxALL</property> | ||
| 11145 | <property name="proportion">0</property> | ||
| 11146 | <object class="wxCheckBox" expanded="1"> | ||
| 11147 | <property name="bg"></property> | ||
| 11148 | <property name="checked">0</property> | ||
| 11149 | <property name="context_help"></property> | ||
| 11150 | <property name="enabled">1</property> | ||
| 11151 | <property name="fg"></property> | ||
| 11152 | <property name="font"></property> | ||
| 11153 | <property name="hidden">0</property> | ||
| 11154 | <property name="id">wxID_ANY</property> | ||
| 11155 | <property name="label">CALL</property> | ||
| 11156 | <property name="maximum_size"></property> | ||
| 11157 | <property name="minimum_size"></property> | ||
| 11158 | <property name="name">m_checkPreCall</property> | ||
| 11159 | <property name="permission">public</property> | ||
| 11160 | <property name="pos"></property> | ||
| 11161 | <property name="size">100,-1</property> | ||
| 11162 | <property name="style"></property> | ||
| 11163 | <property name="subclass"></property> | ||
| 11164 | <property name="tooltip"></property> | ||
| 11165 | <property name="window_extra_style"></property> | ||
| 11166 | <property name="window_name"></property> | ||
| 11167 | <property name="window_style"></property> | ||
| 11168 | <event name="OnChar"></event> | ||
| 11169 | <event name="OnCheckBox">OnCheckPreCall</event> | ||
| 11170 | <event name="OnEnterWindow"></event> | ||
| 11171 | <event name="OnEraseBackground"></event> | ||
| 11172 | <event name="OnKeyDown"></event> | ||
| 11173 | <event name="OnKeyUp"></event> | ||
| 11174 | <event name="OnKillFocus"></event> | ||
| 11175 | <event name="OnLeaveWindow"></event> | ||
| 11176 | <event name="OnLeftDClick"></event> | ||
| 11177 | <event name="OnLeftDown"></event> | ||
| 11178 | <event name="OnLeftUp"></event> | ||
| 11179 | <event name="OnMiddleDClick"></event> | ||
| 11180 | <event name="OnMiddleDown"></event> | ||
| 11181 | <event name="OnMiddleUp"></event> | ||
| 11182 | <event name="OnMotion"></event> | ||
| 11183 | <event name="OnMouseEvents"></event> | ||
| 11184 | <event name="OnMouseWheel"></event> | ||
| 11185 | <event name="OnPaint"></event> | ||
| 11186 | <event name="OnRightDClick"></event> | ||
| 11187 | <event name="OnRightDown"></event> | ||
| 11188 | <event name="OnRightUp"></event> | ||
| 11189 | <event name="OnSetFocus"></event> | ||
| 11190 | <event name="OnSize"></event> | ||
| 11191 | <event name="OnUpdateUI"></event> | ||
| 11192 | </object> | ||
| 11193 | </object> | ||
| 11194 | <object class="sizeritem" expanded="1"> | ||
| 11195 | <property name="border">5</property> | ||
| 11196 | <property name="flag">wxALL</property> | ||
| 11197 | <property name="proportion">0</property> | ||
| 11198 | <object class="wxCheckBox" expanded="1"> | ||
| 11199 | <property name="bg"></property> | ||
| 11200 | <property name="checked">0</property> | ||
| 11201 | <property name="context_help"></property> | ||
| 11202 | <property name="enabled">1</property> | ||
| 11203 | <property name="fg"></property> | ||
| 11204 | <property name="font"></property> | ||
| 11205 | <property name="hidden">0</property> | ||
| 11206 | <property name="id">wxID_ANY</property> | ||
| 11207 | <property name="label">CALL ANY</property> | ||
| 11208 | <property name="maximum_size"></property> | ||
| 11209 | <property name="minimum_size"></property> | ||
| 11210 | <property name="name">m_checkPreCallAny</property> | ||
| 11211 | <property name="permission">public</property> | ||
| 11212 | <property name="pos"></property> | ||
| 11213 | <property name="size">100,-1</property> | ||
| 11214 | <property name="style"></property> | ||
| 11215 | <property name="subclass"></property> | ||
| 11216 | <property name="tooltip"></property> | ||
| 11217 | <property name="window_extra_style"></property> | ||
| 11218 | <property name="window_name"></property> | ||
| 11219 | <property name="window_style"></property> | ||
| 11220 | <event name="OnChar"></event> | ||
| 11221 | <event name="OnCheckBox">OnCheckPreCallAny</event> | ||
| 11222 | <event name="OnEnterWindow"></event> | ||
| 11223 | <event name="OnEraseBackground"></event> | ||
| 11224 | <event name="OnKeyDown"></event> | ||
| 11225 | <event name="OnKeyUp"></event> | ||
| 11226 | <event name="OnKillFocus"></event> | ||
| 11227 | <event name="OnLeaveWindow"></event> | ||
| 11228 | <event name="OnLeftDClick"></event> | ||
| 11229 | <event name="OnLeftDown"></event> | ||
| 11230 | <event name="OnLeftUp"></event> | ||
| 11231 | <event name="OnMiddleDClick"></event> | ||
| 11232 | <event name="OnMiddleDown"></event> | ||
| 11233 | <event name="OnMiddleUp"></event> | ||
| 11234 | <event name="OnMotion"></event> | ||
| 11235 | <event name="OnMouseEvents"></event> | ||
| 11236 | <event name="OnMouseWheel"></event> | ||
| 11237 | <event name="OnPaint"></event> | ||
| 11238 | <event name="OnRightDClick"></event> | ||
| 11239 | <event name="OnRightDown"></event> | ||
| 11240 | <event name="OnRightUp"></event> | ||
| 11241 | <event name="OnSetFocus"></event> | ||
| 11242 | <event name="OnSize"></event> | ||
| 11243 | <event name="OnUpdateUI"></event> | ||
| 11244 | </object> | ||
| 11245 | </object> | ||
| 11246 | <object class="sizeritem" expanded="1"> | ||
| 11247 | <property name="border">5</property> | ||
| 11248 | <property name="flag">wxALL</property> | ||
| 11249 | <property name="proportion">0</property> | ||
| 11250 | <object class="wxCheckBox" expanded="1"> | ||
| 11251 | <property name="bg"></property> | ||
| 11252 | <property name="checked">0</property> | ||
| 11253 | <property name="context_help"></property> | ||
| 11254 | <property name="enabled">1</property> | ||
| 11255 | <property name="fg"></property> | ||
| 11256 | <property name="font"></property> | ||
| 11257 | <property name="hidden">0</property> | ||
| 11258 | <property name="id">wxID_ANY</property> | ||
| 11259 | <property name="label">RAISE</property> | ||
| 11260 | <property name="maximum_size"></property> | ||
| 11261 | <property name="minimum_size"></property> | ||
| 11262 | <property name="name">m_checkPreRaise</property> | ||
| 11263 | <property name="permission">public</property> | ||
| 11264 | <property name="pos"></property> | ||
| 11265 | <property name="size">100,-1</property> | ||
| 11266 | <property name="style"></property> | ||
| 11267 | <property name="subclass"></property> | ||
| 11268 | <property name="tooltip"></property> | ||
| 11269 | <property name="window_extra_style"></property> | ||
| 11270 | <property name="window_name"></property> | ||
| 11271 | <property name="window_style"></property> | ||
| 11272 | <event name="OnChar"></event> | ||
| 11273 | <event name="OnCheckBox">OnCheckPreRaise</event> | ||
| 11274 | <event name="OnEnterWindow"></event> | ||
| 11275 | <event name="OnEraseBackground"></event> | ||
| 11276 | <event name="OnKeyDown"></event> | ||
| 11277 | <event name="OnKeyUp"></event> | ||
| 11278 | <event name="OnKillFocus"></event> | ||
| 11279 | <event name="OnLeaveWindow"></event> | ||
| 11280 | <event name="OnLeftDClick"></event> | ||
| 11281 | <event name="OnLeftDown"></event> | ||
| 11282 | <event name="OnLeftUp"></event> | ||
| 11283 | <event name="OnMiddleDClick"></event> | ||
| 11284 | <event name="OnMiddleDown"></event> | ||
| 11285 | <event name="OnMiddleUp"></event> | ||
| 11286 | <event name="OnMotion"></event> | ||
| 11287 | <event name="OnMouseEvents"></event> | ||
| 11288 | <event name="OnMouseWheel"></event> | ||
| 11289 | <event name="OnPaint"></event> | ||
| 11290 | <event name="OnRightDClick"></event> | ||
| 11291 | <event name="OnRightDown"></event> | ||
| 11292 | <event name="OnRightUp"></event> | ||
| 11293 | <event name="OnSetFocus"></event> | ||
| 11294 | <event name="OnSize"></event> | ||
| 11295 | <event name="OnUpdateUI"></event> | ||
| 11296 | </object> | ||
| 11297 | </object> | ||
| 11298 | <object class="sizeritem" expanded="1"> | ||
| 11299 | <property name="border">5</property> | ||
| 11300 | <property name="flag">wxALL</property> | ||
| 11301 | <property name="proportion">0</property> | ||
| 11302 | <object class="wxCheckBox" expanded="1"> | ||
| 11303 | <property name="bg"></property> | ||
| 11304 | <property name="checked">0</property> | ||
| 11305 | <property name="context_help"></property> | ||
| 11306 | <property name="enabled">1</property> | ||
| 11307 | <property name="fg"></property> | ||
| 11308 | <property name="font"></property> | ||
| 11309 | <property name="hidden">0</property> | ||
| 11310 | <property name="id">wxID_ANY</property> | ||
| 11311 | <property name="label">RAISE ANY</property> | ||
| 11312 | <property name="maximum_size"></property> | ||
| 11313 | <property name="minimum_size"></property> | ||
| 11314 | <property name="name">m_checkPreRaiseAny</property> | ||
| 11315 | <property name="permission">public</property> | ||
| 11316 | <property name="pos"></property> | ||
| 11317 | <property name="size">100,-1</property> | ||
| 11318 | <property name="style"></property> | ||
| 11319 | <property name="subclass"></property> | ||
| 11320 | <property name="tooltip"></property> | ||
| 11321 | <property name="window_extra_style"></property> | ||
| 11322 | <property name="window_name"></property> | ||
| 11323 | <property name="window_style"></property> | ||
| 11324 | <event name="OnChar"></event> | ||
| 11325 | <event name="OnCheckBox">OnCheckPreRaiseAny</event> | ||
| 11326 | <event name="OnEnterWindow"></event> | ||
| 11327 | <event name="OnEraseBackground"></event> | ||
| 11328 | <event name="OnKeyDown"></event> | ||
| 11329 | <event name="OnKeyUp"></event> | ||
| 11330 | <event name="OnKillFocus"></event> | ||
| 11331 | <event name="OnLeaveWindow"></event> | ||
| 11332 | <event name="OnLeftDClick"></event> | ||
| 11333 | <event name="OnLeftDown"></event> | ||
| 11334 | <event name="OnLeftUp"></event> | ||
| 11335 | <event name="OnMiddleDClick"></event> | ||
| 11336 | <event name="OnMiddleDown"></event> | ||
| 11337 | <event name="OnMiddleUp"></event> | ||
| 11338 | <event name="OnMotion"></event> | ||
| 11339 | <event name="OnMouseEvents"></event> | ||
| 11340 | <event name="OnMouseWheel"></event> | ||
| 11341 | <event name="OnPaint"></event> | ||
| 11342 | <event name="OnRightDClick"></event> | ||
| 11343 | <event name="OnRightDown"></event> | ||
| 11344 | <event name="OnRightUp"></event> | ||
| 11345 | <event name="OnSetFocus"></event> | ||
| 11346 | <event name="OnSize"></event> | ||
| 11347 | <event name="OnUpdateUI"></event> | ||
| 11348 | </object> | ||
| 11349 | </object> | ||
| 11350 | </object> | ||
| 11351 | <object class="wxStatusBar" expanded="1"> | ||
| 11352 | <property name="bg"></property> | ||
| 11353 | <property name="context_help"></property> | ||
| 11354 | <property name="enabled">1</property> | ||
| 11355 | <property name="fg"></property> | ||
| 11356 | <property name="fields">1</property> | ||
| 11357 | <property name="font"></property> | ||
| 11358 | <property name="hidden">0</property> | ||
| 11359 | <property name="id">wxID_ANY</property> | ||
| 11360 | <property name="maximum_size"></property> | ||
| 11361 | <property name="minimum_size"></property> | ||
| 11362 | <property name="name">m_statusBar</property> | ||
| 11363 | <property name="permission">public</property> | ||
| 11364 | <property name="pos"></property> | ||
| 11365 | <property name="size"></property> | ||
| 11366 | <property name="style">wxST_SIZEGRIP</property> | ||
| 11367 | <property name="subclass"></property> | ||
| 11368 | <property name="tooltip"></property> | ||
| 11369 | <property name="window_extra_style"></property> | ||
| 11370 | <property name="window_name"></property> | ||
| 11371 | <property name="window_style"></property> | ||
| 11372 | <event name="OnChar"></event> | ||
| 11373 | <event name="OnEnterWindow"></event> | ||
| 11374 | <event name="OnEraseBackground"></event> | ||
| 11375 | <event name="OnKeyDown"></event> | ||
| 11376 | <event name="OnKeyUp"></event> | ||
| 11377 | <event name="OnKillFocus"></event> | ||
| 11378 | <event name="OnLeaveWindow"></event> | ||
| 11379 | <event name="OnLeftDClick"></event> | ||
| 11380 | <event name="OnLeftDown"></event> | ||
| 11381 | <event name="OnLeftUp"></event> | ||
| 11382 | <event name="OnMiddleDClick"></event> | ||
| 11383 | <event name="OnMiddleDown"></event> | ||
| 11384 | <event name="OnMiddleUp"></event> | ||
| 11385 | <event name="OnMotion"></event> | ||
| 11386 | <event name="OnMouseEvents"></event> | ||
| 11387 | <event name="OnMouseWheel"></event> | ||
| 11388 | <event name="OnPaint"></event> | ||
| 11389 | <event name="OnRightDClick"></event> | ||
| 11390 | <event name="OnRightDown"></event> | ||
| 11391 | <event name="OnRightUp"></event> | ||
| 11392 | <event name="OnSetFocus"></event> | ||
| 11393 | <event name="OnSize"></event> | ||
| 11394 | <event name="OnUpdateUI"></event> | ||
| 11395 | </object> | ||
| 11396 | </object> | ||
| 11397 | <object class="Dialog" expanded="0"> | ||
| 11398 | <property name="bg"></property> | ||
| 11399 | <property name="center"></property> | ||
| 11400 | <property name="context_help"></property> | ||
| 11401 | <property name="enabled">1</property> | ||
| 11402 | <property name="extra_style"></property> | ||
| 11403 | <property name="fg"></property> | ||
| 11404 | <property name="font"></property> | ||
| 11405 | <property name="hidden">0</property> | ||
| 11406 | <property name="id">wxID_ANY</property> | ||
| 11407 | <property name="maximum_size"></property> | ||
| 11408 | <property name="minimum_size"></property> | ||
| 11409 | <property name="name">CGetTextFromUserDialogBase</property> | ||
| 11410 | <property name="pos"></property> | ||
| 11411 | <property name="size">403,138</property> | ||
| 11412 | <property name="style">wxDEFAULT_DIALOG_STYLE</property> | ||
| 11413 | <property name="subclass"></property> | ||
| 11414 | <property name="title"></property> | ||
| 11415 | <property name="tooltip"></property> | ||
| 11416 | <property name="window_extra_style"></property> | ||
| 11417 | <property name="window_name"></property> | ||
| 11418 | <property name="window_style"></property> | ||
| 11419 | <event name="OnActivate"></event> | ||
| 11420 | <event name="OnActivateApp"></event> | ||
| 11421 | <event name="OnChar"></event> | ||
| 11422 | <event name="OnClose">OnClose</event> | ||
| 11423 | <event name="OnEnterWindow"></event> | ||
| 11424 | <event name="OnEraseBackground"></event> | ||
| 11425 | <event name="OnHibernate"></event> | ||
| 11426 | <event name="OnIconize"></event> | ||
| 11427 | <event name="OnIdle"></event> | ||
| 11428 | <event name="OnInitDialog"></event> | ||
| 11429 | <event name="OnKeyDown"></event> | ||
| 11430 | <event name="OnKeyUp"></event> | ||
| 11431 | <event name="OnKillFocus"></event> | ||
| 11432 | <event name="OnLeaveWindow"></event> | ||
| 11433 | <event name="OnLeftDClick"></event> | ||
| 11434 | <event name="OnLeftDown"></event> | ||
| 11435 | <event name="OnLeftUp"></event> | ||
| 11436 | <event name="OnMiddleDClick"></event> | ||
| 11437 | <event name="OnMiddleDown"></event> | ||
| 11438 | <event name="OnMiddleUp"></event> | ||
| 11439 | <event name="OnMotion"></event> | ||
| 11440 | <event name="OnMouseEvents"></event> | ||
| 11441 | <event name="OnMouseWheel"></event> | ||
| 11442 | <event name="OnPaint"></event> | ||
| 11443 | <event name="OnRightDClick"></event> | ||
| 11444 | <event name="OnRightDown"></event> | ||
| 11445 | <event name="OnRightUp"></event> | ||
| 11446 | <event name="OnSetFocus"></event> | ||
| 11447 | <event name="OnSize"></event> | ||
| 11448 | <event name="OnUpdateUI"></event> | ||
| 11449 | <object class="wxBoxSizer" expanded="1"> | ||
| 11450 | <property name="minimum_size"></property> | ||
| 11451 | <property name="name">bSizer79</property> | ||
| 11452 | <property name="orient">wxVERTICAL</property> | ||
| 11453 | <property name="permission">none</property> | ||
| 11454 | <object class="sizeritem" expanded="1"> | ||
| 11455 | <property name="border">10</property> | ||
| 11456 | <property name="flag">wxEXPAND|wxALL</property> | ||
| 11457 | <property name="proportion">1</property> | ||
| 11458 | <object class="wxBoxSizer" expanded="1"> | ||
| 11459 | <property name="minimum_size"></property> | ||
| 11460 | <property name="name">bSizer81</property> | ||
| 11461 | <property name="orient">wxVERTICAL</property> | ||
| 11462 | <property name="permission">none</property> | ||
| 11463 | <object class="sizeritem" expanded="1"> | ||
| 11464 | <property name="border">5</property> | ||
| 11465 | <property name="flag">wxEXPAND</property> | ||
| 11466 | <property name="proportion">1</property> | ||
| 11467 | <object class="spacer" expanded="1"> | ||
| 11468 | <property name="height">0</property> | ||
| 11469 | <property name="permission">protected</property> | ||
| 11470 | <property name="width">0</property> | ||
| 11471 | </object> | ||
| 11472 | </object> | ||
| 11473 | <object class="sizeritem" expanded="1"> | ||
| 11474 | <property name="border">5</property> | ||
| 11475 | <property name="flag">wxTOP|wxRIGHT|wxLEFT</property> | ||
| 11476 | <property name="proportion">0</property> | ||
| 11477 | <object class="wxStaticText" expanded="1"> | ||
| 11478 | <property name="bg"></property> | ||
| 11479 | <property name="context_help"></property> | ||
| 11480 | <property name="enabled">1</property> | ||
| 11481 | <property name="fg"></property> | ||
| 11482 | <property name="font"></property> | ||
| 11483 | <property name="hidden">0</property> | ||
| 11484 | <property name="id">wxID_ANY</property> | ||
| 11485 | <property name="label"></property> | ||
| 11486 | <property name="maximum_size"></property> | ||
| 11487 | <property name="minimum_size"></property> | ||
| 11488 | <property name="name">m_staticTextMessage1</property> | ||
| 11489 | <property name="permission">protected</property> | ||
| 11490 | <property name="pos"></property> | ||
| 11491 | <property name="size"></property> | ||
| 11492 | <property name="style"></property> | ||
| 11493 | <property name="subclass"></property> | ||
| 11494 | <property name="tooltip"></property> | ||
| 11495 | <property name="window_extra_style"></property> | ||
| 11496 | <property name="window_name"></property> | ||
| 11497 | <property name="window_style"></property> | ||
| 11498 | <property name="wrap">-1</property> | ||
| 11499 | <event name="OnChar"></event> | ||
| 11500 | <event name="OnEnterWindow"></event> | ||
| 11501 | <event name="OnEraseBackground"></event> | ||
| 11502 | <event name="OnKeyDown"></event> | ||
| 11503 | <event name="OnKeyUp"></event> | ||
| 11504 | <event name="OnKillFocus"></event> | ||
| 11505 | <event name="OnLeaveWindow"></event> | ||
| 11506 | <event name="OnLeftDClick"></event> | ||
| 11507 | <event name="OnLeftDown"></event> | ||
| 11508 | <event name="OnLeftUp"></event> | ||
| 11509 | <event name="OnMiddleDClick"></event> | ||
| 11510 | <event name="OnMiddleDown"></event> | ||
| 11511 | <event name="OnMiddleUp"></event> | ||
| 11512 | <event name="OnMotion"></event> | ||
| 11513 | <event name="OnMouseEvents"></event> | ||
| 11514 | <event name="OnMouseWheel"></event> | ||
| 11515 | <event name="OnPaint"></event> | ||
| 11516 | <event name="OnRightDClick"></event> | ||
| 11517 | <event name="OnRightDown"></event> | ||
| 11518 | <event name="OnRightUp"></event> | ||
| 11519 | <event name="OnSetFocus"></event> | ||
| 11520 | <event name="OnSize"></event> | ||
| 11521 | <event name="OnUpdateUI"></event> | ||
| 11522 | </object> | ||
| 11523 | </object> | ||
| 11524 | <object class="sizeritem" expanded="1"> | ||
| 11525 | <property name="border">5</property> | ||
| 11526 | <property name="flag">wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL</property> | ||
| 11527 | <property name="proportion">0</property> | ||
| 11528 | <object class="wxTextCtrl" expanded="1"> | ||
| 11529 | <property name="bg"></property> | ||
| 11530 | <property name="context_help"></property> | ||
| 11531 | <property name="enabled">1</property> | ||
| 11532 | <property name="fg"></property> | ||
| 11533 | <property name="font"></property> | ||
| 11534 | <property name="hidden">0</property> | ||
| 11535 | <property name="id">wxID_TEXTCTRL</property> | ||
| 11536 | <property name="maximum_size"></property> | ||
| 11537 | <property name="maxlength">0</property> | ||
| 11538 | <property name="minimum_size"></property> | ||
| 11539 | <property name="name">m_textCtrl1</property> | ||
| 11540 | <property name="permission">protected</property> | ||
| 11541 | <property name="pos"></property> | ||
| 11542 | <property name="size"></property> | ||
| 11543 | <property name="style">wxTE_PROCESS_ENTER</property> | ||
| 11544 | <property name="subclass"></property> | ||
| 11545 | <property name="tooltip"></property> | ||
| 11546 | <property name="value"></property> | ||
| 11547 | <property name="window_extra_style"></property> | ||
| 11548 | <property name="window_name"></property> | ||
| 11549 | <property name="window_style"></property> | ||
| 11550 | <event name="OnChar"></event> | ||
| 11551 | <event name="OnEnterWindow"></event> | ||
| 11552 | <event name="OnEraseBackground"></event> | ||
| 11553 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 11554 | <event name="OnKeyUp"></event> | ||
| 11555 | <event name="OnKillFocus"></event> | ||
| 11556 | <event name="OnLeaveWindow"></event> | ||
| 11557 | <event name="OnLeftDClick"></event> | ||
| 11558 | <event name="OnLeftDown"></event> | ||
| 11559 | <event name="OnLeftUp"></event> | ||
| 11560 | <event name="OnMiddleDClick"></event> | ||
| 11561 | <event name="OnMiddleDown"></event> | ||
| 11562 | <event name="OnMiddleUp"></event> | ||
| 11563 | <event name="OnMotion"></event> | ||
| 11564 | <event name="OnMouseEvents"></event> | ||
| 11565 | <event name="OnMouseWheel"></event> | ||
| 11566 | <event name="OnPaint"></event> | ||
| 11567 | <event name="OnRightDClick"></event> | ||
| 11568 | <event name="OnRightDown"></event> | ||
| 11569 | <event name="OnRightUp"></event> | ||
| 11570 | <event name="OnSetFocus"></event> | ||
| 11571 | <event name="OnSize"></event> | ||
| 11572 | <event name="OnText"></event> | ||
| 11573 | <event name="OnTextEnter"></event> | ||
| 11574 | <event name="OnTextMaxLen"></event> | ||
| 11575 | <event name="OnTextURL"></event> | ||
| 11576 | <event name="OnUpdateUI"></event> | ||
| 11577 | </object> | ||
| 11578 | </object> | ||
| 11579 | <object class="sizeritem" expanded="1"> | ||
| 11580 | <property name="border">5</property> | ||
| 11581 | <property name="flag">wxTOP|wxRIGHT|wxLEFT</property> | ||
| 11582 | <property name="proportion">0</property> | ||
| 11583 | <object class="wxStaticText" expanded="1"> | ||
| 11584 | <property name="bg"></property> | ||
| 11585 | <property name="context_help"></property> | ||
| 11586 | <property name="enabled">1</property> | ||
| 11587 | <property name="fg"></property> | ||
| 11588 | <property name="font"></property> | ||
| 11589 | <property name="hidden">1</property> | ||
| 11590 | <property name="id">wxID_ANY</property> | ||
| 11591 | <property name="label"></property> | ||
| 11592 | <property name="maximum_size"></property> | ||
| 11593 | <property name="minimum_size"></property> | ||
| 11594 | <property name="name">m_staticTextMessage2</property> | ||
| 11595 | <property name="permission">protected</property> | ||
| 11596 | <property name="pos"></property> | ||
| 11597 | <property name="size"></property> | ||
| 11598 | <property name="style"></property> | ||
| 11599 | <property name="subclass"></property> | ||
| 11600 | <property name="tooltip"></property> | ||
| 11601 | <property name="window_extra_style"></property> | ||
| 11602 | <property name="window_name"></property> | ||
| 11603 | <property name="window_style"></property> | ||
| 11604 | <property name="wrap">-1</property> | ||
| 11605 | <event name="OnChar"></event> | ||
| 11606 | <event name="OnEnterWindow"></event> | ||
| 11607 | <event name="OnEraseBackground"></event> | ||
| 11608 | <event name="OnKeyDown"></event> | ||
| 11609 | <event name="OnKeyUp"></event> | ||
| 11610 | <event name="OnKillFocus"></event> | ||
| 11611 | <event name="OnLeaveWindow"></event> | ||
| 11612 | <event name="OnLeftDClick"></event> | ||
| 11613 | <event name="OnLeftDown"></event> | ||
| 11614 | <event name="OnLeftUp"></event> | ||
| 11615 | <event name="OnMiddleDClick"></event> | ||
| 11616 | <event name="OnMiddleDown"></event> | ||
| 11617 | <event name="OnMiddleUp"></event> | ||
| 11618 | <event name="OnMotion"></event> | ||
| 11619 | <event name="OnMouseEvents"></event> | ||
| 11620 | <event name="OnMouseWheel"></event> | ||
| 11621 | <event name="OnPaint"></event> | ||
| 11622 | <event name="OnRightDClick"></event> | ||
| 11623 | <event name="OnRightDown"></event> | ||
| 11624 | <event name="OnRightUp"></event> | ||
| 11625 | <event name="OnSetFocus"></event> | ||
| 11626 | <event name="OnSize"></event> | ||
| 11627 | <event name="OnUpdateUI"></event> | ||
| 11628 | </object> | ||
| 11629 | </object> | ||
| 11630 | <object class="sizeritem" expanded="1"> | ||
| 11631 | <property name="border">5</property> | ||
| 11632 | <property name="flag">wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL</property> | ||
| 11633 | <property name="proportion">0</property> | ||
| 11634 | <object class="wxTextCtrl" expanded="1"> | ||
| 11635 | <property name="bg"></property> | ||
| 11636 | <property name="context_help"></property> | ||
| 11637 | <property name="enabled">1</property> | ||
| 11638 | <property name="fg"></property> | ||
| 11639 | <property name="font"></property> | ||
| 11640 | <property name="hidden">1</property> | ||
| 11641 | <property name="id">wxID_TEXTCTRL</property> | ||
| 11642 | <property name="maximum_size"></property> | ||
| 11643 | <property name="maxlength">0</property> | ||
| 11644 | <property name="minimum_size"></property> | ||
| 11645 | <property name="name">m_textCtrl2</property> | ||
| 11646 | <property name="permission">protected</property> | ||
| 11647 | <property name="pos"></property> | ||
| 11648 | <property name="size"></property> | ||
| 11649 | <property name="style">wxTE_PROCESS_ENTER</property> | ||
| 11650 | <property name="subclass"></property> | ||
| 11651 | <property name="tooltip"></property> | ||
| 11652 | <property name="value"></property> | ||
| 11653 | <property name="window_extra_style"></property> | ||
| 11654 | <property name="window_name"></property> | ||
| 11655 | <property name="window_style"></property> | ||
| 11656 | <event name="OnChar"></event> | ||
| 11657 | <event name="OnEnterWindow"></event> | ||
| 11658 | <event name="OnEraseBackground"></event> | ||
| 11659 | <event name="OnKeyDown">OnKeyDown</event> | ||
| 11660 | <event name="OnKeyUp"></event> | ||
| 11661 | <event name="OnKillFocus"></event> | ||
| 11662 | <event name="OnLeaveWindow"></event> | ||
| 11663 | <event name="OnLeftDClick"></event> | ||
| 11664 | <event name="OnLeftDown"></event> | ||
| 11665 | <event name="OnLeftUp"></event> | ||
| 11666 | <event name="OnMiddleDClick"></event> | ||
| 11667 | <event name="OnMiddleDown"></event> | ||
| 11668 | <event name="OnMiddleUp"></event> | ||
| 11669 | <event name="OnMotion"></event> | ||
| 11670 | <event name="OnMouseEvents"></event> | ||
| 11671 | <event name="OnMouseWheel"></event> | ||
| 11672 | <event name="OnPaint"></event> | ||
| 11673 | <event name="OnRightDClick"></event> | ||
| 11674 | <event name="OnRightDown"></event> | ||
| 11675 | <event name="OnRightUp"></event> | ||
| 11676 | <event name="OnSetFocus"></event> | ||
| 11677 | <event name="OnSize"></event> | ||
| 11678 | <event name="OnText"></event> | ||
| 11679 | <event name="OnTextEnter"></event> | ||
| 11680 | <event name="OnTextMaxLen"></event> | ||
| 11681 | <event name="OnTextURL"></event> | ||
| 11682 | <event name="OnUpdateUI"></event> | ||
| 11683 | </object> | ||
| 11684 | </object> | ||
| 11685 | <object class="sizeritem" expanded="1"> | ||
| 11686 | <property name="border">5</property> | ||
| 11687 | <property name="flag">wxEXPAND</property> | ||
| 11688 | <property name="proportion">1</property> | ||
| 11689 | <object class="spacer" expanded="1"> | ||
| 11690 | <property name="height">0</property> | ||
| 11691 | <property name="permission">protected</property> | ||
| 11692 | <property name="width">0</property> | ||
| 11693 | </object> | ||
| 11694 | </object> | ||
| 11695 | </object> | ||
| 11696 | </object> | ||
| 11697 | <object class="sizeritem" expanded="1"> | ||
| 11698 | <property name="border">5</property> | ||
| 11699 | <property name="flag">wxEXPAND</property> | ||
| 11700 | <property name="proportion">0</property> | ||
| 11701 | <object class="wxBoxSizer" expanded="1"> | ||
| 11702 | <property name="minimum_size"></property> | ||
| 11703 | <property name="name">bSizer80</property> | ||
| 11704 | <property name="orient">wxHORIZONTAL</property> | ||
| 11705 | <property name="permission">none</property> | ||
| 11706 | <object class="sizeritem" expanded="1"> | ||
| 11707 | <property name="border">5</property> | ||
| 11708 | <property name="flag">wxEXPAND</property> | ||
| 11709 | <property name="proportion">1</property> | ||
| 11710 | <object class="spacer" expanded="1"> | ||
| 11711 | <property name="height">0</property> | ||
| 11712 | <property name="permission">protected</property> | ||
| 11713 | <property name="width">0</property> | ||
| 11714 | </object> | ||
| 11715 | </object> | ||
| 11716 | <object class="sizeritem" expanded="1"> | ||
| 11717 | <property name="border">5</property> | ||
| 11718 | <property name="flag">wxALL</property> | ||
| 11719 | <property name="proportion">0</property> | ||
| 11720 | <object class="wxButton" expanded="1"> | ||
| 11721 | <property name="bg"></property> | ||
| 11722 | <property name="context_help"></property> | ||
| 11723 | <property name="default">0</property> | ||
| 11724 | <property name="enabled">1</property> | ||
| 11725 | <property name="fg"></property> | ||
| 11726 | <property name="font"></property> | ||
| 11727 | <property name="hidden">0</property> | ||
| 11728 | <property name="id">wxID_OK</property> | ||
| 11729 | <property name="label">OK</property> | ||
| 11730 | <property name="maximum_size"></property> | ||
| 11731 | <property name="minimum_size">85,25</property> | ||
| 11732 | <property name="name">m_buttonOK</property> | ||
| 11733 | <property name="permission">protected</property> | ||
| 11734 | <property name="pos"></property> | ||
| 11735 | <property name="size">-1,-1</property> | ||
| 11736 | <property name="style"></property> | ||
| 11737 | <property name="subclass"></property> | ||
| 11738 | <property name="tooltip"></property> | ||
| 11739 | <property name="window_extra_style"></property> | ||
| 11740 | <property name="window_name"></property> | ||
| 11741 | <property name="window_style"></property> | ||
| 11742 | <event name="OnButtonClick">OnButtonOK</event> | ||
| 11743 | <event name="OnChar"></event> | ||
| 11744 | <event name="OnEnterWindow"></event> | ||
| 11745 | <event name="OnEraseBackground"></event> | ||
| 11746 | <event name="OnKeyDown"></event> | ||
| 11747 | <event name="OnKeyUp"></event> | ||
| 11748 | <event name="OnKillFocus"></event> | ||
| 11749 | <event name="OnLeaveWindow"></event> | ||
| 11750 | <event name="OnLeftDClick"></event> | ||
| 11751 | <event name="OnLeftDown"></event> | ||
| 11752 | <event name="OnLeftUp"></event> | ||
| 11753 | <event name="OnMiddleDClick"></event> | ||
| 11754 | <event name="OnMiddleDown"></event> | ||
| 11755 | <event name="OnMiddleUp"></event> | ||
| 11756 | <event name="OnMotion"></event> | ||
| 11757 | <event name="OnMouseEvents"></event> | ||
| 11758 | <event name="OnMouseWheel"></event> | ||
| 11759 | <event name="OnPaint"></event> | ||
| 11760 | <event name="OnRightDClick"></event> | ||
| 11761 | <event name="OnRightDown"></event> | ||
| 11762 | <event name="OnRightUp"></event> | ||
| 11763 | <event name="OnSetFocus"></event> | ||
| 11764 | <event name="OnSize"></event> | ||
| 11765 | <event name="OnUpdateUI"></event> | ||
| 11766 | </object> | ||
| 11767 | </object> | ||
| 11768 | <object class="sizeritem" expanded="1"> | ||
| 11769 | <property name="border">5</property> | ||
| 11770 | <property name="flag">wxALL</property> | ||
| 11771 | <property name="proportion">0</property> | ||
| 11772 | <object class="wxButton" expanded="1"> | ||
| 11773 | <property name="bg"></property> | ||
| 11774 | <property name="context_help"></property> | ||
| 11775 | <property name="default">0</property> | ||
| 11776 | <property name="enabled">1</property> | ||
| 11777 | <property name="fg"></property> | ||
| 11778 | <property name="font"></property> | ||
| 11779 | <property name="hidden">0</property> | ||
| 11780 | <property name="id">wxID_CANCEL</property> | ||
| 11781 | <property name="label">Cancel</property> | ||
| 11782 | <property name="maximum_size"></property> | ||
| 11783 | <property name="minimum_size">85,25</property> | ||
| 11784 | <property name="name">m_buttonCancel</property> | ||
| 11785 | <property name="permission">protected</property> | ||
| 11786 | <property name="pos"></property> | ||
| 11787 | <property name="size"></property> | ||
| 11788 | <property name="style"></property> | ||
| 11789 | <property name="subclass"></property> | ||
| 11790 | <property name="tooltip"></property> | ||
| 11791 | <property name="window_extra_style"></property> | ||
| 11792 | <property name="window_name"></property> | ||
| 11793 | <property name="window_style"></property> | ||
| 11794 | <event name="OnButtonClick">OnButtonCancel</event> | ||
| 11795 | <event name="OnChar"></event> | ||
| 11796 | <event name="OnEnterWindow"></event> | ||
| 11797 | <event name="OnEraseBackground"></event> | ||
| 11798 | <event name="OnKeyDown"></event> | ||
| 11799 | <event name="OnKeyUp"></event> | ||
| 11800 | <event name="OnKillFocus"></event> | ||
| 11801 | <event name="OnLeaveWindow"></event> | ||
| 11802 | <event name="OnLeftDClick"></event> | ||
| 11803 | <event name="OnLeftDown"></event> | ||
| 11804 | <event name="OnLeftUp"></event> | ||
| 11805 | <event name="OnMiddleDClick"></event> | ||
| 11806 | <event name="OnMiddleDown"></event> | ||
| 11807 | <event name="OnMiddleUp"></event> | ||
| 11808 | <event name="OnMotion"></event> | ||
| 11809 | <event name="OnMouseEvents"></event> | ||
| 11810 | <event name="OnMouseWheel"></event> | ||
| 11811 | <event name="OnPaint"></event> | ||
| 11812 | <event name="OnRightDClick"></event> | ||
| 11813 | <event name="OnRightDown"></event> | ||
| 11814 | <event name="OnRightUp"></event> | ||
| 11815 | <event name="OnSetFocus"></event> | ||
| 11816 | <event name="OnSize"></event> | ||
| 11817 | <event name="OnUpdateUI"></event> | ||
| 11818 | </object> | ||
| 11819 | </object> | ||
| 11820 | </object> | ||
| 11821 | </object> | ||
| 11822 | </object> | ||
| 11823 | </object> | ||
| 11824 | </object> | ||
| 11825 | </wxFormBuilder_Project> | ||
diff --git a/src/util.cpp b/src/util.cpp new file mode 100644 index 0000000..0b794d4 --- /dev/null +++ b/src/util.cpp | |||
| @@ -0,0 +1,393 @@ | |||
| 1 | // Copyright (c) 2009 Satoshi Nakamoto | ||
| 2 | // Distributed under the MIT/X11 software license, see the accompanying | ||
| 3 | // file license.txt or http://www.opensource.org/licenses/mit-license.php. | ||
| 4 | |||
| 5 | #include "headers.h" | ||
| 6 | |||
| 7 | |||
| 8 | |||
| 9 | bool fDebug = false; | ||
| 10 | |||
| 11 | |||
| 12 | |||
| 13 | |||
| 14 | #ifdef _WIN32 | ||
| 15 | // Init openssl library multithreading support (OpenSSL < 1.1 needed callbacks; | ||
| 16 | // OpenSSL 1.1+/3 is internally thread-safe, so the Linux build skips this). | ||
| 17 | static HANDLE* lock_cs; | ||
| 18 | |||
| 19 | void win32_locking_callback(int mode, int type, const char* file, int line) | ||
| 20 | { | ||
| 21 | if (mode & CRYPTO_LOCK) | ||
| 22 | WaitForSingleObject(lock_cs[type], INFINITE); | ||
| 23 | else | ||
| 24 | ReleaseMutex(lock_cs[type]); | ||
| 25 | } | ||
| 26 | #endif | ||
| 27 | |||
| 28 | // Init | ||
| 29 | class CInit | ||
| 30 | { | ||
| 31 | public: | ||
| 32 | CInit() | ||
| 33 | { | ||
| 34 | #ifdef _WIN32 | ||
| 35 | // Init openssl library multithreading support | ||
| 36 | lock_cs = (HANDLE*)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(HANDLE)); | ||
| 37 | for (int i = 0; i < CRYPTO_num_locks(); i++) | ||
| 38 | lock_cs[i] = CreateMutex(NULL,FALSE,NULL); | ||
| 39 | CRYPTO_set_locking_callback(win32_locking_callback); | ||
| 40 | |||
| 41 | // Seed random number generator with screen scrape and other hardware sources | ||
| 42 | RAND_screen(); | ||
| 43 | #endif | ||
| 44 | // Seed random number generator with perfmon / high-res timer data | ||
| 45 | RandAddSeed(true); | ||
| 46 | } | ||
| 47 | ~CInit() | ||
| 48 | { | ||
| 49 | #ifdef _WIN32 | ||
| 50 | // Shutdown openssl library multithreading support | ||
| 51 | CRYPTO_set_locking_callback(NULL); | ||
| 52 | for (int i =0 ; i < CRYPTO_num_locks(); i++) | ||
| 53 | CloseHandle(lock_cs[i]); | ||
| 54 | OPENSSL_free(lock_cs); | ||
| 55 | #endif | ||
| 56 | } | ||
| 57 | } | ||
| 58 | instance_of_cinit; | ||
| 59 | |||
| 60 | |||
| 61 | |||
| 62 | |||
| 63 | void RandAddSeed(bool fPerfmon) | ||
| 64 | { | ||
| 65 | #ifdef _WIN32 | ||
| 66 | // Seed with CPU performance counter | ||
| 67 | LARGE_INTEGER PerformanceCount; | ||
| 68 | QueryPerformanceCounter(&PerformanceCount); | ||
| 69 | RAND_add(&PerformanceCount, sizeof(PerformanceCount), 1.5); | ||
| 70 | memset(&PerformanceCount, 0, sizeof(PerformanceCount)); | ||
| 71 | |||
| 72 | static int64 nLastPerfmon; | ||
| 73 | if (fPerfmon || GetTime() > nLastPerfmon + 5 * 60) | ||
| 74 | { | ||
| 75 | nLastPerfmon = GetTime(); | ||
| 76 | |||
| 77 | // Seed with the entire set of perfmon data | ||
| 78 | unsigned char pdata[250000]; | ||
| 79 | memset(pdata, 0, sizeof(pdata)); | ||
| 80 | unsigned long nSize = sizeof(pdata); | ||
| 81 | long ret = RegQueryValueEx(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, pdata, &nSize); | ||
| 82 | RegCloseKey(HKEY_PERFORMANCE_DATA); | ||
| 83 | if (ret == ERROR_SUCCESS) | ||
| 84 | { | ||
| 85 | uint256 hash; | ||
| 86 | SHA256(pdata, nSize, (unsigned char*)&hash); | ||
| 87 | RAND_add(&hash, sizeof(hash), min(nSize/500.0, (double)sizeof(hash))); | ||
| 88 | hash = 0; | ||
| 89 | memset(pdata, 0, nSize); | ||
| 90 | printf("RandAddSeed() got %d bytes of performance data\n", nSize); | ||
| 91 | } | ||
| 92 | } | ||
| 93 | #else | ||
| 94 | // Seed with a high-resolution timer; OpenSSL also seeds itself from | ||
| 95 | // /dev/urandom, so this is just extra entropy. No perfmon on Linux. | ||
| 96 | (void)fPerfmon; | ||
| 97 | struct timespec ts; | ||
| 98 | clock_gettime(CLOCK_MONOTONIC, &ts); | ||
| 99 | RAND_add(&ts, sizeof(ts), 1.5); | ||
| 100 | memset(&ts, 0, sizeof(ts)); | ||
| 101 | #endif | ||
| 102 | } | ||
| 103 | |||
| 104 | |||
| 105 | |||
| 106 | |||
| 107 | |||
| 108 | |||
| 109 | |||
| 110 | |||
| 111 | |||
| 112 | |||
| 113 | // Safer snprintf | ||
| 114 | // - prints up to limit-1 characters | ||
| 115 | // - output string is always null terminated even if limit reached | ||
| 116 | // - return value is the number of characters actually printed | ||
| 117 | int my_snprintf(char* buffer, size_t limit, const char* format, ...) | ||
| 118 | { | ||
| 119 | if (limit == 0) | ||
| 120 | return 0; | ||
| 121 | va_list arg_ptr; | ||
| 122 | va_start(arg_ptr, format); | ||
| 123 | int ret = _vsnprintf(buffer, limit, format, arg_ptr); | ||
| 124 | va_end(arg_ptr); | ||
| 125 | if (ret < 0 || ret >= limit) | ||
| 126 | { | ||
| 127 | ret = limit - 1; | ||
| 128 | buffer[limit-1] = 0; | ||
| 129 | } | ||
| 130 | return ret; | ||
| 131 | } | ||
| 132 | |||
| 133 | |||
| 134 | string strprintf(const char* format, ...) | ||
| 135 | { | ||
| 136 | char buffer[50000]; | ||
| 137 | char* p = buffer; | ||
| 138 | int limit = sizeof(buffer); | ||
| 139 | int ret; | ||
| 140 | loop | ||
| 141 | { | ||
| 142 | va_list arg_ptr; | ||
| 143 | va_start(arg_ptr, format); | ||
| 144 | ret = _vsnprintf(p, limit, format, arg_ptr); | ||
| 145 | va_end(arg_ptr); | ||
| 146 | if (ret >= 0 && ret < limit) | ||
| 147 | break; | ||
| 148 | if (p != buffer) | ||
| 149 | delete p; | ||
| 150 | limit *= 2; | ||
| 151 | p = new char[limit]; | ||
| 152 | if (p == NULL) | ||
| 153 | throw std::bad_alloc(); | ||
| 154 | } | ||
| 155 | #ifdef _MSC_VER | ||
| 156 | // msvc optimisation | ||
| 157 | if (p == buffer) | ||
| 158 | return string(p, p+ret); | ||
| 159 | #endif | ||
| 160 | string str(p, p+ret); | ||
| 161 | if (p != buffer) | ||
| 162 | delete p; | ||
| 163 | return str; | ||
| 164 | } | ||
| 165 | |||
| 166 | |||
| 167 | bool error(const char* format, ...) | ||
| 168 | { | ||
| 169 | char buffer[50000]; | ||
| 170 | int limit = sizeof(buffer); | ||
| 171 | va_list arg_ptr; | ||
| 172 | va_start(arg_ptr, format); | ||
| 173 | int ret = _vsnprintf(buffer, limit, format, arg_ptr); | ||
| 174 | va_end(arg_ptr); | ||
| 175 | if (ret < 0 || ret >= limit) | ||
| 176 | { | ||
| 177 | ret = limit - 1; | ||
| 178 | buffer[limit-1] = 0; | ||
| 179 | } | ||
| 180 | printf("ERROR: %s\n", buffer); | ||
| 181 | return false; | ||
| 182 | } | ||
| 183 | |||
| 184 | |||
| 185 | void PrintException(std::exception* pex, const char* pszThread) | ||
| 186 | { | ||
| 187 | char pszModule[260]; | ||
| 188 | pszModule[0] = '\0'; | ||
| 189 | #ifdef _WIN32 | ||
| 190 | GetModuleFileName(NULL, pszModule, sizeof(pszModule)); | ||
| 191 | _strlwr(pszModule); | ||
| 192 | #else | ||
| 193 | strncpy(pszModule, "bitflash-node", sizeof(pszModule) - 1); | ||
| 194 | #endif | ||
| 195 | char pszMessage[1000]; | ||
| 196 | if (pex) | ||
| 197 | snprintf(pszMessage, sizeof(pszMessage), | ||
| 198 | "EXCEPTION: %s \n%s \n%s in %s \n", typeid(*pex).name(), pex->what(), pszModule, pszThread); | ||
| 199 | else | ||
| 200 | snprintf(pszMessage, sizeof(pszMessage), | ||
| 201 | "UNKNOWN EXCEPTION \n%s in %s \n", pszModule, pszThread); | ||
| 202 | printf("\n\n************************\n%s", pszMessage); | ||
| 203 | if (wxTheApp) | ||
| 204 | wxMessageBox(pszMessage, "Error", wxOK | wxICON_ERROR); | ||
| 205 | throw; | ||
| 206 | //DebugBreak(); | ||
| 207 | } | ||
| 208 | |||
| 209 | |||
| 210 | void ParseString(const string& str, char c, vector<string>& v) | ||
| 211 | { | ||
| 212 | unsigned int i1 = 0; | ||
| 213 | unsigned int i2; | ||
| 214 | do | ||
| 215 | { | ||
| 216 | i2 = str.find(c, i1); | ||
| 217 | v.push_back(str.substr(i1, i2-i1)); | ||
| 218 | i1 = i2+1; | ||
| 219 | } | ||
| 220 | while (i2 != str.npos); | ||
| 221 | } | ||
| 222 | |||
| 223 | |||
| 224 | string FormatMoney(int64 n, bool fPlus) | ||
| 225 | { | ||
| 226 | n /= CENT; | ||
| 227 | string str = strprintf("%I64d.%02I64d", (n > 0 ? n : -n)/100, (n > 0 ? n : -n)%100); | ||
| 228 | for (int i = 6; i < str.size(); i += 4) | ||
| 229 | if (isdigit(str[str.size() - i - 1])) | ||
| 230 | str.insert(str.size() - i, 1, ','); | ||
| 231 | if (n < 0) | ||
| 232 | str.insert((unsigned int)0, 1, '-'); | ||
| 233 | else if (fPlus && n > 0) | ||
| 234 | str.insert((unsigned int)0, 1, '+'); | ||
| 235 | return str; | ||
| 236 | } | ||
| 237 | |||
| 238 | bool ParseMoney(const char* pszIn, int64& nRet) | ||
| 239 | { | ||
| 240 | string strWhole; | ||
| 241 | int64 nCents = 0; | ||
| 242 | const char* p = pszIn; | ||
| 243 | while (isspace(*p)) | ||
| 244 | p++; | ||
| 245 | for (; *p; p++) | ||
| 246 | { | ||
| 247 | if (*p == ',' && p > pszIn && isdigit(p[-1]) && isdigit(p[1]) && isdigit(p[2]) && isdigit(p[3]) && !isdigit(p[4])) | ||
| 248 | continue; | ||
| 249 | if (*p == '.') | ||
| 250 | { | ||
| 251 | p++; | ||
| 252 | if (!isdigit(p[0]) || !isdigit(p[1])) | ||
| 253 | return false; | ||
| 254 | nCents = atoi64(p); | ||
| 255 | if (nCents < 0 || nCents > 99) | ||
| 256 | return false; | ||
| 257 | p += 2; | ||
| 258 | break; | ||
| 259 | } | ||
| 260 | if (isspace(*p)) | ||
| 261 | break; | ||
| 262 | if (!isdigit(*p)) | ||
| 263 | return false; | ||
| 264 | strWhole.insert(strWhole.end(), *p); | ||
| 265 | } | ||
| 266 | for (; *p; p++) | ||
| 267 | if (!isspace(*p)) | ||
| 268 | return false; | ||
| 269 | if (strWhole.size() > 17) | ||
| 270 | return false; | ||
| 271 | int64 nWhole = atoi64(strWhole); | ||
| 272 | int64 nValue = nWhole * 100 + nCents; | ||
| 273 | if (nValue / 100 != nWhole) | ||
| 274 | return false; | ||
| 275 | nValue *= CENT; | ||
| 276 | nRet = nValue; | ||
| 277 | return true; | ||
| 278 | } | ||
| 279 | |||
| 280 | |||
| 281 | |||
| 282 | |||
| 283 | |||
| 284 | |||
| 285 | |||
| 286 | |||
| 287 | |||
| 288 | |||
| 289 | bool FileExists(const char* psz) | ||
| 290 | { | ||
| 291 | #ifdef WIN32 | ||
| 292 | return GetFileAttributes(psz) != -1; | ||
| 293 | #else | ||
| 294 | return access(psz, 0) != -1; | ||
| 295 | #endif | ||
| 296 | } | ||
| 297 | |||
| 298 | int GetFilesize(FILE* file) | ||
| 299 | { | ||
| 300 | int nSavePos = ftell(file); | ||
| 301 | int nFilesize = -1; | ||
| 302 | if (fseek(file, 0, SEEK_END) == 0) | ||
| 303 | nFilesize = ftell(file); | ||
| 304 | fseek(file, nSavePos, SEEK_SET); | ||
| 305 | return nFilesize; | ||
| 306 | } | ||
| 307 | |||
| 308 | |||
| 309 | |||
| 310 | |||
| 311 | |||
| 312 | |||
| 313 | |||
| 314 | |||
| 315 | uint64 GetRand(uint64 nMax) | ||
| 316 | { | ||
| 317 | if (nMax == 0) | ||
| 318 | return 0; | ||
| 319 | |||
| 320 | // The range of the random source must be a multiple of the modulus | ||
| 321 | // to give every possible output value an equal possibility | ||
| 322 | uint64 nRange = (_UI64_MAX / nMax) * nMax; | ||
| 323 | uint64 nRand = 0; | ||
| 324 | do | ||
| 325 | RAND_bytes((unsigned char*)&nRand, sizeof(nRand)); | ||
| 326 | while (nRand >= nRange); | ||
| 327 | return (nRand % nMax); | ||
| 328 | } | ||
| 329 | |||
| 330 | |||
| 331 | |||
| 332 | |||
| 333 | |||
| 334 | |||
| 335 | |||
| 336 | |||
| 337 | |||
| 338 | |||
| 339 | // | ||
| 340 | // "Never go to sea with two chronometers; take one or three." | ||
| 341 | // Our three chronometers are: | ||
| 342 | // - System clock | ||
| 343 | // - Median of other server's clocks | ||
| 344 | // - NTP servers | ||
| 345 | // | ||
| 346 | // note: NTP isn't implemented yet, so until then we just use the median | ||
| 347 | // of other nodes clocks to correct ours. | ||
| 348 | // | ||
| 349 | |||
| 350 | int64 GetTime() | ||
| 351 | { | ||
| 352 | return time(NULL); | ||
| 353 | } | ||
| 354 | |||
| 355 | static int64 nTimeOffset = 0; | ||
| 356 | |||
| 357 | int64 GetAdjustedTime() | ||
| 358 | { | ||
| 359 | return GetTime() + nTimeOffset; | ||
| 360 | } | ||
| 361 | |||
| 362 | void AddTimeData(unsigned int ip, int64 nTime) | ||
| 363 | { | ||
| 364 | int64 nOffsetSample = nTime - GetTime(); | ||
| 365 | |||
| 366 | // Ignore duplicates | ||
| 367 | static set<unsigned int> setKnown; | ||
| 368 | if (!setKnown.insert(ip).second) | ||
| 369 | return; | ||
| 370 | |||
| 371 | // Add data | ||
| 372 | static vector<int64> vTimeOffsets; | ||
| 373 | if (vTimeOffsets.empty()) | ||
| 374 | vTimeOffsets.push_back(0); | ||
| 375 | vTimeOffsets.push_back(nOffsetSample); | ||
| 376 | printf("Added time data, samples %d, ip %08x, offset %+I64d (%+I64d minutes)\n", vTimeOffsets.size(), ip, vTimeOffsets.back(), vTimeOffsets.back()/60); | ||
| 377 | if (vTimeOffsets.size() >= 5 && vTimeOffsets.size() % 2 == 1) | ||
| 378 | { | ||
| 379 | sort(vTimeOffsets.begin(), vTimeOffsets.end()); | ||
| 380 | int64 nMedian = vTimeOffsets[vTimeOffsets.size()/2]; | ||
| 381 | nTimeOffset = nMedian; | ||
| 382 | if ((nMedian > 0 ? nMedian : -nMedian) > 5 * 60) | ||
| 383 | { | ||
| 384 | // Only let other nodes change our clock so far before we | ||
| 385 | // go to the NTP servers | ||
| 386 | /// todo: Get time from NTP servers, then set a flag | ||
| 387 | /// to make sure it doesn't get changed again | ||
| 388 | } | ||
| 389 | foreach(int64 n, vTimeOffsets) | ||
| 390 | printf("%+I64d ", n); | ||
| 391 | printf("| nTimeOffset = %+I64d (%+I64d minutes)\n", nTimeOffset, nTimeOffset/60); | ||
| 392 | } | ||
| 393 | } | ||
diff --git a/src/util.h b/src/util.h new file mode 100644 index 0000000..96cb4d4 --- /dev/null +++ b/src/util.h | |||
| @@ -0,0 +1,413 @@ | |||
| 1 | // Copyright (c) 2009 Satoshi Nakamoto | ||
| 2 | // Distributed under the MIT/X11 software license, see the accompanying | ||
| 3 | // file license.txt or http://www.opensource.org/licenses/mit-license.php. | ||
| 4 | |||
| 5 | |||
| 6 | #if defined(_MSC_VER) || defined(__BORLANDC__) | ||
| 7 | typedef __int64 int64; | ||
| 8 | typedef unsigned __int64 uint64; | ||
| 9 | #else | ||
| 10 | typedef long long int64; | ||
| 11 | typedef unsigned long long uint64; | ||
| 12 | #endif | ||
| 13 | #if defined(_MSC_VER) && _MSC_VER < 1300 | ||
| 14 | #define for if (false) ; else for | ||
| 15 | #endif | ||
| 16 | |||
| 17 | #ifndef _MSC_VER | ||
| 18 | #define __forceinline inline | ||
| 19 | #endif | ||
| 20 | |||
| 21 | #define foreach BOOST_FOREACH | ||
| 22 | #define loop for (;;) | ||
| 23 | #define BEGIN(a) ((char*)&(a)) | ||
| 24 | #define END(a) ((char*)&((&(a))[1])) | ||
| 25 | #define UBEGIN(a) ((unsigned char*)&(a)) | ||
| 26 | #define UEND(a) ((unsigned char*)&((&(a))[1])) | ||
| 27 | #define ARRAYLEN(array) (sizeof(array)/sizeof((array)[0])) | ||
| 28 | |||
| 29 | // Route printf to debug.log (and the console) on the GUI Windows build and on | ||
| 30 | // the headless Linux build alike. | ||
| 31 | #if defined(_WINDOWS) || !defined(_WIN32) | ||
| 32 | #define printf OutputDebugStringF | ||
| 33 | #endif | ||
| 34 | |||
| 35 | #ifdef snprintf | ||
| 36 | #undef snprintf | ||
| 37 | #endif | ||
| 38 | #define snprintf my_snprintf | ||
| 39 | |||
| 40 | #ifndef PRId64 | ||
| 41 | #if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__MSVCRT__) | ||
| 42 | #define PRId64 "I64d" | ||
| 43 | #define PRIu64 "I64u" | ||
| 44 | #define PRIx64 "I64x" | ||
| 45 | #else | ||
| 46 | #define PRId64 "lld" | ||
| 47 | #define PRIu64 "llu" | ||
| 48 | #define PRIx64 "llx" | ||
| 49 | #endif | ||
| 50 | #endif | ||
| 51 | |||
| 52 | // This is needed because the foreach macro can't get over the comma in pair<t1, t2> | ||
| 53 | #define PAIRTYPE(t1, t2) pair<t1, t2> | ||
| 54 | |||
| 55 | // Used to bypass the rule against non-const reference to temporary | ||
| 56 | // where it makes sense with wrappers such as CFlatData or CTxDB | ||
| 57 | template<typename T> | ||
| 58 | inline T& REF(const T& val) | ||
| 59 | { | ||
| 60 | return (T&)val; | ||
| 61 | } | ||
| 62 | |||
| 63 | |||
| 64 | |||
| 65 | |||
| 66 | |||
| 67 | |||
| 68 | |||
| 69 | |||
| 70 | |||
| 71 | extern bool fDebug; | ||
| 72 | |||
| 73 | void RandAddSeed(bool fPerfmon=false); | ||
| 74 | int my_snprintf(char* buffer, size_t limit, const char* format, ...); | ||
| 75 | string strprintf(const char* format, ...); | ||
| 76 | bool error(const char* format, ...); | ||
| 77 | void PrintException(std::exception* pex, const char* pszThread); | ||
| 78 | void ParseString(const string& str, char c, vector<string>& v); | ||
| 79 | string FormatMoney(int64 n, bool fPlus=false); | ||
| 80 | bool ParseMoney(const char* pszIn, int64& nRet); | ||
| 81 | bool FileExists(const char* psz); | ||
| 82 | int GetFilesize(FILE* file); | ||
| 83 | uint64 GetRand(uint64 nMax); | ||
| 84 | int64 GetTime(); | ||
| 85 | int64 GetAdjustedTime(); | ||
| 86 | void AddTimeData(unsigned int ip, int64 nTime); | ||
| 87 | |||
| 88 | |||
| 89 | |||
| 90 | |||
| 91 | |||
| 92 | |||
| 93 | |||
| 94 | |||
| 95 | |||
| 96 | |||
| 97 | |||
| 98 | |||
| 99 | // Wrapper to automatically initialize critical section | ||
| 100 | // Could use wxCriticalSection for portability, but it doesn't support TryEnterCriticalSection | ||
| 101 | class CCriticalSection | ||
| 102 | { | ||
| 103 | protected: | ||
| 104 | CRITICAL_SECTION cs; | ||
| 105 | public: | ||
| 106 | char* pszFile; | ||
| 107 | int nLine; | ||
| 108 | explicit CCriticalSection() { InitializeCriticalSection(&cs); } | ||
| 109 | ~CCriticalSection() { DeleteCriticalSection(&cs); } | ||
| 110 | void Enter() { EnterCriticalSection(&cs); } | ||
| 111 | void Leave() { LeaveCriticalSection(&cs); } | ||
| 112 | bool TryEnter() { return TryEnterCriticalSection(&cs); } | ||
| 113 | CRITICAL_SECTION* operator&() { return &cs; } | ||
| 114 | }; | ||
| 115 | |||
| 116 | // Automatically leave critical section when leaving block, needed for exception safety | ||
| 117 | class CCriticalBlock | ||
| 118 | { | ||
| 119 | protected: | ||
| 120 | CRITICAL_SECTION* pcs; | ||
| 121 | public: | ||
| 122 | CCriticalBlock(CRITICAL_SECTION& csIn) { pcs = &csIn; EnterCriticalSection(pcs); } | ||
| 123 | CCriticalBlock(CCriticalSection& csIn) { pcs = &csIn; EnterCriticalSection(pcs); } | ||
| 124 | ~CCriticalBlock() { LeaveCriticalSection(pcs); } | ||
| 125 | }; | ||
| 126 | |||
| 127 | // WARNING: This will catch continue and break! | ||
| 128 | // break is caught with an assertion, but there's no way to detect continue. | ||
| 129 | // I'd rather be careful than suffer the other more error prone syntax. | ||
| 130 | // The compiler will optimise away all this loop junk. | ||
| 131 | #define CRITICAL_BLOCK(cs) \ | ||
| 132 | for (bool fcriticalblockonce=true; fcriticalblockonce; assert(("break caught by CRITICAL_BLOCK!", !fcriticalblockonce)), fcriticalblockonce=false) \ | ||
| 133 | for (CCriticalBlock criticalblock(cs); fcriticalblockonce && (cs.pszFile=__FILE__, cs.nLine=__LINE__, true); fcriticalblockonce=false, cs.pszFile=NULL, cs.nLine=0) | ||
| 134 | |||
| 135 | class CTryCriticalBlock | ||
| 136 | { | ||
| 137 | protected: | ||
| 138 | CRITICAL_SECTION* pcs; | ||
| 139 | public: | ||
| 140 | CTryCriticalBlock(CRITICAL_SECTION& csIn) { pcs = (TryEnterCriticalSection(&csIn) ? &csIn : NULL); } | ||
| 141 | CTryCriticalBlock(CCriticalSection& csIn) { pcs = (TryEnterCriticalSection(&csIn) ? &csIn : NULL); } | ||
| 142 | ~CTryCriticalBlock() { if (pcs) LeaveCriticalSection(pcs); } | ||
| 143 | bool Entered() { return pcs != NULL; } | ||
| 144 | }; | ||
| 145 | |||
| 146 | #define TRY_CRITICAL_BLOCK(cs) \ | ||
| 147 | for (bool fcriticalblockonce=true; fcriticalblockonce; assert(("break caught by TRY_CRITICAL_BLOCK!", !fcriticalblockonce)), fcriticalblockonce=false) \ | ||
| 148 | for (CTryCriticalBlock criticalblock(cs); fcriticalblockonce && (fcriticalblockonce = criticalblock.Entered()) && (cs.pszFile=__FILE__, cs.nLine=__LINE__, true); fcriticalblockonce=false, cs.pszFile=NULL, cs.nLine=0) | ||
| 149 | |||
| 150 | |||
| 151 | |||
| 152 | |||
| 153 | |||
| 154 | |||
| 155 | |||
| 156 | |||
| 157 | |||
| 158 | |||
| 159 | |||
| 160 | |||
| 161 | inline string i64tostr(int64 n) | ||
| 162 | { | ||
| 163 | return strprintf("%" PRId64, n); | ||
| 164 | } | ||
| 165 | |||
| 166 | inline string itostr(int n) | ||
| 167 | { | ||
| 168 | return strprintf("%d", n); | ||
| 169 | } | ||
| 170 | |||
| 171 | inline int64 atoi64(const char* psz) | ||
| 172 | { | ||
| 173 | #ifdef _MSC_VER | ||
| 174 | return _atoi64(psz); | ||
| 175 | #else | ||
| 176 | return strtoll(psz, NULL, 10); | ||
| 177 | #endif | ||
| 178 | } | ||
| 179 | |||
| 180 | inline int64 atoi64(const string& str) | ||
| 181 | { | ||
| 182 | #ifdef _MSC_VER | ||
| 183 | return _atoi64(str.c_str()); | ||
| 184 | #else | ||
| 185 | return strtoll(str.c_str(), NULL, 10); | ||
| 186 | #endif | ||
| 187 | } | ||
| 188 | |||
| 189 | inline int atoi(const string& str) | ||
| 190 | { | ||
| 191 | return atoi(str.c_str()); | ||
| 192 | } | ||
| 193 | |||
| 194 | inline int roundint(double d) | ||
| 195 | { | ||
| 196 | return (int)(d > 0 ? d + 0.5 : d - 0.5); | ||
| 197 | } | ||
| 198 | |||
| 199 | template<typename T> | ||
| 200 | string HexStr(const T itbegin, const T itend, bool fSpaces=true) | ||
| 201 | { | ||
| 202 | const unsigned char* pbegin = (const unsigned char*)&itbegin[0]; | ||
| 203 | const unsigned char* pend = pbegin + (itend - itbegin) * sizeof(itbegin[0]); | ||
| 204 | string str; | ||
| 205 | for (const unsigned char* p = pbegin; p != pend; p++) | ||
| 206 | str += strprintf((fSpaces && p != pend-1 ? "%02x " : "%02x"), *p); | ||
| 207 | return str; | ||
| 208 | } | ||
| 209 | |||
| 210 | template<typename T> | ||
| 211 | string HexNumStr(const T itbegin, const T itend, bool f0x=true) | ||
| 212 | { | ||
| 213 | const unsigned char* pbegin = (const unsigned char*)&itbegin[0]; | ||
| 214 | const unsigned char* pend = pbegin + (itend - itbegin) * sizeof(itbegin[0]); | ||
| 215 | string str = (f0x ? "0x" : ""); | ||
| 216 | for (const unsigned char* p = pend-1; p >= pbegin; p--) | ||
| 217 | str += strprintf("%02X", *p); | ||
| 218 | return str; | ||
| 219 | } | ||
| 220 | |||
| 221 | template<typename T> | ||
| 222 | void PrintHex(const T pbegin, const T pend, const char* pszFormat="%s", bool fSpaces=true) | ||
| 223 | { | ||
| 224 | printf(pszFormat, HexStr(pbegin, pend, fSpaces).c_str()); | ||
| 225 | } | ||
| 226 | |||
| 227 | |||
| 228 | |||
| 229 | |||
| 230 | |||
| 231 | |||
| 232 | |||
| 233 | |||
| 234 | inline int OutputDebugStringF(const char* pszFormat, ...) | ||
| 235 | { | ||
| 236 | #if 1 // debug.log always enabled (was previously only under __WXDEBUG__) | ||
| 237 | // log file | ||
| 238 | FILE* fileout = fopen("debug.log", "a"); | ||
| 239 | if (fileout) | ||
| 240 | { | ||
| 241 | va_list arg_ptr; | ||
| 242 | va_start(arg_ptr, pszFormat); | ||
| 243 | vfprintf(fileout, pszFormat, arg_ptr); | ||
| 244 | va_end(arg_ptr); | ||
| 245 | fclose(fileout); | ||
| 246 | } | ||
| 247 | |||
| 248 | #ifndef _WIN32 | ||
| 249 | // Headless build: also echo to the console (the Windows path below returns | ||
| 250 | // early before reaching the console print, which is fine for the GUI app). | ||
| 251 | { | ||
| 252 | va_list arg_ptr; | ||
| 253 | va_start(arg_ptr, pszFormat); | ||
| 254 | vprintf(pszFormat, arg_ptr); | ||
| 255 | va_end(arg_ptr); | ||
| 256 | fflush(stdout); | ||
| 257 | } | ||
| 258 | #endif | ||
| 259 | |||
| 260 | // accumulate a line at a time | ||
| 261 | static CCriticalSection cs_OutputDebugStringF; | ||
| 262 | CRITICAL_BLOCK(cs_OutputDebugStringF) | ||
| 263 | { | ||
| 264 | static char pszBuffer[50000]; | ||
| 265 | static char* pend; | ||
| 266 | if (pend == NULL) | ||
| 267 | pend = pszBuffer; | ||
| 268 | va_list arg_ptr; | ||
| 269 | va_start(arg_ptr, pszFormat); | ||
| 270 | int limit = END(pszBuffer) - pend - 2; | ||
| 271 | int ret = _vsnprintf(pend, limit, pszFormat, arg_ptr); | ||
| 272 | va_end(arg_ptr); | ||
| 273 | if (ret < 0 || ret >= limit) | ||
| 274 | { | ||
| 275 | pend = END(pszBuffer) - 2; | ||
| 276 | *pend++ = '\n'; | ||
| 277 | } | ||
| 278 | else | ||
| 279 | pend += ret; | ||
| 280 | *pend = '\0'; | ||
| 281 | char* p1 = pszBuffer; | ||
| 282 | char* p2; | ||
| 283 | while (p2 = strchr(p1, '\n')) | ||
| 284 | { | ||
| 285 | p2++; | ||
| 286 | char c = *p2; | ||
| 287 | *p2 = '\0'; | ||
| 288 | OutputDebugStringA(p1); | ||
| 289 | *p2 = c; | ||
| 290 | p1 = p2; | ||
| 291 | } | ||
| 292 | if (p1 != pszBuffer) | ||
| 293 | memmove(pszBuffer, p1, pend - p1 + 1); | ||
| 294 | pend -= (p1 - pszBuffer); | ||
| 295 | return ret; | ||
| 296 | } | ||
| 297 | #endif | ||
| 298 | |||
| 299 | if (!wxTheApp) | ||
| 300 | { | ||
| 301 | // print to console | ||
| 302 | va_list arg_ptr; | ||
| 303 | va_start(arg_ptr, pszFormat); | ||
| 304 | vprintf(pszFormat, arg_ptr); | ||
| 305 | va_end(arg_ptr); | ||
| 306 | } | ||
| 307 | return 0; | ||
| 308 | } | ||
| 309 | |||
| 310 | |||
| 311 | |||
| 312 | |||
| 313 | |||
| 314 | |||
| 315 | |||
| 316 | |||
| 317 | |||
| 318 | inline void heapchk() | ||
| 319 | { | ||
| 320 | if (_heapchk() != _HEAPOK) | ||
| 321 | DebugBreak(); | ||
| 322 | } | ||
| 323 | |||
| 324 | // Randomize the stack to help protect against buffer overrun exploits | ||
| 325 | #define IMPLEMENT_RANDOMIZE_STACK(ThreadFn) \ | ||
| 326 | { \ | ||
| 327 | static char nLoops; \ | ||
| 328 | if (nLoops <= 0) \ | ||
| 329 | nLoops = GetRand(50) + 1; \ | ||
| 330 | if (nLoops-- > 1) \ | ||
| 331 | { \ | ||
| 332 | ThreadFn; \ | ||
| 333 | return; \ | ||
| 334 | } \ | ||
| 335 | } | ||
| 336 | |||
| 337 | #define CATCH_PRINT_EXCEPTION(pszFn) \ | ||
| 338 | catch (std::exception& e) { \ | ||
| 339 | PrintException(&e, (pszFn)); \ | ||
| 340 | } catch (...) { \ | ||
| 341 | PrintException(NULL, (pszFn)); \ | ||
| 342 | } | ||
| 343 | |||
| 344 | |||
| 345 | |||
| 346 | |||
| 347 | |||
| 348 | |||
| 349 | |||
| 350 | |||
| 351 | |||
| 352 | template<typename T1> | ||
| 353 | inline uint256 Hash(const T1 pbegin, const T1 pend) | ||
| 354 | { | ||
| 355 | uint256 hash1; | ||
| 356 | SHA256((unsigned char*)&pbegin[0], (pend - pbegin) * sizeof(pbegin[0]), (unsigned char*)&hash1); | ||
| 357 | uint256 hash2; | ||
| 358 | SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2); | ||
| 359 | return hash2; | ||
| 360 | } | ||
| 361 | |||
| 362 | template<typename T1, typename T2> | ||
| 363 | inline uint256 Hash(const T1 p1begin, const T1 p1end, | ||
| 364 | const T2 p2begin, const T2 p2end) | ||
| 365 | { | ||
| 366 | uint256 hash1; | ||
| 367 | SHA256_CTX ctx; | ||
| 368 | SHA256_Init(&ctx); | ||
| 369 | SHA256_Update(&ctx, (unsigned char*)&p1begin[0], (p1end - p1begin) * sizeof(p1begin[0])); | ||
| 370 | SHA256_Update(&ctx, (unsigned char*)&p2begin[0], (p2end - p2begin) * sizeof(p2begin[0])); | ||
| 371 | SHA256_Final((unsigned char*)&hash1, &ctx); | ||
| 372 | uint256 hash2; | ||
| 373 | SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2); | ||
| 374 | return hash2; | ||
| 375 | } | ||
| 376 | |||
| 377 | template<typename T1, typename T2, typename T3> | ||
| 378 | inline uint256 Hash(const T1 p1begin, const T1 p1end, | ||
| 379 | const T2 p2begin, const T2 p2end, | ||
| 380 | const T3 p3begin, const T3 p3end) | ||
| 381 | { | ||
| 382 | uint256 hash1; | ||
| 383 | SHA256_CTX ctx; | ||
| 384 | SHA256_Init(&ctx); | ||
| 385 | SHA256_Update(&ctx, (unsigned char*)&p1begin[0], (p1end - p1begin) * sizeof(p1begin[0])); | ||
| 386 | SHA256_Update(&ctx, (unsigned char*)&p2begin[0], (p2end - p2begin) * sizeof(p2begin[0])); | ||
| 387 | SHA256_Update(&ctx, (unsigned char*)&p3begin[0], (p3end - p3begin) * sizeof(p3begin[0])); | ||
| 388 | SHA256_Final((unsigned char*)&hash1, &ctx); | ||
| 389 | uint256 hash2; | ||
| 390 | SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2); | ||
| 391 | return hash2; | ||
| 392 | } | ||
| 393 | |||
| 394 | template<typename T> | ||
| 395 | uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=VERSION) | ||
| 396 | { | ||
| 397 | // Most of the time is spent allocating and deallocating CDataStream's | ||
| 398 | // buffer. If this ever needs to be optimized further, make a CStaticStream | ||
| 399 | // class with its buffer on the stack. | ||
| 400 | CDataStream ss(nType, nVersion); | ||
| 401 | ss.reserve(10000); | ||
| 402 | ss << obj; | ||
| 403 | return Hash(ss.begin(), ss.end()); | ||
| 404 | } | ||
| 405 | |||
| 406 | inline uint160 Hash160(const vector<unsigned char>& vch) | ||
| 407 | { | ||
| 408 | uint256 hash1; | ||
| 409 | SHA256(&vch[0], vch.size(), (unsigned char*)&hash1); | ||
| 410 | uint160 hash2; | ||
| 411 | RIPEMD160((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2); | ||
| 412 | return hash2; | ||
| 413 | } | ||