1 #include "preferences_window_stock_info_digikey.hpp"
2 #include "common/common.hpp"
3 #include "util/gtk_util.hpp"
4 #include "util/util.hpp"
5 #include "preferences/preferences.hpp"
6 #include <set>
7 #include <iostream>
8 #include "util/stock_info_provider_digikey.hpp"
9 #include "util/sqlite.hpp"
10 #include "util/win32_undef.hpp"
11 #include "digikey_auth_window.hpp"
12
13 namespace horizon {
14
populate_and_bind_combo(Gtk::ComboBoxText & combo,const std::vector<std::pair<std::string,std::string>> & items,std::string & value)15 void DigiKeyApiPreferencesEditor::populate_and_bind_combo(Gtk::ComboBoxText &combo,
16 const std::vector<std::pair<std::string, std::string>> &items,
17 std::string &value)
18 {
19 for (const auto &[code, name] : items)
20 combo.append(code, name + " (" + code + ")");
21 combo.set_active_id(value);
22 combo.signal_changed().connect([this, &combo, &value] {
23 value = combo.get_active_id();
24 preferences.signal_changed().emit();
25 });
26 }
27
DigiKeyApiPreferencesEditor(BaseObjectType * cobject,const Glib::RefPtr<Gtk::Builder> & x,Preferences & prefs)28 DigiKeyApiPreferencesEditor::DigiKeyApiPreferencesEditor(BaseObjectType *cobject, const Glib::RefPtr<Gtk::Builder> &x,
29 Preferences &prefs)
30 : Gtk::Box(cobject), preferences(prefs), digikey_preferences(preferences.digikey_api),
31 db(StockInfoProviderDigiKey::get_db_filename(), SQLITE_OPEN_READWRITE)
32 {
33 GET_WIDGET(digikey_client_id_entry);
34 GET_WIDGET(digikey_client_secret_entry);
35 GET_WIDGET(digikey_max_price_breaks_sp);
36 GET_WIDGET(digikey_site_combo);
37 GET_WIDGET(digikey_currency_combo);
38 GET_WIDGET(digikey_token_label);
39
40 bind_widget(digikey_client_id_entry, digikey_preferences.client_id, [this](std::string &v) {
41 update_warnings();
42 preferences.signal_changed().emit();
43 });
44 bind_widget(digikey_client_secret_entry, digikey_preferences.client_secret, [this](std::string &v) {
45 update_warnings();
46 preferences.signal_changed().emit();
47 });
48
49
50 digikey_max_price_breaks_sp->set_value(digikey_preferences.max_price_breaks);
51 digikey_max_price_breaks_sp->signal_changed().connect([this] {
52 digikey_preferences.max_price_breaks = digikey_max_price_breaks_sp->get_value_as_int();
53 preferences.signal_changed().emit();
54 });
55
56 {
57 const std::vector<std::pair<std::string, std::string>> sites = {
58 {"AU", "Australia"},
59 {"AT", "Austria"},
60 {"BE", "Belgium"},
61 {"BG", "Bulgaria"},
62 {"CA", "Canada"},
63 {"CN", "China"},
64 {"CZ", "Czech Republic"},
65 {"DK", "Denmark"},
66 {"EE", "Estonia"},
67 {"FI", "Finland"},
68 {"FR", "France"},
69 {"DE", "Germany"},
70 {"GR", "Greece"},
71 {"HK", "Hong Kong"},
72 {"HU", "Hungary"},
73 {"IN", "India"},
74 {"IE", "Ireland"},
75 {"IL", "Israel"},
76 {"IT", "Italy"},
77 {"JP", "Japan"},
78 {"KR", "Korea, Republic of"},
79 {"LV", "Latvia"},
80 {"LT", "Lithuania"},
81 {"LU", "Luxembourg"},
82 {"MY", "Malaysia"},
83 {"MX", "Mexico"},
84 {"NL", "Netherlands"},
85 {"NZ", "New Zealand"},
86 {"NO", "Norway"},
87 {"PH", "Philippines"},
88 {"PL", "Poland"},
89 {"PT", "Portugal"},
90 {"RO", "Romania"},
91 {"SG", "Singapore"},
92 {"SK", "Slovakia"},
93 {"SI", "Slovenia"},
94 {"ZA", "South Africa"},
95 {"ES", "Spain"},
96 {"SE", "Sweden"},
97 {"CH", "Switzerland"},
98 {"TW", "Taiwan, Province of China"},
99 {"TH", "Thailand"},
100 {"UK", "United Kingdom"},
101 {"US", "United States"},
102 };
103 populate_and_bind_combo(*digikey_site_combo, sites, digikey_preferences.site);
104 }
105
106 {
107 const std::vector<std::pair<std::string, std::string>> currencies = {
108 {"AUD", "Australian Dollar"},
109 {"THB", "Baht"},
110 {"CAD", "Canadian Dollar"},
111 {"CZK", "Czech Koruna"},
112 {"DKK", "Danish Krone"},
113 {"EUR", "Euro"},
114 {"HUF", "Forint"},
115 {"HKD", "Hong Kong Dollar"},
116 {"INR", "Indian Rupee"},
117 {"MYR", "Malaysian Ringgit"},
118 {"ILS", "New Israeli Sheqel"},
119 {"RON", "New Romanian Leu"},
120 {"TWD", "New Taiwan Dollar"},
121 {"NZD", "New Zealand Dollar"},
122 {"NOK", "Norwegian Krone"},
123 {"PHP", "Philippine Piso"},
124 {"GBP", "Pound Sterling"},
125 {"ZAR", "Rand"},
126 {"SGD", "Singapore Dollar"},
127 {"SEK", "Swedish Krona"},
128 {"CHF", "Swiss Franc"},
129 {"USD", "US Dollar"},
130 {"KRW", "Won"},
131 {"JPY", "Yen"},
132 {"CNY", "Yuan Renminbi"},
133 {"PLN", "Zloty"},
134 };
135 populate_and_bind_combo(*digikey_currency_combo, currencies, digikey_preferences.currency);
136 }
137
138 {
139 Gtk::Button *digikey_sign_in_button;
140 GET_WIDGET(digikey_sign_in_button);
141 digikey_sign_in_button->signal_clicked().connect([this] {
142 auto top = dynamic_cast<Gtk::Window *>(get_ancestor(GTK_TYPE_WINDOW));
143 auto win = DigiKeyAuthWindow::create();
144 win->set_transient_for(*top);
145 win->present();
146 win->signal_hide().connect(sigc::mem_fun(*this, &DigiKeyApiPreferencesEditor::update_token), false);
147 });
148 }
149
150 update_warnings();
151 update_token();
152 }
153
needs_trim(const std::string & s)154 static bool needs_trim(const std::string &s)
155 {
156 return s.size() && (isspace(s.front()) || isspace(s.back()));
157 }
158
update_warnings()159 void DigiKeyApiPreferencesEditor::update_warnings()
160 {
161 for (auto entry : {digikey_client_id_entry, digikey_client_secret_entry}) {
162 const std::string txt = entry->get_text();
163 if (txt.size() == 0) {
164 entry_set_warning(entry, "Required");
165 }
166 else if (needs_trim(txt)) {
167 entry_set_warning(entry, "Has trailing/leading whitespace");
168 }
169 else {
170 entry_set_warning(entry, "");
171 }
172 }
173 }
174
175
update_token()176 void DigiKeyApiPreferencesEditor::update_token()
177 {
178 SQLite::Query q(db, "SELECT datetime(valid_until, 'localtime') FROM tokens WHERE key = 'refresh'");
179 if (q.step()) {
180 digikey_token_label->set_text("Token valid until " + q.get<std::string>(0)
181 + "\nThe token will automatically be refreshed.");
182 }
183 else {
184 digikey_token_label->set_text("No token, log in to obtain one.");
185 }
186 }
187
create(Preferences & prefs)188 DigiKeyApiPreferencesEditor *DigiKeyApiPreferencesEditor::create(Preferences &prefs)
189 {
190 DigiKeyApiPreferencesEditor *w;
191 Glib::RefPtr<Gtk::Builder> x = Gtk::Builder::create();
192 std::vector<Glib::ustring> widgets = {"digikey_box", "adjustment10", "adjustment11"};
193 x->add_from_resource("/org/horizon-eda/horizon/pool-prj-mgr/preferences/preferences.ui", widgets);
194 x->get_widget_derived("digikey_box", w, prefs);
195 w->reference();
196 return w;
197 }
198
199 } // namespace horizon
200