Toggle main window hide on tray icon click
[novacoin.git] / src / qt / optionsdialog.cpp
1 #include "optionsdialog.h"
2 #include "optionsmodel.h"
3 #include "bitcoinamountfield.h"
4 #include "monitoreddatamapper.h"
5 #include "guiutil.h"
6 #include "bitcoinunits.h"
7 #include "qvaluecombobox.h"
8
9 #include <QHBoxLayout>
10 #include <QVBoxLayout>
11 #include <QPushButton>
12 #include <QListWidget>
13 #include <QStackedWidget>
14
15 #include <QCheckBox>
16 #include <QLabel>
17 #include <QLineEdit>
18 #include <QIntValidator>
19 #include <QDoubleValidator>
20 #include <QRegExpValidator>
21 #include <QDialogButtonBox>
22
23 /* First page of options */
24 class MainOptionsPage : public QWidget
25 {
26     Q_OBJECT
27 public:
28     explicit MainOptionsPage(QWidget *parent=0);
29
30     void setMapper(MonitoredDataMapper *mapper);
31 private:
32     QCheckBox *bitcoin_at_startup;
33 #ifndef Q_WS_MAC
34     QCheckBox *minimize_to_tray;
35 #endif
36     QCheckBox *map_port_upnp;
37 #ifndef Q_WS_MAC
38     QCheckBox *minimize_on_close;
39 #endif
40     QCheckBox *connect_socks4;
41     QLineEdit *proxy_ip;
42     QLineEdit *proxy_port;
43     BitcoinAmountField *fee_edit;
44
45 signals:
46
47 public slots:
48
49 };
50
51 class DisplayOptionsPage : public QWidget
52 {
53     Q_OBJECT
54 public:
55     explicit DisplayOptionsPage(QWidget *parent=0);
56
57     void setMapper(MonitoredDataMapper *mapper);
58 private:
59     QValueComboBox *unit;
60     QCheckBox *display_addresses;
61 signals:
62
63 public slots:
64
65 };
66
67 #include "optionsdialog.moc"
68
69 OptionsDialog::OptionsDialog(QWidget *parent):
70     QDialog(parent), contents_widget(0), pages_widget(0),
71     model(0), main_page(0), display_page(0)
72 {
73     contents_widget = new QListWidget();
74     contents_widget->setMaximumWidth(128);
75
76     pages_widget = new QStackedWidget();
77     pages_widget->setMinimumWidth(300);
78
79     QListWidgetItem *item_main = new QListWidgetItem(tr("Main"));
80     contents_widget->addItem(item_main);
81     main_page = new MainOptionsPage(this);
82     pages_widget->addWidget(main_page);
83
84     QListWidgetItem *item_display = new QListWidgetItem(tr("Display"));
85     contents_widget->addItem(item_display);
86     display_page = new DisplayOptionsPage(this);
87     pages_widget->addWidget(display_page);
88
89     contents_widget->setCurrentRow(0);
90
91     QHBoxLayout *main_layout = new QHBoxLayout();
92     main_layout->addWidget(contents_widget);
93     main_layout->addWidget(pages_widget, 1);
94
95     QVBoxLayout *layout = new QVBoxLayout();
96     layout->addLayout(main_layout);
97
98     QDialogButtonBox *buttonbox = new QDialogButtonBox();
99     buttonbox->setStandardButtons(QDialogButtonBox::Apply|QDialogButtonBox::Ok|QDialogButtonBox::Cancel);
100     apply_button = buttonbox->button(QDialogButtonBox::Apply);
101     layout->addWidget(buttonbox);
102
103     setLayout(layout);
104     setWindowTitle(tr("Options"));
105
106     /* Widget-to-option mapper */
107     mapper = new MonitoredDataMapper(this);
108     mapper->setSubmitPolicy(QDataWidgetMapper::ManualSubmit);
109     mapper->setOrientation(Qt::Vertical);
110     /* enable apply button when data modified */
111     connect(mapper, SIGNAL(viewModified()), this, SLOT(enableApply()));
112     /* disable apply button when new data loaded */
113     connect(mapper, SIGNAL(currentIndexChanged(int)), this, SLOT(disableApply()));
114
115     /* Event bindings */
116     connect(contents_widget, SIGNAL(currentRowChanged(int)), this, SLOT(changePage(int)));
117     connect(buttonbox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(okClicked()));
118     connect(buttonbox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(cancelClicked()));
119     connect(buttonbox->button(QDialogButtonBox::Apply), SIGNAL(clicked()), this, SLOT(applyClicked()));
120 }
121
122 void OptionsDialog::setModel(OptionsModel *model)
123 {
124     this->model = model;
125
126     mapper->setModel(model);
127     main_page->setMapper(mapper);
128     display_page->setMapper(mapper);
129
130     mapper->toFirst();
131 }
132
133 void OptionsDialog::changePage(int index)
134 {
135     pages_widget->setCurrentIndex(index);
136 }
137
138 void OptionsDialog::okClicked()
139 {
140     mapper->submit();
141     accept();
142 }
143
144 void OptionsDialog::cancelClicked()
145 {
146     reject();
147 }
148
149 void OptionsDialog::applyClicked()
150 {
151     mapper->submit();
152     apply_button->setEnabled(false);
153 }
154
155 void OptionsDialog::enableApply()
156 {
157     apply_button->setEnabled(true);
158 }
159
160 void OptionsDialog::disableApply()
161 {
162     apply_button->setEnabled(false);
163 }
164
165 MainOptionsPage::MainOptionsPage(QWidget *parent):
166         QWidget(parent)
167 {
168     QVBoxLayout *layout = new QVBoxLayout();
169
170     bitcoin_at_startup = new QCheckBox(tr("&Start Bitcoin on window system startup"));
171     bitcoin_at_startup->setToolTip(tr("Automatically start Bitcoin after the computer is turned on"));
172     layout->addWidget(bitcoin_at_startup);
173
174 #ifndef Q_WS_MAC
175     minimize_to_tray = new QCheckBox(tr("&Minimize to the tray instead of the taskbar"));
176     minimize_to_tray->setToolTip(tr("Show only a tray icon after minimizing the window"));
177     layout->addWidget(minimize_to_tray);
178
179     minimize_on_close = new QCheckBox(tr("M&inimize on close"));
180     minimize_on_close->setToolTip(tr("Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu."));
181     layout->addWidget(minimize_on_close);
182 #endif
183
184     map_port_upnp = new QCheckBox(tr("Map port using &UPnP"));
185     map_port_upnp->setToolTip(tr("Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled."));
186     layout->addWidget(map_port_upnp);
187
188     connect_socks4 = new QCheckBox(tr("&Connect through SOCKS4 proxy:"));
189     connect_socks4->setToolTip(tr("Connect to the Bitcon network through a SOCKS4 proxy (e.g. when connecting through Tor)"));
190     layout->addWidget(connect_socks4);
191
192     QHBoxLayout *proxy_hbox = new QHBoxLayout();
193     proxy_hbox->addSpacing(18);
194     QLabel *proxy_ip_label = new QLabel(tr("Proxy &IP: "));
195     proxy_hbox->addWidget(proxy_ip_label);
196     proxy_ip = new QLineEdit();
197     proxy_ip->setMaximumWidth(140);
198     proxy_ip->setEnabled(false);
199     proxy_ip->setValidator(new QRegExpValidator(QRegExp("[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}"), this));
200     proxy_ip->setToolTip(tr("IP address of the proxy (e.g. 127.0.0.1)"));
201     proxy_ip_label->setBuddy(proxy_ip);
202     proxy_hbox->addWidget(proxy_ip);
203     QLabel *proxy_port_label = new QLabel(tr("&Port: "));
204     proxy_hbox->addWidget(proxy_port_label);
205     proxy_port = new QLineEdit();
206     proxy_port->setMaximumWidth(55);
207     proxy_port->setValidator(new QIntValidator(0, 65535, this));
208     proxy_port->setEnabled(false);
209     proxy_port->setToolTip(tr("Port of the proxy (e.g. 1234)"));
210     proxy_port_label->setBuddy(proxy_port);
211     proxy_hbox->addWidget(proxy_port);
212     proxy_hbox->addStretch(1);
213
214     layout->addLayout(proxy_hbox);
215     QLabel *fee_help = new QLabel(tr("Optional transaction fee per kB that helps make sure your transactions are processed quickly.  Most transactions are 1 kB.  Fee 0.01 recommended."));
216     fee_help->setWordWrap(true);
217     layout->addWidget(fee_help);
218
219     QHBoxLayout *fee_hbox = new QHBoxLayout();
220     fee_hbox->addSpacing(18);
221     QLabel *fee_label = new QLabel(tr("Pay transaction &fee"));
222     fee_hbox->addWidget(fee_label);
223     fee_edit = new BitcoinAmountField();
224     fee_edit->setToolTip(tr("Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended."));
225
226     fee_label->setBuddy(fee_edit);
227     fee_hbox->addWidget(fee_edit);
228     fee_hbox->addStretch(1);
229
230     layout->addLayout(fee_hbox);
231
232     layout->addStretch(1); // Extra space at bottom
233
234     setLayout(layout);
235
236     connect(connect_socks4, SIGNAL(toggled(bool)), proxy_ip, SLOT(setEnabled(bool)));
237     connect(connect_socks4, SIGNAL(toggled(bool)), proxy_port, SLOT(setEnabled(bool)));
238
239 #ifndef USE_UPNP
240     map_port_upnp->setDisabled(true);
241 #endif
242 }
243
244 void MainOptionsPage::setMapper(MonitoredDataMapper *mapper)
245 {
246     // Map model to widgets
247     mapper->addMapping(bitcoin_at_startup, OptionsModel::StartAtStartup);
248 #ifndef Q_WS_MAC
249     mapper->addMapping(minimize_to_tray, OptionsModel::MinimizeToTray);
250 #endif
251     mapper->addMapping(map_port_upnp, OptionsModel::MapPortUPnP);
252 #ifndef Q_WS_MAC
253     mapper->addMapping(minimize_on_close, OptionsModel::MinimizeOnClose);
254 #endif
255     mapper->addMapping(connect_socks4, OptionsModel::ConnectSOCKS4);
256     mapper->addMapping(proxy_ip, OptionsModel::ProxyIP);
257     mapper->addMapping(proxy_port, OptionsModel::ProxyPort);
258     mapper->addMapping(fee_edit, OptionsModel::Fee);
259 }
260
261 DisplayOptionsPage::DisplayOptionsPage(QWidget *parent):
262         QWidget(parent)
263 {
264     QVBoxLayout *layout = new QVBoxLayout();
265
266     QHBoxLayout *unit_hbox = new QHBoxLayout();
267     unit_hbox->addSpacing(18);
268     QLabel *unit_label = new QLabel(tr("&Unit to show amounts in: "));
269     unit_hbox->addWidget(unit_label);
270     unit = new QValueComboBox(this);
271     unit->setModel(new BitcoinUnits(this));
272     unit->setToolTip(tr("Choose the default subdivision unit to show in the interface, and when sending coins"));
273
274     unit_label->setBuddy(unit);
275     unit_hbox->addWidget(unit);
276
277     layout->addLayout(unit_hbox);
278
279     display_addresses = new QCheckBox(tr("Display addresses in transaction list"), this);
280     layout->addWidget(display_addresses);
281
282     layout->addStretch();
283
284     setLayout(layout);
285 }
286
287 void DisplayOptionsPage::setMapper(MonitoredDataMapper *mapper)
288 {
289     mapper->addMapping(unit, OptionsModel::DisplayUnit);
290     mapper->addMapping(display_addresses, OptionsModel::DisplayAddresses);
291 }