Skip to content

Commit b9503a1

Browse files
Improve QR view with more encoders
1 parent a2495e6 commit b9503a1

File tree

5 files changed

+221
-13
lines changed

5 files changed

+221
-13
lines changed

BitcoinTransactionTool/Backend/Encoders/Base16.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,14 @@ public static string Reverse(string hexToReverse)
6969
/// <summary>
7070
/// Converts a given base-16 encoded string to its byte array representation.
7171
/// </summary>
72-
/// <exception cref="ArgumentException"/>
72+
/// <exception cref="FormatException"/>
7373
/// <param name="hex">Hex to convert.</param>
7474
/// <returns>An array of bytes equivalant of the given base16 encoded string.</returns>
7575
public static byte[] ToByteArray(string hex)
7676
{
7777
if (!IsValid(hex))
7878
{
79-
throw new ArgumentException($"Input is not a valid hex. <{hex}>");
79+
throw new FormatException($"Input is not a valid hex. <{hex}>");
8080
}
8181

8282
if (hex.StartsWith(Prefix))

BitcoinTransactionTool/Properties/AssemblyInfo.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,5 +51,5 @@
5151
// You can specify all the values or you can default the Build and Revision Numbers
5252
// by using the '*' as shown below:
5353
// [assembly: AssemblyVersion("1.0.*")]
54-
[assembly: AssemblyVersion("0.10.0.2")]
55-
[assembly: AssemblyFileVersion("0.10.0.2")]
54+
[assembly: AssemblyVersion("0.10.1.0")]
55+
[assembly: AssemblyFileVersion("0.10.1.0")]

BitcoinTransactionTool/ViewModels/MainWindowViewModel.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -330,8 +330,12 @@ private bool CanMakeTx()
330330
public RelayCommand ShowQrWindowCommand { get; private set; }
331331
private void ShowQrWindow()
332332
{
333-
QrViewModel vm = new QrViewModel();
334-
vm.QRCode = TransactionQR.Build(RawTx);
333+
QrViewModel vm = new QrViewModel()
334+
{
335+
RawTx = this.RawTx,
336+
SelectedInEncoder = QrViewModel.Encoders.Base16,
337+
SelectedOutEncoder = QrViewModel.Encoders.Base16
338+
};
335339
winManager = new QrWinManager();
336340
winManager.Show(vm);
337341
}

BitcoinTransactionTool/ViewModels/QrViewModel.cs

Lines changed: 153 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,167 @@
33
// Distributed under the MIT software license, see the accompanying
44
// file LICENCE or http://www.opensource.org/licenses/mit-license.php.
55

6+
using BitcoinTransactionTool.Backend;
7+
using BitcoinTransactionTool.Backend.Encoders;
68
using BitcoinTransactionTool.Backend.MVVM;
9+
using QRCoder;
10+
using System;
11+
using System.Collections.Generic;
12+
using System.Drawing;
13+
using System.IO;
14+
using System.Linq;
15+
using System.Text;
716
using System.Windows.Media.Imaging;
817

918
namespace BitcoinTransactionTool.ViewModels
1019
{
11-
public class QrViewModel : InpcBase
20+
public class QrViewModel : ViewModelBase
1221
{
13-
private BitmapImage qRCode;
22+
public QrViewModel()
23+
{
24+
EncodingList = Enum.GetValues(typeof(Encoders)).Cast<Encoders>();
25+
ShowCommand = new RelayCommand(ShowQr, () => !string.IsNullOrEmpty(RawTx));
26+
}
27+
28+
29+
30+
public enum Encoders
31+
{
32+
UTF8,
33+
Base16,
34+
Base58,
35+
Base58Check,
36+
Base43,
37+
Base64
38+
}
39+
40+
private readonly Base58 b58enc = new Base58();
41+
private readonly Base43 b43enc = new Base43();
42+
43+
44+
45+
public IEnumerable<Encoders> EncodingList { get; private set; }
46+
47+
48+
private Encoders _encIn;
49+
public Encoders SelectedInEncoder
50+
{
51+
get => _encIn;
52+
set => SetField(ref _encIn, value);
53+
}
54+
55+
56+
private Encoders _encOut;
57+
public Encoders SelectedOutEncoder
58+
{
59+
get => _encOut;
60+
set => SetField(ref _encOut, value);
61+
}
62+
63+
64+
private string _tx;
65+
public string RawTx
66+
{
67+
get => _tx;
68+
set
69+
{
70+
if (SetField(ref _tx, value))
71+
{
72+
ShowCommand.RaiseCanExecuteChanged();
73+
}
74+
}
75+
}
76+
77+
78+
private BitmapImage _qr;
1479
public BitmapImage QRCode
1580
{
16-
get { return qRCode; }
17-
set { SetField(ref qRCode, value); }
81+
get => _qr;
82+
private set => SetField(ref _qr, value);
83+
}
84+
85+
86+
public RelayCommand ShowCommand { get; private set; }
87+
private void ShowQr()
88+
{
89+
try
90+
{
91+
Errors = string.Empty;
92+
93+
byte[] input = GetInput();
94+
string converted = (SelectedInEncoder == SelectedOutEncoder) ? RawTx : GetOutput(input);
95+
96+
97+
QRCodeGenerator qrGenerator = new QRCodeGenerator();
98+
QRCodeData qrCodeData = qrGenerator.CreateQrCode(converted, QRCodeGenerator.ECCLevel.Q);
99+
QRCode qrCode = new QRCode(qrCodeData);
100+
Bitmap qrCodeImage = qrCode.GetGraphic(20);
101+
102+
using (MemoryStream memory = new MemoryStream())
103+
{
104+
qrCodeImage.Save(memory, System.Drawing.Imaging.ImageFormat.Bmp);
105+
memory.Position = 0;
106+
BitmapImage bitmapimage = new BitmapImage();
107+
bitmapimage.BeginInit();
108+
bitmapimage.StreamSource = memory;
109+
bitmapimage.CacheOption = BitmapCacheOption.OnLoad;
110+
bitmapimage.EndInit();
111+
112+
QRCode = bitmapimage;
113+
}
114+
}
115+
catch (FormatException ex)
116+
{
117+
Errors = $"Invalid input format. Exception details: {ex.Message}";
118+
QRCode = null;
119+
}
120+
catch (Exception ex)
121+
{
122+
Errors = $"An unexpected exception of type {ex.GetType()} was thrown with message: {ex.Message}";
123+
QRCode = null;
124+
}
125+
}
126+
127+
private byte[] GetInput()
128+
{
129+
switch (SelectedInEncoder)
130+
{
131+
case Encoders.UTF8:
132+
return Encoding.UTF8.GetBytes(RawTx);
133+
case Encoders.Base16:
134+
return Base16.ToByteArray(RawTx);
135+
case Encoders.Base58:
136+
return b58enc.Decode(RawTx);
137+
case Encoders.Base58Check:
138+
return b58enc.DecodeWithCheckSum(RawTx);
139+
case Encoders.Base43:
140+
return b43enc.Decode(RawTx);
141+
case Encoders.Base64:
142+
return Convert.FromBase64String(RawTx);
143+
default:
144+
throw new ArgumentException($"Encoder type {SelectedInEncoder} is not defined.");
145+
}
18146
}
147+
private string GetOutput(byte[] input)
148+
{
149+
switch (SelectedOutEncoder)
150+
{
151+
case Encoders.UTF8:
152+
return Encoding.UTF8.GetString(input);
153+
case Encoders.Base16:
154+
return input.ToBase16();
155+
case Encoders.Base58:
156+
return b58enc.Encode(input);
157+
case Encoders.Base58Check:
158+
return b58enc.EncodeWithCheckSum(input);
159+
case Encoders.Base43:
160+
return b43enc.Encode(input);
161+
case Encoders.Base64:
162+
return Convert.ToBase64String(input);
163+
default:
164+
throw new ArgumentException($"Encoder type {SelectedInEncoder} is not defined.");
165+
}
166+
}
167+
19168
}
20169
}

BitcoinTransactionTool/Views/QrView.xaml

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,65 @@
22
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
33
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
44
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
5-
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
5+
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
66
xmlns:vm="clr-namespace:BitcoinTransactionTool.ViewModels"
7-
mc:Ignorable="d" Height="750" Width="750">
7+
mc:Ignorable="d"
8+
d:DataContext="{d:DesignInstance Type=vm:QrViewModel, IsDesignTimeCreatable=True}"
9+
Height="750" Width="750">
10+
11+
<UserControl.Resources>
12+
<Style x:Key="RadioButtonListBoxStyle" TargetType="{x:Type ListBox}">
13+
<Setter Property="BorderBrush" Value="Transparent"/>
14+
<Setter Property="KeyboardNavigation.DirectionalNavigation" Value="Cycle" />
15+
<Setter Property="ItemContainerStyle">
16+
<Setter.Value>
17+
<Style TargetType="{x:Type ListBoxItem}" >
18+
<Setter Property="Margin" Value="2, 2, 2, 0" />
19+
<Setter Property="Template">
20+
<Setter.Value>
21+
<ControlTemplate>
22+
<Border Background="Transparent">
23+
<RadioButton Content="{TemplateBinding ContentPresenter.Content}"
24+
VerticalAlignment="Center"
25+
IsChecked="{Binding Path=IsSelected,RelativeSource={RelativeSource TemplatedParent},Mode=TwoWay}"/>
26+
27+
</Border>
28+
</ControlTemplate>
29+
</Setter.Value>
30+
</Setter>
31+
</Style>
32+
</Setter.Value>
33+
</Setter>
34+
</Style>
35+
</UserControl.Resources>
36+
837
<Grid>
9-
<Image Source="{Binding QRCode}"/>
38+
<Grid.RowDefinitions>
39+
<RowDefinition Height="147"/>
40+
<RowDefinition/>
41+
<RowDefinition Height="auto"/>
42+
</Grid.RowDefinitions>
43+
44+
<StackPanel Orientation="Horizontal" Grid.Row="0">
45+
<TextBox Text="{Binding RawTx, UpdateSourceTrigger=PropertyChanged}" TextWrapping="Wrap"
46+
VerticalScrollBarVisibility="Visible" Width="450" Margin="3"/>
47+
48+
<StackPanel Orientation="Vertical" Margin="3">
49+
<Label Content="Input Encoding" FontFamily="Comic Sans MS" FontWeight="Bold"/>
50+
<ListBox ItemsSource="{Binding EncodingList}" SelectedItem="{Binding SelectedInEncoder}"
51+
Style="{StaticResource RadioButtonListBoxStyle}"/>
52+
</StackPanel>
53+
54+
<StackPanel Orientation="Vertical" Margin="3">
55+
<Label Content="Output Encoding" FontFamily="Comic Sans MS" FontWeight="Bold"/>
56+
<ListBox ItemsSource="{Binding EncodingList}" SelectedItem="{Binding SelectedOutEncoder}"
57+
Style="{StaticResource RadioButtonListBoxStyle}"/>
58+
</StackPanel>
59+
60+
<Button Content="Show QR" Command="{Binding ShowCommand}" Height="40" Width="65" Margin="3"/>
61+
</StackPanel>
62+
63+
<Image Source="{Binding QRCode}" Margin="3" Grid.Row="1"/>
64+
<TextBlock Text="{Binding Errors}" TextWrapping="Wrap" Margin="3" Grid.Row="2"/>
1065
</Grid>
1166
</UserControl>

0 commit comments

Comments
 (0)