1 #include "settings.h"
2
3 #include "../debug.h"
4 #include "../flist.h"
5 #include "../macros.h"
6 #include "../self.h"
7 #include "../theme.h"
8 #include "../tox.h"
9
10 #include "../av/video.h"
11
12 #include "../native/clipboard.h"
13 #include "../native/dialog.h"
14 #include "../native/filesys.h"
15 #include "../native/keyboard.h"
16 #include "../native/notify.h"
17 #include "../native/os.h"
18
19 #include "../ui/button.h"
20 #include "../ui/contextmenu.h"
21 #include "../ui/draw.h"
22 #include "../ui/dropdown.h"
23 #include "../ui/edit.h"
24 #include "../ui/scrollable.h"
25 #include "../ui/svg.h"
26 #include "../ui/switch.h"
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31
32 /* Top bar for user settings */
draw_settings_header(int x,int y,int w,int UNUSED (height))33 static void draw_settings_header(int x, int y, int w, int UNUSED(height)) {
34 (void)w; // Silence an irreverent warning when GIT_VERSION is undefined
35 setcolor(COLOR_MAIN_TEXT);
36 setfont(FONT_SELF_NAME);
37 drawstr(x + SCALE(10), y + SCALE(10), UTOX_SETTINGS);
38 #ifdef GIT_VERSION
39 setfont(FONT_TEXT);
40 char ver_string[64];
41 int ver_string_len;
42
43 snprintf(ver_string, sizeof(ver_string), "Toxcore v%u.%u.%u",
44 tox_version_major(), tox_version_minor(), tox_version_patch());
45 ver_string_len = strnlen(ver_string, sizeof(ver_string) - 1);
46
47 drawtextwidth_right(x + w - textwidth(ver_string, ver_string_len),
48 textwidth(ver_string, ver_string_len), SCALE(10),
49 ver_string, ver_string_len);
50
51 setfont(FONT_SELF_NAME); // x adjustment depends on the font type being set first
52 x += SCALE(25) + UTOX_STR_WIDTH(UTOX_SETTINGS);
53 setfont(FONT_TEXT);
54 drawtext(x, SCALE(10), GIT_VERSION, strlen(GIT_VERSION));
55 #endif
56 }
57
58 #define DRAW_UNDERLINE() drawhline(x, y + SCALE(28), next_x, COLOR_EDGE_NORMAL)
59 #define DRAW_OVERLINE() drawhline(x, y + SCALE(0), next_x, COLOR_EDGE_ACTIVE); \
60 drawhline(x, y + SCALE(1), next_x, COLOR_EDGE_ACTIVE)
61
draw_settings_sub_header(int x,int y,int width,int UNUSED (height))62 static void draw_settings_sub_header(int x, int y, int width, int UNUSED(height)) {
63 drawhline(x, y, x + width, COLOR_EDGE_NORMAL);
64
65 setfont(FONT_SELF_NAME);
66 int last_x = x + width;
67
68 /* Draw the text and bars for general settings */
69 setcolor(!button_settings_sub_profile.mouseover ? COLOR_MAIN_TEXT : COLOR_MAIN_TEXT_SUBTEXT);
70 int next_x = x + SCALE(20) + UTOX_STR_WIDTH(PROFILE_BUTTON);
71 drawstr(x + SCALE(10), y + SCALE(10), PROFILE_BUTTON);
72
73 if (panel_settings_profile.disabled) {
74 DRAW_UNDERLINE();
75 } else {
76 DRAW_OVERLINE();
77 }
78 drawvline(next_x, y, y + SCALE(28), COLOR_EDGE_NORMAL);
79 x = next_x;
80
81 /* Draw the text and bars for device settings */
82 #ifdef ENABLE_MULTIDEVICE
83 setcolor(!button_settings_sub_devices.mouseover ? COLOR_MAIN_TEXT : COLOR_MAIN_TEXT_SUBTEXT);
84 next_x += SCALE(20) + UTOX_STR_WIDTH(DEVICES_BUTTON);
85 drawstr(x + SCALE(10), y, + SCALE(10), DEVICES_BUTTON);
86 if (panel_settings_devices.disabled) {
87 DRAW_UNDERLINE();
88 } else {
89 DRAW_OVERLINE();
90 }
91 drawvline(next_x, y, y, + SCALE(28), COLOR_EDGE_NORMAL);
92 x = next_x;
93 #endif
94
95 /* Draw the text and bars for User interface settings */
96 setcolor(!button_settings_sub_ui.mouseover ? COLOR_MAIN_TEXT : COLOR_MAIN_TEXT_SUBTEXT);
97 next_x += SCALE(20) + UTOX_STR_WIDTH(USER_INTERFACE_BUTTON);
98 drawstr(x + SCALE(10), y + SCALE(10), USER_INTERFACE_BUTTON);
99 if (panel_settings_ui.disabled) {
100 DRAW_UNDERLINE();
101 } else {
102 DRAW_OVERLINE();
103 }
104 drawvline(next_x, y, y + SCALE(28), COLOR_EDGE_NORMAL);
105 x = next_x;
106
107 /* Draw the text and bars for A/V settings */
108 setcolor(!button_settings_sub_av.mouseover ? COLOR_MAIN_TEXT : COLOR_MAIN_TEXT_SUBTEXT);
109 next_x += SCALE(20) + UTOX_STR_WIDTH(AUDIO_VIDEO_BUTTON);
110 drawstr(x + SCALE(10), y + SCALE(10), AUDIO_VIDEO_BUTTON);
111 if (panel_settings_av.disabled) {
112 DRAW_UNDERLINE();
113 } else {
114 DRAW_OVERLINE();
115 }
116 drawvline(next_x, y, y + SCALE(28), COLOR_EDGE_NORMAL);
117 x = next_x;
118
119 /* Draw the text and bars for notification settings */
120 setcolor(!button_settings_sub_notifications.mouseover ? COLOR_MAIN_TEXT : COLOR_MAIN_TEXT_SUBTEXT);
121 next_x += SCALE(20) + UTOX_STR_WIDTH(NOTIFICATIONS_BUTTON);
122 drawstr(x + SCALE(10), y + SCALE(10), NOTIFICATIONS_BUTTON);
123 if (panel_settings_notifications.disabled) {
124 DRAW_UNDERLINE();
125 } else {
126 DRAW_OVERLINE();
127 }
128 drawvline(next_x, y, y + SCALE(28), COLOR_EDGE_NORMAL);
129 x = next_x;
130
131 /* Draw the text and bars for advanced settings */
132 setcolor(!button_settings_sub_adv.mouseover ? COLOR_MAIN_TEXT : COLOR_MAIN_TEXT_SUBTEXT);
133 next_x += SCALE(20) + UTOX_STR_WIDTH(ADVANCED_BUTTON);
134 drawstr(x + SCALE(10), y + SCALE(10), ADVANCED_BUTTON);
135 if (panel_settings_adv.disabled) {
136 DRAW_UNDERLINE();
137 } else {
138 DRAW_OVERLINE();
139 }
140 drawvline(next_x, y, y + SCALE(28), COLOR_EDGE_NORMAL);
141 x = next_x;
142
143 next_x = last_x;
144 DRAW_UNDERLINE();
145 }
146
147 /* draw switch profile top bar */
148 /* Text content for settings page */
draw_settings_text_profile(int x,int y,int UNUSED (w),int UNUSED (h))149 static void draw_settings_text_profile(int x, int y, int UNUSED(w), int UNUSED(h)) {
150 setcolor(COLOR_MAIN_TEXT);
151 setfont(FONT_SELF_NAME);
152 drawstr(x + SCALE(10), y + SCALE(10), NAME);
153 drawstr(x + SCALE(10), y + SCALE(65), STATUSMESSAGE);
154 drawstr(x + SCALE(10), y + SCALE(120), TOXID);
155
156 if (self.qr_image && !button_qr.disabled) {
157 // Enlarge original QR for better recognition
158 const double image_scale = SCALE(4);
159 const uint32_t image_size = self.qr_image_size * image_scale;
160
161 button_qr.panel.width = button_qr.panel.height = UN_SCALE(self.qr_image_size * image_scale);
162
163 image_set_scale(self.qr_image, image_scale);
164 draw_image(self.qr_image, x + SCALE(10), y + SCALE(175), image_size, image_size, 0, 0);
165 image_set_scale(self.qr_image, 1.0);
166 }
167 }
168
169 // Devices settings page
draw_settings_text_devices(int x,int y,int UNUSED (w),int UNUSED (h))170 static void draw_settings_text_devices(int x, int y, int UNUSED(w), int UNUSED(h)) {
171 setcolor(COLOR_MAIN_TEXT);
172 setfont(FONT_SELF_NAME);
173 drawstr(x + SCALE(10), y + SCALE(10), DEVICES_ADD_NEW);
174
175 drawstr(x + SCALE(10), y + SCALE(60), DEVICES_NUMBER);
176
177 char str[10];
178
179 snprintf(str, sizeof(str), "%zu", self.device_list_count);
180 size_t str_len = strnlen(str, sizeof(str) - 1);
181
182 drawtext(x + SCALE(10), y + SCALE(75), str, str_len);
183 }
184
draw_settings_text_password(int x,int y,int UNUSED (w),int UNUSED (h))185 static void draw_settings_text_password(int x, int y, int UNUSED(w), int UNUSED(h)) {
186 setcolor(COLOR_MAIN_TEXT);
187 setfont(FONT_SELF_NAME);
188 drawstr(x + SCALE(10), y + SCALE(215), PROFILE_PASSWORD);
189
190 setfont(FONT_MISC);
191 setcolor(C_RED);
192 drawstr(x + SCALE(10), y + SCALE(289), PROFILE_PW_WARNING);
193 drawstr(x + SCALE(10), y + SCALE(301), PROFILE_PW_NO_RECOVER);
194 }
195
draw_nospam_settings(int x,int y,int UNUSED (w),int UNUSED (h))196 static void draw_nospam_settings(int x, int y, int UNUSED(w), int UNUSED(h)){
197 setfont(FONT_MISC);
198 setcolor(C_RED);
199 drawstr(x + SCALE(95), y + SCALE(218), NOSPAM_WARNING);
200
201 setcolor(COLOR_MAIN_TEXT);
202 setfont(FONT_SELF_NAME);
203
204 drawstr(x + SCALE(10), y + SCALE(215), NOSPAM);
205 }
206
207 // UI settings page
draw_settings_text_ui(int x,int y,int UNUSED (w),int UNUSED (height))208 static void draw_settings_text_ui(int x, int y, int UNUSED(w), int UNUSED(height)) {
209 setcolor(COLOR_MAIN_TEXT);
210 setfont(FONT_SELF_NAME);
211 drawstr(x + SCALE(10), y + SCALE(10), LANGUAGE);
212 drawstr(x + SCALE(150), y + SCALE(65), DPI);
213 drawstr(x + SCALE(10), y + SCALE(65), THEME);
214 drawstr(x + SCALE(20) + BM_SWITCH_WIDTH, y + SCALE(120), SAVE_CHAT_HISTORY);
215 drawstr(x + SCALE(20) + BM_SWITCH_WIDTH, y + SCALE(150), CLOSE_TO_TRAY);
216 drawstr(x + SCALE(20) + BM_SWITCH_WIDTH, y + SCALE(180), START_IN_TRAY);
217 drawstr(x + SCALE(20) + BM_SWITCH_WIDTH, y + SCALE(210), AUTO_STARTUP);
218 drawstr(x + SCALE(20) + BM_SWITCH_WIDTH, y + SCALE(240), SETTINGS_UI_MINI_ROSTER);
219 #if PLATFORM_ANDROID
220 drawstr(x + SCALE(20) + BM_SWITCH_WIDTH, y + SCALE(270), SETTINGS_UI_AUTO_HIDE_SIDEBAR);
221 #endif
222 }
223
224 // Audio/Video settings page
draw_settings_text_av(int x,int y,int UNUSED (w),int UNUSED (height))225 static void draw_settings_text_av(int x, int y, int UNUSED(w), int UNUSED(height)) {
226 setcolor(COLOR_MAIN_TEXT);
227 setfont(FONT_SELF_NAME);
228
229 // The element is draw_pos_y_inc units apart and they start draw_pos_y down.
230 uint16_t draw_pos_y = 15;
231 uint16_t draw_pos_y_inc = 30;
232
233 drawstr(x + SCALE(20) + BM_SWITCH_WIDTH, y + SCALE(draw_pos_y), PUSH_TO_TALK);
234 draw_pos_y += draw_pos_y_inc;
235 #ifdef AUDIO_FILTERING
236 drawstr(x + SCALE(20) + BM_SWITCH_WIDTH, y + SCALE(draw_pos_y), AUDIOFILTERING);
237 draw_pos_y += draw_pos_y_inc;
238 #endif
239
240 // These are 60 apart as there needs to be room for a dropdown between them.
241 draw_pos_y_inc = 60;
242
243 drawstr(x + SCALE(10), y + SCALE(draw_pos_y), AUDIOINPUTDEVICE);
244 draw_pos_y += draw_pos_y_inc;
245 drawstr(x + SCALE(10), y + SCALE(draw_pos_y - 7), AUDIOOUTPUTDEVICE);
246 draw_pos_y += draw_pos_y_inc;
247 drawstr(x + SCALE(10), y + SCALE(draw_pos_y - 15), VIDEOFRAMERATE);
248 draw_pos_y += draw_pos_y_inc;
249 drawstr(x + SCALE(10), y + SCALE(draw_pos_y - 23), VIDEOINPUTDEVICE);
250 draw_pos_y += draw_pos_y_inc;
251 drawstr(x + SCALE(10), y + SCALE(draw_pos_y - 30), PREVIEW);
252 }
253
254 // Notification settings page
draw_settings_text_notifications(int x,int y,int UNUSED (w),int UNUSED (height))255 static void draw_settings_text_notifications(int x, int y, int UNUSED(w), int UNUSED(height)) {
256 setcolor(COLOR_MAIN_TEXT);
257 setfont(FONT_SELF_NAME);
258
259 drawstr(x + SCALE(20) + BM_SWITCH_WIDTH, y + SCALE(15), RINGTONE);
260 drawstr(x + SCALE(20) + BM_SWITCH_WIDTH, y + SCALE(45), STATUS_NOTIFICATIONS);
261 drawstr(x + SCALE(20) + BM_SWITCH_WIDTH, y + SCALE(75), SEND_TYPING_NOTIFICATIONS);
262 drawstr(x + SCALE(10), y + SCALE(105), GROUP_NOTIFICATIONS);
263 }
264
draw_settings_text_adv(int x,int y,int UNUSED (w),int UNUSED (height))265 static void draw_settings_text_adv(int x, int y, int UNUSED(w), int UNUSED(height)) {
266 setfont(FONT_MISC);
267 setcolor(C_RED);
268 drawstr(x + SCALE(10), y + SCALE(5), WARNING);
269
270 setcolor(COLOR_MAIN_TEXT);
271 setfont(FONT_SELF_NAME);
272
273 drawstr(x + SCALE(20) + BM_SWITCH_WIDTH, y + SCALE(30), IPV6);
274 drawstr(x + SCALE(20) + BM_SWITCH_WIDTH, y + SCALE(60), UDP);
275 drawstr(x + SCALE(20) + BM_SWITCH_WIDTH, y + SCALE(90), PROXY);
276 drawstr(x + SCALE(20) + BM_SWITCH_WIDTH, y + SCALE(120), PROXY_FORCE); // TODO draw ONLY when settings.use_proxy = true
277 drawtext(x + SCALE(353), y + SCALE(89), ":", 1); // Little addr port separator
278
279 drawstr(x + SCALE(20)+ BM_SWITCH_WIDTH, y + SCALE(150), BLOCK_FRIEND_REQUESTS);
280 }
281
282
283 SCROLLABLE scrollbar_settings = {
284 .panel = { .type = PANEL_SCROLLABLE, },
285 .color = C_SCROLL,
286 };
287
288 /* Draw the text for profile password window */
draw_profile_password(int x,int UNUSED (y),int UNUSED (w),int UNUSED (height))289 static void draw_profile_password(int x, int UNUSED(y), int UNUSED(w), int UNUSED(height)) {
290 setcolor(COLOR_MAIN_TEXT);
291 setfont(FONT_SELF_NAME);
292 drawstr(x + SCALE(10), SCALE(10), PROFILE_PASSWORD);
293
294 setcolor(COLOR_MAIN_TEXT_SUBTEXT);
295 setfont(FONT_TEXT);
296 drawstr(x + SCALE(10), SCALE(MAIN_TOP + 5), PROFILE_PASSWORD);
297 }
298
299 PANEL
300 boxfor_password_entry_login = {
301 .type = PANEL_NONE,
302 .x = 0, .y = 0,
303 .child = (PANEL*[]) {
304 (PANEL*)&edit_profile_password,
305 NULL
306 }
307 },
308 boxfor_password_entry_change = {
309 .type = PANEL_NONE,
310 .x = 0, .y = 180,
311 .child = (PANEL*[]) {
312 (PANEL*)&edit_profile_password,
313 NULL
314 }
315 },
316 panel_profile_password = {
317 .type = PANEL_NONE,
318 .disabled = 0,
319 .drawfunc = draw_profile_password,
320 .child = (PANEL*[]) {
321 (PANEL*)&boxfor_password_entry_login,
322 NULL
323 }
324 },
325 panel_nospam_settings = {
326 .type = PANEL_NONE,
327 .disabled = true,
328 .drawfunc = draw_nospam_settings,
329 .content_scroll = &scrollbar_settings,
330 .child = (PANEL*[]) {
331 (PANEL*)&edit_nospam,
332 (PANEL*)&button_change_nospam,
333 (PANEL*)&button_revert_nospam,
334 NULL
335 }
336 },
337 panel_profile_password_settings = {
338 .type = PANEL_NONE,
339 .disabled = 1,
340 .drawfunc = draw_settings_text_password,
341 .child = (PANEL*[]) {
342 (PANEL*)&boxfor_password_entry_change,
343 (PANEL*)&button_lock_uTox,
344 NULL
345 }
346 },
347 panel_settings_master = {
348 .type = PANEL_NONE,
349 .disabled = 1,
350 .drawfunc = draw_settings_header,
351 .child = (PANEL*[]) {
352 &panel_settings_subheader,
353 NULL
354 }
355 },
356 panel_settings_subheader = {
357 .y = MAIN_TOP_FRAME_THIN,
358 .type = PANEL_NONE,
359 .disabled = 0,
360 .drawfunc = draw_settings_sub_header,
361 .child = (PANEL*[]) {
362 (PANEL*)&button_settings_sub_profile,
363 (PANEL*)&button_settings_sub_devices,
364 (PANEL*)&button_settings_sub_ui,
365 (PANEL*)&button_settings_sub_av,
366 (PANEL*)&button_settings_sub_notifications,
367 (PANEL*)&button_settings_sub_adv,
368 (PANEL*)&scrollbar_settings,
369 &panel_settings_profile,
370 &panel_settings_devices,
371 &panel_settings_ui,
372 &panel_settings_av,
373 &panel_settings_notifications,
374 &panel_settings_adv,
375 NULL
376 }
377 },
378 /* Panel to draw settings page */
379 panel_settings_profile = {
380 .type = PANEL_NONE,
381 .disabled = 0,
382 .drawfunc = draw_settings_text_profile,
383 .content_scroll = &scrollbar_settings,
384 .child = (PANEL*[]) {
385 (PANEL*)&edit_name,
386 (PANEL*)&edit_status_msg,
387 // Text: Tox ID
388 (PANEL*)&edit_toxid,
389 (PANEL*)&button_copyid,
390 (PANEL*)&button_show_qr,
391 (PANEL*)&button_qr,
392 NULL
393 }
394 },
395 /* Panel to draw settings page */
396 panel_settings_devices = {
397 .type = PANEL_NONE,
398 .disabled = 1,
399 .drawfunc = draw_settings_text_devices,
400 .content_scroll = &scrollbar_settings,
401 .child = NULL,
402 },
403 panel_settings_ui = {
404 .type = PANEL_NONE,
405 .drawfunc = draw_settings_text_ui,
406 .disabled = 1,
407 .content_scroll = &scrollbar_settings,
408 .child = (PANEL*[]) {
409 (PANEL*)&dropdown_language,
410 (PANEL*)&dropdown_dpi,
411 (PANEL*)&dropdown_theme,
412 (PANEL*)&switch_save_chat_history,
413 (PANEL*)&switch_close_to_tray,
414 (PANEL*)&switch_start_in_tray,
415 (PANEL*)&switch_auto_startup,
416 (PANEL*)&switch_mini_contacts,
417 #if PLATFORM_ANDROID
418 (PANEL*)&switch_magic_sidebar,
419 #endif
420 NULL
421 }
422 },
423 panel_settings_av = {
424 .type = PANEL_NONE,
425 .disabled = 1,
426 .drawfunc = draw_settings_text_av,
427 .content_scroll = &scrollbar_settings,
428 .child = (PANEL*[]) {
429 (PANEL*)&button_callpreview,
430 (PANEL*)&switch_push_to_talk,
431 (PANEL*)&button_videopreview,
432 (PANEL*)&edit_video_fps,
433 (PANEL*)&dropdown_audio_in,
434 (PANEL*)&dropdown_audio_out,
435 (PANEL*)&dropdown_video,
436 (PANEL*)&switch_audio_filtering,
437 NULL
438 }
439 },
440
441 panel_settings_notifications = {
442 .type = PANEL_NONE,
443 .disabled = true,
444 .drawfunc = draw_settings_text_notifications,
445 .content_scroll = &scrollbar_settings,
446 .child = (PANEL*[]) {
447 (PANEL*)&dropdown_global_group_notifications,
448 (PANEL*)&switch_status_notifications,
449 (PANEL*)&switch_typing_notes,
450 (PANEL*)&switch_audible_notifications,
451 NULL
452 }
453 },
454
455 panel_settings_adv = {
456 .type = PANEL_NONE,
457 .disabled = true,
458 .drawfunc = draw_settings_text_adv,
459 .content_scroll = &scrollbar_settings,
460 .child = (PANEL*[]) {
461 (PANEL*)&edit_proxy_ip,
462 (PANEL*)&edit_proxy_port,
463 (PANEL*)&switch_proxy,
464 (PANEL*)&switch_proxy_force,
465 (PANEL*)&switch_ipv6,
466 (PANEL*)&switch_udp,
467 (PANEL*)&button_show_password_settings,
468 &panel_profile_password_settings,
469 (PANEL*)&switch_block_friend_requests,
470 (PANEL*)&button_show_nospam,
471 &panel_nospam_settings,
472 NULL,
473 }
474 };
475
476
477 extern SCROLLABLE scrollbar_settings;
478
button_bottommenu_update(BUTTON * b)479 static void button_bottommenu_update(BUTTON *b) {
480 b->c1 = COLOR_BKGRND_MENU;
481 b->c2 = COLOR_BKGRND_MENU_HOVER;
482 b->c3 = COLOR_BKGRND_MENU_ACTIVE;
483 b->ct1 = COLOR_MENU_TEXT;
484 b->ct2 = COLOR_MENU_TEXT;
485 if (b->mousedown || b->disabled) {
486 b->ct1 = COLOR_MENU_TEXT_ACTIVE;
487 b->ct2 = COLOR_MENU_TEXT_ACTIVE;
488 }
489 b->cd = COLOR_BKGRND_MENU_ACTIVE;
490 }
491
button_settings_on_mup(void)492 static void button_settings_on_mup(void) {
493 if (tox_thread_init == UTOX_TOX_THREAD_INIT_SUCCESS) {
494 flist_selectsettings();
495 }
496 }
497
update_show_nospam_button_text(void)498 static void update_show_nospam_button_text(void) {
499 if (panel_nospam_settings.disabled) {
500 maybe_i18nal_string_set_i18nal(&button_show_nospam.button_text, STR_SHOW_NOSPAM);
501 } else {
502 maybe_i18nal_string_set_i18nal(&button_show_nospam.button_text, STR_HIDE_NOSPAM);
503 }
504 }
505
update_show_password_button_text(void)506 static void update_show_password_button_text(void) {
507 if (panel_profile_password_settings.disabled) {
508 maybe_i18nal_string_set_i18nal(&button_show_password_settings.button_text, STR_SHOW_UI_PASSWORD);
509 maybe_i18nal_string_set_i18nal(&button_show_password_settings.tooltip_text, STR_SHOW_UI_PASSWORD_TOOLTIP);
510 } else {
511 maybe_i18nal_string_set_i18nal(&button_show_password_settings.button_text, STR_HIDE_UI_PASSWORD);
512 maybe_i18nal_string_set_i18nal(&button_show_password_settings.tooltip_text, STR_HIDE_UI_PASSWORD_TOOLTIP);
513 }
514 }
515
516 BUTTON button_settings = {
517 .panel = {
518 .type = PANEL_BUTTON,
519 .x = SIDEBAR_BUTTON_LEFT,
520 .y = ROSTER_BOTTOM,
521 .width = SIDEBAR_BUTTON_WIDTH,
522 .height = SIDEBAR_BUTTON_HEIGHT,
523 },
524 .bm_icon = BM_SETTINGS,
525 .icon_w = _BM_ADD_WIDTH,
526 .icon_h = _BM_ADD_WIDTH,
527 .update = button_bottommenu_update,
528 .on_mup = button_settings_on_mup,
529 .disabled = false,
530 .nodraw = false,
531 .tooltip_text = {.i18nal = STR_USERSETTINGS },
532 };
533
close_dropdowns(PANEL * p)534 static void close_dropdowns(PANEL *p) {
535 if (!p->child) {
536 return;
537 }
538
539 PANEL *ch;
540 for (int i = 0; (ch = p->child[i]); ++i)
541 {
542 PANEL_TYPE type = ch->type;
543 if (type == PANEL_DROPDOWN) {
544 dropdown_close((DROPDOWN*)ch);
545 } else if (type == PANEL_NONE) {
546 close_dropdowns(ch);
547 }
548 }
549 }
550
reset_settings_controls(void)551 void reset_settings_controls(void) {
552 update_show_nospam_button_text();
553 update_show_password_button_text();
554 close_dropdowns(&panel_settings_master);
555 }
556
disable_all_setting_sub(void)557 static void disable_all_setting_sub(void) {
558 flist_selectsettings();
559 panel_settings_profile.disabled = true;
560 panel_settings_devices.disabled = true;
561 panel_settings_ui.disabled = true;
562 panel_settings_av.disabled = true;
563 panel_settings_notifications.disabled = true;
564 panel_settings_adv.disabled = true;
565 reset_settings_controls();
566 }
567
button_settings_sub_profile_on_mup(void)568 static void button_settings_sub_profile_on_mup(void) {
569 scrollbar_settings.content_height = SCALE(260);
570 disable_all_setting_sub();
571 panel_settings_profile.disabled = false;
572 }
573
button_settings_sub_devices_on_mup(void)574 static void button_settings_sub_devices_on_mup(void) {
575 scrollbar_settings.content_height = SCALE(260);
576 disable_all_setting_sub();
577 panel_settings_devices.disabled = false;
578 }
579
button_settings_sub_ui_on_mup(void)580 static void button_settings_sub_ui_on_mup(void) {
581 scrollbar_settings.content_height = SCALE(280);
582 disable_all_setting_sub();
583 panel_settings_ui.disabled = false;
584 }
585
button_settings_sub_av_on_mup(void)586 static void button_settings_sub_av_on_mup(void) {
587 scrollbar_settings.content_height = SCALE(350);
588 disable_all_setting_sub();
589 panel_settings_av.disabled = false;
590 }
591
button_settings_sub_adv_on_mup(void)592 static void button_settings_sub_adv_on_mup(void) {
593 scrollbar_settings.content_height = SCALE(300);
594 disable_all_setting_sub();
595 panel_settings_adv.disabled = false;
596 }
597
button_settings_sub_notifications_on_mup(void)598 static void button_settings_sub_notifications_on_mup(void){
599 scrollbar_settings.content_height = SCALE(300);
600 disable_all_setting_sub();
601 panel_settings_notifications.disabled = false;
602 }
603
604
button_add_device_to_self_mdown(void)605 static void button_add_device_to_self_mdown(void) {
606 #ifdef ENABLE_MULTIDEVICE
607 devices_self_add(edit_add_new_device_to_self.data, edit_add_new_device_to_self.length);
608 edit_resetfocus();
609 #endif
610 }
611
612 BUTTON
613 button_settings_sub_profile = {
614 .nodraw = true,
615 .on_mup = button_settings_sub_profile_on_mup,
616 .tooltip_text = {.i18nal = STR_PROFILE_BUTTON },
617 .button_text = {.i18nal = STR_PROFILE_BUTTON },
618 },
619
620 button_settings_sub_devices = {
621 .nodraw = true,
622 .on_mup = button_settings_sub_devices_on_mup,
623 .tooltip_text = {.i18nal = STR_DEVICES_BUTTON },
624 .button_text = {.i18nal = STR_DEVICES_BUTTON },
625 },
626
627 button_settings_sub_ui = {
628 .nodraw = true,
629 .on_mup = button_settings_sub_ui_on_mup,
630 .tooltip_text = {.i18nal = STR_USER_INTERFACE_BUTTON },
631 .button_text = {.i18nal = STR_USER_INTERFACE_BUTTON },
632 },
633
634 button_settings_sub_av = {
635 .nodraw = true,
636 .on_mup = button_settings_sub_av_on_mup,
637 .tooltip_text = {.i18nal = STR_AUDIO_VIDEO_BUTTON },
638 .button_text = {.i18nal = STR_AUDIO_VIDEO_BUTTON },
639 },
640
641 button_settings_sub_notifications = {
642 .nodraw = true,
643 .on_mup = button_settings_sub_notifications_on_mup,
644 .tooltip_text = {.i18nal = STR_NOTIFICATIONS_BUTTON },
645 .button_text = {.i18nal = STR_NOTIFICATIONS_BUTTON },
646 },
647
648 button_settings_sub_adv = {
649 .nodraw = true,
650 .on_mup = button_settings_sub_adv_on_mup,
651 .tooltip_text = {.i18nal = STR_ADVANCED_BUTTON },
652 .button_text = {.i18nal = STR_ADVANCED_BUTTON },
653 },
654
655 button_add_new_device_to_self = {
656 .bm_fill = BM_SBUTTON,
657 .button_text = {.i18nal = STR_ADD },
658 // .update = button_setcolors_success,
659 .on_mup = button_add_device_to_self_mdown,
660 };
661
662 #include "../tox.h"
button_lock_uTox_on_mup(void)663 static void button_lock_uTox_on_mup(void) {
664 if (tox_thread_init && edit_profile_password.length > 3) {
665 flist_selectsettings();
666 panel_profile_password.disabled = false;
667 panel_settings_master.disabled = true;
668 tox_settingschanged();
669 } else {
670 show_messagebox(NULL, 0, S(PASSWORD_TOO_SHORT), SLEN(PASSWORD_TOO_SHORT));
671 memset(edit_profile_password.data, '\0', edit_profile_password.data_size);
672 edit_profile_password.length = 0;
673 }
674 button_show_password_settings.disabled = false;
675 button_show_password_settings.nodraw = false;
676 update_show_nospam_button_text();
677 update_show_password_button_text();
678 }
679
button_show_password_settings_on_mup(void)680 static void button_show_password_settings_on_mup(void) {
681 panel_nospam_settings.disabled = true;
682 panel_profile_password_settings.disabled = !panel_profile_password_settings.disabled;
683 update_show_nospam_button_text();
684 update_show_password_button_text();
685 }
686
687
688 #include "../chatlog.h"
689 #include "../flist.h"
690 #include "../friend.h"
button_export_chatlog_on_mup(void)691 static void button_export_chatlog_on_mup(void) {
692 FRIEND *f = flist_get_friend();
693 if (!f) {
694 LOG_ERR("Settings", "Could not get selected friend.");
695 return;
696 }
697 utox_export_chatlog_init(f->number);
698 }
699
button_change_nospam_on_mup(void)700 static void button_change_nospam_on_mup(void) {
701 button_revert_nospam.disabled = false;
702 long int nospam = rand() | rand() << 16;
703 postmessage_toxcore(TOX_SELF_CHANGE_NOSPAM, nospam, 0, NULL);
704 }
705
button_revert_nospam_on_mup(void)706 static void button_revert_nospam_on_mup(void) {
707 if (button_revert_nospam.disabled) {
708 return;
709 }
710
711 if (self.old_nospam == 0 || self.nospam == self.old_nospam) { //nospam can not be 0
712 LOG_ERR("Settings", "Invalid or current nospam: %u.", self.old_nospam);
713 return;
714 }
715 postmessage_toxcore(TOX_SELF_CHANGE_NOSPAM, self.old_nospam, 0, NULL);
716 button_revert_nospam.disabled = true;
717 }
718
button_revert_nospam_on_update(BUTTON * b)719 static void button_revert_nospam_on_update(BUTTON *b) {
720 if (button_revert_nospam.disabled) {
721 button_setcolors_disabled(b);
722 } else {
723 button_setcolors_success(b);
724 }
725 }
726
button_show_nospam_on_mup(void)727 static void button_show_nospam_on_mup(void) {
728 panel_profile_password_settings.disabled = true;
729 panel_nospam_settings.disabled = !panel_nospam_settings.disabled;
730 update_show_nospam_button_text();
731 update_show_password_button_text();
732 }
733
button_copyid_on_mup(void)734 static void button_copyid_on_mup(void) {
735 edit_setfocus(&edit_toxid);
736 copy(0);
737 }
738
button_show_qr_on_mup(void)739 static void button_show_qr_on_mup(void) {
740 if (button_qr.disabled) {
741 maybe_i18nal_string_set_i18nal(&button_show_qr.button_text, STR_HIDE_QR);
742 } else {
743 maybe_i18nal_string_set_i18nal(&button_show_qr.button_text, STR_SHOW_QR);
744 }
745
746 button_qr.disabled = !button_qr.disabled;
747 button_qr.panel.disabled = button_qr.disabled;
748 }
749
contextmenu_qr_onselect(uint8_t i)750 static void contextmenu_qr_onselect(uint8_t i) {
751 if (i == 0) {
752 if (!native_save_image_png(self.name, self.qr_data, self.qr_data_size)) {
753 LOG_ERR("Self", "Unable to save QR code.");
754 }
755 }
756 }
757
button_qr_on_mright(void)758 static void button_qr_on_mright(void) {
759 static UTOX_I18N_STR menu[] = { STR_SAVE_QR };
760 contextmenu_new(COUNTOF(menu), menu, contextmenu_qr_onselect);
761 }
762
763 #include "../settings.h"
764 #include "../av/utox_av.h"
button_audiopreview_on_mup(void)765 static void button_audiopreview_on_mup(void) {
766 if (!settings.audio_preview) {
767 postmessage_utoxav(UTOXAV_START_AUDIO, 1, 0, NULL);
768 } else {
769 postmessage_utoxav(UTOXAV_STOP_AUDIO, 1, 0, NULL);
770 }
771 settings.audio_preview = !settings.audio_preview;
772 }
773
button_audiopreview_update(BUTTON * b)774 static void button_audiopreview_update(BUTTON *b) {
775 if (settings.audio_preview) {
776 button_setcolors_danger(b);
777 } else {
778 button_setcolors_success(b);
779 }
780 }
781
button_videopreview_on_mup(void)782 static void button_videopreview_on_mup(void) {
783 if (settings.video_preview) {
784 postmessage_utoxav(UTOXAV_STOP_VIDEO, UINT16_MAX, 1, NULL);
785 } else if (video_width && video_height) {
786 postmessage_utoxav(UTOXAV_START_VIDEO, UINT16_MAX, 1, NULL);
787 } else {
788 LOG_ERR("Button", "Video_width = 0, can't preview\n");
789 return;
790 }
791 settings.video_preview = !settings.video_preview;
792 }
793
button_videopreview_update(BUTTON * b)794 static void button_videopreview_update(BUTTON *b) {
795 if (settings.video_preview) {
796 button_setcolors_danger(b);
797 } else {
798 button_setcolors_success(b);
799 }
800 }
801
button_show_qr_update(BUTTON * b)802 static void button_show_qr_update(BUTTON *b) {
803 button_setcolors_success(b);
804 b->panel.x = 85 + UN_SCALE(UTOX_STR_WIDTH(COPY_TOX_ID));
805 }
806
807 BUTTON button_copyid = {
808 .panel = {
809 .type = PANEL_BUTTON,
810 .x = 66,
811 .y = 117,
812 .width = _BM_SBUTTON_WIDTH,
813 .height = _BM_SBUTTON_HEIGHT,
814 },
815 .bm_fill = BM_SBUTTON,
816 .update = button_setcolors_success,
817 .on_mup = button_copyid_on_mup,
818 .disabled = false,
819 .button_text = {.i18nal = STR_COPY_TOX_ID },
820 };
821
822 BUTTON button_show_qr = {
823 .panel = {
824 .type = PANEL_BUTTON,
825 .x = 85 + _BM_SBUTTON_WIDTH,
826 .y = 117,
827 .width = _BM_SBUTTON_WIDTH,
828 .height = _BM_SBUTTON_HEIGHT
829 },
830 .bm_fill = BM_SBUTTON,
831 .update = button_show_qr_update,
832 .on_mup = button_show_qr_on_mup,
833 .disabled = false,
834 .button_text = {.i18nal = STR_SHOW_QR },
835 };
836
837 BUTTON button_qr = {
838 .panel = {
839 .type = PANEL_BUTTON,
840 .x = 10,
841 .y = 175,
842 .disabled = true,
843 },
844 .nodraw = true,
845 .disabled = true,
846 .onright = button_qr_on_mright,
847 };
848
849 BUTTON button_callpreview = {
850 .bm_fill = BM_LBUTTON,
851 .bm_icon = BM_CALL,
852 .icon_w = _BM_LBICON_WIDTH,
853 .icon_h = _BM_LBICON_HEIGHT,
854 .on_mup = button_audiopreview_on_mup,
855 .update = button_audiopreview_update,
856 .disabled = false,
857 };
858
859 BUTTON button_videopreview = {
860 .bm_fill = BM_LBUTTON,
861 .bm_icon = BM_VIDEO,
862 .icon_w = _BM_LBICON_WIDTH,
863 .icon_h = _BM_LBICON_HEIGHT,
864 .on_mup = button_videopreview_on_mup,
865 .update = button_videopreview_update,
866 .disabled = false,
867 };
868
869 BUTTON button_lock_uTox = {
870 .panel = {
871 .type = PANEL_BUTTON,
872 .x = 10,
873 .y = 265,
874 .width = _BM_SBUTTON_WIDTH,
875 .height = _BM_SBUTTON_HEIGHT,
876 },
877 .bm_fill = BM_SBUTTON,
878 .update = button_setcolors_success,
879 .on_mup = button_lock_uTox_on_mup,
880 .button_text = {.i18nal = STR_LOCK },
881 .tooltip_text = {.i18nal = STR_LOCK_UTOX },
882 };
883
884 BUTTON button_show_password_settings = {
885 .panel = {
886 .type = PANEL_BUTTON,
887 .x = 10,
888 .y = 177,
889 .width = _BM_SBUTTON_WIDTH,
890 .height = _BM_SBUTTON_HEIGHT,
891 },
892 .bm_fill = BM_SBUTTON,
893 .update = button_setcolors_success,
894 .on_mup = button_show_password_settings_on_mup,
895 .button_text = {.i18nal = STR_SHOW_UI_PASSWORD },
896 .tooltip_text = {.i18nal = STR_SHOW_UI_PASSWORD_TOOLTIP },
897 };
898
899 BUTTON button_export_chatlog = {
900 .panel = {
901 .type = PANEL_BUTTON,
902 .x = 10,
903 .y = 208,
904 .width = _BM_SBUTTON_WIDTH,
905 .height = _BM_SBUTTON_HEIGHT,
906 },
907 .bm_fill = BM_SBUTTON,
908 .update = button_setcolors_success,
909 .on_mup = button_export_chatlog_on_mup,
910 .disabled = false,
911 .button_text = {.i18nal = STR_FRIEND_EXPORT_CHATLOG },
912 .tooltip_text = {.i18nal = STR_FRIEND_EXPORT_CHATLOG },
913 };
914
915 BUTTON button_change_nospam = {
916 .panel = {
917 .type = PANEL_BUTTON,
918 .x = 10,
919 .y = 265,
920 .width = _BM_SBUTTON_WIDTH,
921 .height = _BM_SBUTTON_HEIGHT,
922 },
923 .bm_fill = BM_SBUTTON,
924 .update = button_setcolors_success,
925 .on_mup = button_change_nospam_on_mup,
926 .button_text = {.i18nal = STR_RANDOMIZE_NOSPAM},
927 .tooltip_text = {.i18nal = STR_RANDOMIZE_NOSPAM},
928 };
929
930 BUTTON button_revert_nospam = {
931 .bm_fill = BM_SBUTTON,
932 .update = button_revert_nospam_on_update,
933 .on_mup = button_revert_nospam_on_mup,
934 .disabled = true,
935 .button_text = {.i18nal = STR_REVERT_NOSPAM},
936 .tooltip_text = {.i18nal = STR_REVERT_NOSPAM},
937 };
938
939 BUTTON button_show_nospam = {
940 .bm_fill = BM_SBUTTON,
941 .update = button_setcolors_success,
942 .tooltip_text = {.i18nal = STR_SHOW_NOSPAM},
943 .button_text = {.i18nal = STR_SHOW_NOSPAM},
944 .on_mup = button_show_nospam_on_mup,
945 };
946
switchfxn_logging(void)947 static void switchfxn_logging(void) {
948 settings.logging_enabled = !settings.logging_enabled;
949 }
950
switchfxn_mini_contacts(void)951 static void switchfxn_mini_contacts(void) {
952 settings.use_mini_flist = !settings.use_mini_flist;
953 flist_re_scale();
954 }
955
switchfxn_ipv6(void)956 static void switchfxn_ipv6(void) {
957 settings.enable_ipv6 = !settings.enable_ipv6;
958 tox_settingschanged();
959 }
960
switchfxn_udp(void)961 static void switchfxn_udp(void) {
962 settings.enable_udp = !settings.enable_udp;
963 tox_settingschanged();
964 }
965
switchfxn_close_to_tray(void)966 static void switchfxn_close_to_tray(void) {
967 settings.close_to_tray = !settings.close_to_tray;
968 }
969
switchfxn_start_in_tray(void)970 static void switchfxn_start_in_tray(void) {
971 settings.start_in_tray = !settings.start_in_tray;
972 }
973
switchfxn_auto_startup(void)974 static void switchfxn_auto_startup(void) {
975 settings.start_with_system = !settings.start_with_system;
976 launch_at_startup(settings.start_with_system);
977 }
978
switchfxn_typing_notes(void)979 static void switchfxn_typing_notes(void) {
980 settings.send_typing_status = !settings.send_typing_status;
981 }
982
switchfxn_audible_notifications(void)983 static void switchfxn_audible_notifications(void) { settings.ringtone_enabled = !settings.ringtone_enabled; }
984
switchfxn_push_to_talk(void)985 static void switchfxn_push_to_talk(void) {
986 if (!settings.push_to_talk) {
987 init_ptt();
988 } else {
989 exit_ptt();
990 }
991 }
992
switchfxn_audio_filtering(void)993 static void switchfxn_audio_filtering(void) { settings.audiofilter_enabled = !settings.audiofilter_enabled; }
994
switchfxn_status_notifications(void)995 static void switchfxn_status_notifications(void) { settings.status_notifications = !settings.status_notifications; }
996
switchfxn_block_friend_requests(void)997 static void switchfxn_block_friend_requests(void) { settings.block_friend_requests = !settings.block_friend_requests; }
998
999 UISWITCH switch_save_chat_history = {
1000 .panel = {
1001 .type = PANEL_SWITCH,
1002 .x = 10,
1003 .y = 115,
1004 .width = _BM_SWITCH_WIDTH,
1005 .height = _BM_SWITCH_HEIGHT,
1006 },
1007 .style_outer = BM_SWITCH,
1008 .style_toggle = BM_SWITCH_TOGGLE,
1009 .style_icon_off = BM_NO,
1010 .style_icon_on = BM_YES,
1011 .update = switch_update,
1012 .on_mup = switchfxn_logging,
1013 .tooltip_text = {.i18nal = STR_SAVE_CHAT_HISTORY },
1014 };
1015
1016 UISWITCH switch_mini_contacts = {
1017 .panel = {
1018 .type = PANEL_SWITCH,
1019 .x = 10,
1020 .y = 235,
1021 .width = _BM_SWITCH_WIDTH,
1022 .height = _BM_SWITCH_HEIGHT,
1023 },
1024 .style_outer = BM_SWITCH,
1025 .style_toggle = BM_SWITCH_TOGGLE,
1026 .style_icon_off = BM_NO,
1027 .style_icon_on = BM_YES,
1028 .update = switch_update,
1029 .on_mup = switchfxn_mini_contacts,
1030 .tooltip_text = {.i18nal = STR_SETTINGS_UI_MINI_ROSTER },
1031 };
1032
1033
switchfxn_magic_sidebar(void)1034 static void switchfxn_magic_sidebar(void) {
1035 settings.magic_flist_enabled = !settings.magic_flist_enabled;
1036 }
1037
1038 UISWITCH switch_magic_sidebar = {
1039 .panel = {
1040 .type = PANEL_SWITCH,
1041 .x = -10 - _BM_SWITCH_WIDTH,
1042 .y = 210,
1043 .width = _BM_SWITCH_WIDTH,
1044 .height = _BM_SWITCH_HEIGHT
1045 },
1046 .style_outer = BM_SWITCH,
1047 .style_toggle = BM_SWITCH_TOGGLE,
1048 .style_icon_off = BM_NO,
1049 .style_icon_on = BM_YES,
1050 .update = switch_update,
1051 .on_mup = switchfxn_magic_sidebar,
1052 .tooltip_text = {.i18nal = STR_SETTINGS_UI_AUTO_HIDE_SIDEBAR },
1053 };
1054
1055 UISWITCH switch_ipv6 = {
1056 .panel = {
1057 .type = PANEL_SWITCH,
1058 .x = 10,
1059 .y = 27,
1060 .width = _BM_SWITCH_WIDTH,
1061 .height = _BM_SWITCH_HEIGHT,
1062 },
1063 .style_outer = BM_SWITCH,
1064 .style_toggle = BM_SWITCH_TOGGLE,
1065 .style_icon_off = BM_NO,
1066 .style_icon_on = BM_YES,
1067 .update = switch_update,
1068 .on_mup = switchfxn_ipv6,
1069 .tooltip_text = {.i18nal = STR_IPV6 },
1070 };
1071
1072 UISWITCH switch_udp = {
1073 .panel = {
1074 .type = PANEL_SWITCH,
1075 .x = 10,
1076 .y = 57,
1077 .width = _BM_SWITCH_WIDTH,
1078 .height = _BM_SWITCH_HEIGHT,
1079 },
1080 .style_outer = BM_SWITCH,
1081 .style_toggle = BM_SWITCH_TOGGLE,
1082 .style_icon_off = BM_NO,
1083 .style_icon_on = BM_YES,
1084 .update = switch_update,
1085 .on_mup = switchfxn_udp,
1086 .tooltip_text = {.i18nal = STR_UDP },
1087 };
1088
1089 UISWITCH switch_close_to_tray = {
1090 .panel = {
1091 .type = PANEL_SWITCH,
1092 .x = 10,
1093 .y = 145,
1094 .width = _BM_SWITCH_WIDTH,
1095 .height = _BM_SWITCH_HEIGHT,
1096 },
1097 .style_outer = BM_SWITCH,
1098 .style_toggle = BM_SWITCH_TOGGLE,
1099 .style_icon_off = BM_NO,
1100 .style_icon_on = BM_YES,
1101 .update = switch_update,
1102 .on_mup = switchfxn_close_to_tray,
1103 .tooltip_text = {.i18nal = STR_CLOSE_TO_TRAY },
1104 };
1105
1106 UISWITCH switch_start_in_tray = {
1107 .panel = {
1108 .type = PANEL_SWITCH,
1109 .x = 10,
1110 .y = 175,
1111 .width = _BM_SWITCH_WIDTH,
1112 .height = _BM_SWITCH_HEIGHT,
1113 },
1114 .style_outer = BM_SWITCH,
1115 .style_toggle = BM_SWITCH_TOGGLE,
1116 .style_icon_off = BM_NO,
1117 .style_icon_on = BM_YES,
1118 .update = switch_update,
1119 .on_mup = switchfxn_start_in_tray,
1120 .tooltip_text = {.i18nal = STR_START_IN_TRAY },
1121 };
1122
1123 UISWITCH switch_auto_startup = {
1124 .panel = {
1125 .type = PANEL_SWITCH,
1126 .x = 10,
1127 .y = 205,
1128 .width = _BM_SWITCH_WIDTH,
1129 .height = _BM_SWITCH_HEIGHT,
1130 },
1131 .style_outer = BM_SWITCH,
1132 .style_toggle = BM_SWITCH_TOGGLE,
1133 .style_icon_off = BM_NO,
1134 .style_icon_on = BM_YES,
1135 .update = switch_update,
1136 .on_mup = switchfxn_auto_startup,
1137 .tooltip_text = {.i18nal = STR_AUTO_STARTUP },
1138 };
1139
1140 UISWITCH switch_typing_notes = {
1141 .panel = {
1142 .type = PANEL_SWITCH,
1143 .x = 10,
1144 .y = 70,
1145 .width = _BM_SWITCH_WIDTH,
1146 .height = _BM_SWITCH_HEIGHT,
1147 },
1148 .style_outer = BM_SWITCH,
1149 .style_toggle = BM_SWITCH_TOGGLE,
1150 .style_icon_off = BM_NO,
1151 .style_icon_on = BM_YES,
1152 .update = switch_update,
1153 .on_mup = switchfxn_typing_notes,
1154 .tooltip_text = {.i18nal = STR_SEND_TYPING_NOTIFICATIONS },
1155 };
1156
1157 UISWITCH switch_audible_notifications = {
1158 .panel = {
1159 .type = PANEL_SWITCH,
1160 .x = 10,
1161 .y = 10,
1162 .width = _BM_SWITCH_WIDTH,
1163 .height = _BM_SWITCH_HEIGHT,
1164 },
1165 .style_outer = BM_SWITCH,
1166 .style_toggle = BM_SWITCH_TOGGLE,
1167 .style_icon_off = BM_NO,
1168 .style_icon_on = BM_YES,
1169 .update = switch_update,
1170 .on_mup = switchfxn_audible_notifications,
1171 .tooltip_text = {.i18nal = STR_AUDIONOTIFICATIONS },
1172 };
1173
1174 UISWITCH switch_push_to_talk = {
1175 .panel = {
1176 .type = PANEL_SWITCH,
1177 .x = 10,
1178 .y = 10,
1179 .width = _BM_SWITCH_WIDTH,
1180 .height = _BM_SWITCH_HEIGHT,
1181 },
1182 .style_outer = BM_SWITCH,
1183 .style_toggle = BM_SWITCH_TOGGLE,
1184 .style_icon_off = BM_NO,
1185 .style_icon_on = BM_YES,
1186 .update = switch_update,
1187 .on_mup = switchfxn_push_to_talk,
1188 .tooltip_text = {.i18nal = STR_PUSH_TO_TALK },
1189 };
1190
1191 UISWITCH switch_audio_filtering = {
1192 .style_outer = BM_SWITCH,
1193 .style_toggle = BM_SWITCH_TOGGLE,
1194 .style_icon_off = BM_NO,
1195 .style_icon_on = BM_YES,
1196 .update = switch_update,
1197 .on_mup = switchfxn_audio_filtering,
1198 .tooltip_text = {.i18nal = STR_AUDIOFILTERING },
1199 };
1200
1201 UISWITCH switch_status_notifications = {
1202 .panel = {
1203 .type = PANEL_SWITCH,
1204 .x = 10,
1205 .y = 40,
1206 .width = _BM_SWITCH_WIDTH,
1207 .height = _BM_SWITCH_HEIGHT,
1208 },
1209 .style_outer = BM_SWITCH,
1210 .style_toggle = BM_SWITCH_TOGGLE,
1211 .style_icon_off = BM_NO,
1212 .style_icon_on = BM_YES,
1213 .update = switch_update,
1214 .on_mup = switchfxn_status_notifications,
1215 .tooltip_text = {.i18nal = STR_STATUS_NOTIFICATIONS },
1216 };
1217
1218 UISWITCH switch_block_friend_requests = {
1219 .panel = {
1220 .type = PANEL_SWITCH,
1221 .x = 10,
1222 .y = 147,
1223 .width = _BM_SWITCH_WIDTH,
1224 .height = _BM_SWITCH_HEIGHT,
1225 },
1226 .style_outer = BM_SWITCH,
1227 .style_toggle = BM_SWITCH_TOGGLE,
1228 .style_icon_off = BM_NO,
1229 .style_icon_on = BM_YES,
1230 .update = switch_update,
1231 .on_mup = switchfxn_block_friend_requests,
1232 .tooltip_text = {.i18nal = STR_BLOCK_FRIEND_REQUESTS },
1233 };
1234
switchfxn_proxy(void)1235 static void switchfxn_proxy(void) {
1236 settings.use_proxy = !settings.use_proxy;
1237
1238 if (settings.use_proxy) {
1239 switch_proxy_force.panel.disabled = false;
1240 } else {
1241 settings.force_proxy = false;
1242 switch_proxy_force.switch_on = false;
1243 switch_proxy_force.panel.disabled = true;
1244 switch_udp.panel.disabled = false;
1245 }
1246
1247 memcpy(proxy_address, edit_proxy_ip.data, edit_proxy_ip.length);
1248 proxy_address[edit_proxy_ip.length] = 0;
1249
1250 edit_proxy_port.data[edit_proxy_port.length] = 0;
1251 settings.proxy_port = strtol((char *)edit_proxy_port.data, NULL, 0);
1252
1253 tox_settingschanged();
1254 }
1255
switchfxn_proxy_force(void)1256 static void switchfxn_proxy_force(void) {
1257 settings.force_proxy = !settings.force_proxy;
1258
1259 if (settings.force_proxy) {
1260 switch_udp.switch_on = false;
1261 settings.enable_udp = false;
1262 switch_udp.panel.disabled = true;
1263 } else {
1264 switch_udp.panel.disabled = false;
1265 }
1266
1267 edit_proxy_port.data[edit_proxy_port.length] = 0;
1268 settings.proxy_port = strtol((char *)edit_proxy_port.data, NULL, 0);
1269
1270 tox_settingschanged();
1271 }
1272
1273 UISWITCH switch_proxy = {
1274 .panel = {
1275 .type = PANEL_SWITCH,
1276 .x = 10,
1277 .y = 87,
1278 .width = _BM_SWITCH_WIDTH,
1279 .height = _BM_SWITCH_HEIGHT,
1280 },
1281 .style_outer = BM_SWITCH,
1282 .style_toggle = BM_SWITCH_TOGGLE,
1283 .style_icon_off = BM_NO,
1284 .style_icon_on = BM_YES,
1285 .update = switch_update,
1286 .on_mup = switchfxn_proxy,
1287 .tooltip_text = {.i18nal = STR_PROXY }
1288 };
1289
1290 UISWITCH switch_proxy_force = {
1291 .panel = {
1292 .type = PANEL_SWITCH,
1293 .x = 10,
1294 .y = 117,
1295 .width = _BM_SWITCH_WIDTH,
1296 .height = _BM_SWITCH_HEIGHT,
1297 },
1298 .style_outer = BM_SWITCH,
1299 .style_toggle = BM_SWITCH_TOGGLE,
1300 .style_icon_off = BM_NO,
1301 .style_icon_on = BM_YES,
1302 .update = switch_update,
1303 .on_mup = switchfxn_proxy_force,
1304 .tooltip_text = {.i18nal = STR_PROXY_FORCE },
1305 };
1306
dropdown_audio_in_onselect(uint16_t i,const DROPDOWN * dm)1307 static void dropdown_audio_in_onselect(uint16_t i, const DROPDOWN *dm) {
1308 DROP_ELEMENT *e = &((DROP_ELEMENT *)dm->userdata)[i];
1309 void * handle = e->handle;
1310 postmessage_utoxav(UTOXAV_SET_AUDIO_IN, 0, 0, handle);
1311 }
1312
dropdown_audio_out_onselect(uint16_t i,const DROPDOWN * dm)1313 static void dropdown_audio_out_onselect(uint16_t i, const DROPDOWN *dm) {
1314 DROP_ELEMENT *e = &((DROP_ELEMENT *)dm->userdata)[i];
1315 void * handle = e->handle;
1316 postmessage_utoxav(UTOXAV_SET_AUDIO_OUT, 0, 0, handle);
1317 }
1318
edit_video_fps_onlosefocus(EDIT * UNUSED (edit))1319 static void edit_video_fps_onlosefocus(EDIT *UNUSED(edit)) {
1320 edit_video_fps.data[edit_video_fps.length] = '\0';
1321
1322 char *temp;
1323 uint16_t value = strtol((char *)edit_video_fps.data, &temp, 10);
1324
1325 if (*temp == '\0' && value >= 1 && value <= UINT8_MAX) {
1326 settings.video_fps = value;
1327 return;
1328 }
1329
1330 LOG_WARN("Settings", "FPS value (%s) is invalid. It must be integer in range of [1,%u]. Setting default value (%u).",
1331 edit_video_fps.data, UINT8_MAX, DEFAULT_FPS);
1332
1333 settings.video_fps = DEFAULT_FPS;
1334 snprintf((char *)edit_video_fps.data, edit_video_fps.data_size,
1335 "%u", DEFAULT_FPS);
1336 edit_video_fps.length = strnlen((char *)edit_video_fps.data, edit_video_fps.data_size - 1);
1337 }
1338
1339 #include "../screen_grab.h"
dropdown_video_onselect(uint16_t i,const DROPDOWN * UNUSED (dm))1340 static void dropdown_video_onselect(uint16_t i, const DROPDOWN *UNUSED(dm)) {
1341 if (i == 1) {
1342 utox_screen_grab_desktop(1);
1343 } else {
1344 postmessage_utoxav(UTOXAV_SET_VIDEO_IN, i, 0, NULL);
1345 }
1346 }
1347
dropdown_dpi_onselect(uint16_t i,const DROPDOWN * UNUSED (dm))1348 static void dropdown_dpi_onselect(uint16_t i, const DROPDOWN *UNUSED(dm)) {
1349 ui_rescale(i + 5);
1350 }
1351
dropdown_language_onselect(uint16_t i,const DROPDOWN * UNUSED (dm))1352 static void dropdown_language_onselect(uint16_t i, const DROPDOWN *UNUSED(dm)) {
1353 settings.language = (UTOX_LANG)i;
1354 /* The draw functions need the fonts' and scale to be reset when changing languages. */
1355 ui_rescale(ui_scale);
1356 }
dropdown_language_ondisplay(uint16_t i,const DROPDOWN * UNUSED (dm))1357 static STRING *dropdown_language_ondisplay(uint16_t i, const DROPDOWN *UNUSED(dm)) {
1358 UTOX_LANG tmp_language = (UTOX_LANG)i;
1359 return SPTRFORLANG(tmp_language, STR_LANG_NATIVE_NAME);
1360 }
1361
dropdown_theme_onselect(const uint16_t i,const DROPDOWN * UNUSED (dm))1362 static void dropdown_theme_onselect(const uint16_t i, const DROPDOWN *UNUSED(dm)) {
1363 theme_load(i);
1364 settings.theme = i;
1365 }
1366
1367 #include"../groups.h"
dropdown_notify_groupchats_onselect(const uint16_t i,const DROPDOWN * UNUSED (dm))1368 static void dropdown_notify_groupchats_onselect(const uint16_t i, const DROPDOWN *UNUSED(dm)) {
1369 GROUPCHAT *g = flist_get_groupchat();
1370 if (!g) {
1371 LOG_ERR("Settings", "Could not get selected groupchat.");
1372 return;
1373 }
1374
1375 g->notify = i;
1376 LOG_INFO("Settings", "g->notify = %u\n", i);
1377 }
1378
dropdown_global_group_notifications_onselect(const uint16_t i,const DROPDOWN * UNUSED (dm))1379 static void dropdown_global_group_notifications_onselect(const uint16_t i, const DROPDOWN *UNUSED(dm)) {
1380 settings.group_notifications = i;
1381 }
1382
1383 static UTOX_I18N_STR dpidrops[] = {
1384 STR_DPI_TINY, STR_DPI_060, STR_DPI_070, STR_DPI_080, STR_DPI_090, STR_DPI_NORMAL, STR_DPI_110,
1385 STR_DPI_120, STR_DPI_130, STR_DPI_140, STR_DPI_BIG, STR_DPI_160, STR_DPI_170, STR_DPI_180,
1386 STR_DPI_190, STR_DPI_LARGE, STR_DPI_210, STR_DPI_220, STR_DPI_230, STR_DPI_240, STR_DPI_HUGE,
1387 };
1388
1389 DROPDOWN dropdown_audio_in = {
1390 .ondisplay = dropdown_list_ondisplay,
1391 .onselect = dropdown_audio_in_onselect
1392 };
1393
1394 DROPDOWN dropdown_audio_out = {
1395 .ondisplay = dropdown_list_ondisplay,
1396 .onselect = dropdown_audio_out_onselect
1397 };
1398
1399 DROPDOWN dropdown_video = {
1400 .ondisplay = dropdown_list_ondisplay,
1401 .onselect = dropdown_video_onselect,
1402 };
1403
1404 DROPDOWN dropdown_dpi = {
1405 .panel = {
1406 .type = PANEL_DROPDOWN,
1407 .x = 150,
1408 .y = 85,
1409 .width = 200,
1410 .height = 24,
1411 },
1412 .ondisplay = simple_dropdown_ondisplay,
1413 .onselect = dropdown_dpi_onselect,
1414 .dropcount = COUNTOF(dpidrops),
1415 .userdata = dpidrops
1416 };
1417
1418 DROPDOWN dropdown_language = {
1419 .panel = {
1420 .type = PANEL_DROPDOWN,
1421 .x = 10,
1422 .y = 30,
1423 .width = -10,
1424 .height = 24
1425 },
1426 .ondisplay = dropdown_language_ondisplay,
1427 .onselect = dropdown_language_onselect,
1428 .dropcount = NUM_LANGS,
1429 };
1430
1431
1432 static UTOX_I18N_STR themedrops[] = {
1433 STR_THEME_DEFAULT,
1434 STR_THEME_LIGHT,
1435 STR_THEME_DARK,
1436 STR_THEME_HIGHCONTRAST,
1437 STR_THEME_CUSTOM,
1438 STR_THEME_ZENBURN,
1439 STR_THEME_SOLARIZED_LIGHT,
1440 STR_THEME_SOLARIZED_DARK,
1441 };
1442
1443 DROPDOWN dropdown_theme = {
1444 .panel = {
1445 .type = PANEL_DROPDOWN,
1446 .x = 10,
1447 .y = 85,
1448 .width = 120,
1449 .height = 24,
1450 },
1451 .ondisplay = simple_dropdown_ondisplay,
1452 .onselect = dropdown_theme_onselect,
1453 .dropcount = COUNTOF(themedrops),
1454 .userdata = themedrops
1455 };
1456
1457 static UTOX_I18N_STR notifydrops[] = {
1458 STR_GROUP_NOTIFICATIONS_OFF, STR_GROUP_NOTIFICATIONS_MENTION, STR_GROUP_NOTIFICATIONS_ON,
1459 };
1460
1461 DROPDOWN dropdown_notify_groupchats = {
1462 .panel = {
1463 .type = PANEL_DROPDOWN,
1464 .x = 10,
1465 .y = 138,
1466 .width = 100,
1467 .height = 24
1468 },
1469 .ondisplay = simple_dropdown_ondisplay,
1470 .onselect = dropdown_notify_groupchats_onselect,
1471 .dropcount = COUNTOF(notifydrops),
1472 .userdata = notifydrops
1473 };
1474
1475 DROPDOWN dropdown_global_group_notifications = {
1476 .panel = {
1477 .type = PANEL_DROPDOWN,
1478 .x = 10,
1479 .y = 125,
1480 .width = 100,
1481 .height = 24,
1482 },
1483 .ondisplay = simple_dropdown_ondisplay,
1484 .onselect = dropdown_global_group_notifications_onselect,
1485 .dropcount = COUNTOF(notifydrops),
1486 .userdata = notifydrops
1487 };
1488
1489 static char edit_name_data[128],
1490 edit_status_msg_data[128],
1491 edit_proxy_ip_data[256],
1492 edit_proxy_port_data[8],
1493 edit_video_fps_data[3 + 1], /* range is [1-255] */
1494 edit_profile_password_data[65535],
1495 edit_nospam_data[(sizeof(uint32_t) * 2) + 1] = { 0 };
1496 #ifdef ENABLE_MULTIDEVICE
1497 static char edit_add_self_device_data[TOX_ADDRESS_SIZE * 4];
1498 #endif
1499
1500
edit_name_onenter(EDIT * edit)1501 static void edit_name_onenter(EDIT *edit) {
1502 char * data = edit->data;
1503 uint16_t length = edit->length;
1504
1505 memcpy(self.name, data, length);
1506 self.name_length = length;
1507 update_tray();
1508
1509 postmessage_toxcore(TOX_SELF_SET_NAME, length, 0, self.name);
1510 }
1511
edit_name_ontab(EDIT * UNUSED (edit))1512 static void edit_name_ontab(EDIT *UNUSED(edit)) {
1513 edit_setfocus(&edit_status_msg);
1514 }
1515
edit_name_onshifttab(EDIT * UNUSED (edit))1516 static void edit_name_onshifttab(EDIT *UNUSED(edit)) {
1517 edit_setfocus(&edit_toxid);
1518 }
1519
1520 EDIT edit_name = {
1521 .panel = {
1522 .type = PANEL_EDIT,
1523 .x = 10,
1524 .y = 30,
1525 .width = -10,
1526 .height = 24,
1527 },
1528 .data = edit_name_data,
1529 .data_size = sizeof edit_name_data,
1530 .onenter = edit_name_onenter,
1531 .onlosefocus = edit_name_onenter,
1532 .ontab = edit_name_ontab,
1533 .onshifttab = edit_name_onshifttab,
1534 };
1535
edit_status_msg_onenter(EDIT * edit)1536 static void edit_status_msg_onenter(EDIT *edit) {
1537 char * data = edit->data;
1538 uint16_t length = edit->length;
1539
1540 if (length) {
1541 length = (length <= TOX_MAX_STATUS_MESSAGE_LENGTH) ? length : TOX_MAX_STATUS_MESSAGE_LENGTH;
1542 memcpy(self.statusmsg, data, length);
1543 self.statusmsg_length = length;
1544 } else {
1545 self.statusmsg_length = length;
1546 }
1547
1548 update_tray();
1549
1550 postmessage_toxcore(TOX_SELF_SET_STATUS, length, 0, self.statusmsg); //!
1551 }
1552
edit_status_msg_ontab(EDIT * UNUSED (edit))1553 static void edit_status_msg_ontab(EDIT *UNUSED(edit)) {
1554 edit_setfocus(&edit_toxid);
1555 }
1556
edit_status_msg_onshifttab(EDIT * UNUSED (edit))1557 static void edit_status_msg_onshifttab(EDIT *UNUSED(edit)) {
1558 edit_setfocus(&edit_name);
1559 }
1560
1561 EDIT edit_status_msg = {
1562 .panel = {
1563 .type = PANEL_EDIT,
1564 .x = 10,
1565 .y = 85,
1566 .width = -10,
1567 .height = 24,
1568 },
1569 .data = edit_status_msg_data,
1570 .data_size = sizeof edit_status_msg_data,
1571 .onenter = edit_status_msg_onenter,
1572 .onlosefocus = edit_status_msg_onenter,
1573 .ontab = edit_status_msg_ontab,
1574 .onshifttab = edit_status_msg_onshifttab,
1575 };
1576
1577
edit_proxy_ip_port_onlosefocus(EDIT * UNUSED (edit))1578 static void edit_proxy_ip_port_onlosefocus(EDIT *UNUSED(edit)) {
1579 edit_proxy_port.data[edit_proxy_port.length] = 0;
1580
1581 settings.proxy_port = strtol((char *)edit_proxy_port.data, NULL, 0);
1582
1583 if (memcmp(proxy_address, edit_proxy_ip.data, edit_proxy_ip.length) == 0 && proxy_address[edit_proxy_ip.length] == 0) {
1584 return;
1585 }
1586
1587 memset(proxy_address, 0, 256); /* Magic number from toxcore */
1588 memcpy(proxy_address, edit_proxy_ip.data, edit_proxy_ip.length);
1589 proxy_address[edit_proxy_ip.length] = 0;
1590
1591
1592 if (settings.use_proxy) {
1593 tox_settingschanged();
1594 }
1595 }
1596
edit_proxy_ip_ontab(EDIT * UNUSED (edit))1597 static void edit_proxy_ip_ontab(EDIT *UNUSED(edit)) {
1598 edit_setfocus(&edit_proxy_port);
1599 }
1600
1601 EDIT edit_proxy_ip = {
1602 .panel = {
1603 .type = PANEL_EDIT,
1604 .x = 230,
1605 .y = 87,
1606 .width = 120,
1607 .height = 24,
1608 },
1609 .data = edit_proxy_ip_data,
1610 .data_size = sizeof edit_proxy_ip_data,
1611 .empty_str = {.i18nal = STR_PROXY_EDIT_HINT_IP },
1612 .onlosefocus = edit_proxy_ip_port_onlosefocus,
1613 .ontab = edit_proxy_ip_ontab,
1614 .onshifttab = edit_proxy_ip_ontab,
1615 };
1616
edit_proxy_port_ontab(EDIT * UNUSED (edit))1617 static void edit_proxy_port_ontab(EDIT *UNUSED(edit)) {
1618 edit_setfocus(&edit_proxy_ip);
1619 }
1620
1621 EDIT edit_proxy_port = {
1622 .panel = {
1623 .type = PANEL_EDIT,
1624 .x = 360,
1625 .y = 87,
1626 .width = 60,
1627 .height = 24,
1628 },
1629 .data = edit_proxy_port_data,
1630 .data_size = sizeof edit_proxy_port_data,
1631 .empty_str = {.i18nal = STR_PROXY_EDIT_HINT_PORT },
1632 .onlosefocus = edit_proxy_ip_port_onlosefocus,
1633 .ontab = edit_proxy_port_ontab,
1634 .onshifttab = edit_proxy_port_ontab,
1635 };
1636
1637 EDIT edit_video_fps = {
1638 .data = edit_video_fps_data,
1639 .data_size = sizeof edit_video_fps_data,
1640 .onlosefocus = edit_video_fps_onlosefocus,
1641 /* .empty_str = {.i18nal = STR_PROXY_EDIT_HINT_PORT }, */
1642 };
1643
edit_profile_password_update(EDIT * UNUSED (edit))1644 static void edit_profile_password_update(EDIT *UNUSED(edit)) {
1645 if (tox_thread_init) {
1646 postmessage_toxcore(TOX_SAVE, 0, 0, NULL);
1647 }
1648 }
1649
1650 EDIT edit_profile_password = {
1651 .panel = {
1652 .type = PANEL_EDIT,
1653 .x = 10,
1654 .y = 55,
1655 .width = -10,
1656 .height = 24,
1657 },
1658 .data_size = sizeof edit_profile_password_data,
1659 .data = edit_profile_password_data,
1660 // .onchange = edit_profile_password_update,
1661 .onlosefocus = edit_profile_password_update,
1662 .password = 1,
1663 };
1664
edit_toxid_ontab(EDIT * UNUSED (edit))1665 static void edit_toxid_ontab(EDIT *UNUSED(edit)) {
1666 edit_setfocus(&edit_name);
1667 }
1668
edit_toxid_onshifttab(EDIT * UNUSED (edit))1669 static void edit_toxid_onshifttab(EDIT *UNUSED(edit)) {
1670 edit_setfocus(&edit_status_msg);
1671 }
1672
1673 EDIT edit_toxid = {
1674 .panel = {
1675 .type = PANEL_EDIT,
1676 .x = 10,
1677 .y = 140,
1678 .width = -10,
1679 .height = 24,
1680 },
1681 .length = TOX_ADDRESS_SIZE * 2,
1682 .data = self.id_str,
1683 .readonly = 1,
1684 .noborder = 0,
1685 .select_completely = 1,
1686 .ontab = edit_toxid_ontab,
1687 .onshifttab = edit_toxid_onshifttab,
1688 };
1689
edit_change_nospam_onenter(EDIT * edit)1690 static void edit_change_nospam_onenter(EDIT *edit) {
1691 char *endptr;
1692 edit_nospam_data[edit->length] = '\0';
1693 long int nospam = strtol(edit_nospam_data, &endptr, 16);
1694 if (nospam == 0 || nospam < 0) {
1695 LOG_ERR("Nospam", "Invalid nospam value: %lu", nospam);
1696 return;
1697 } else if (endptr == edit_nospam_data) {
1698 LOG_ERR("Nospam", "No numbers found.");
1699 return;
1700 }
1701 postmessage_toxcore(TOX_SELF_CHANGE_NOSPAM, nospam, 0, NULL);
1702 }
1703
1704 EDIT edit_nospam = {
1705 .panel = {
1706 .type = PANEL_EDIT,
1707 .x = 10,
1708 .y = 235,
1709 .width = -10,
1710 .height = 24,
1711 },
1712 .data_size = sizeof edit_nospam_data,
1713 .data = edit_nospam_data,
1714 .noborder = false,
1715 .onenter = edit_change_nospam_onenter,
1716 .onlosefocus = edit_change_nospam_onenter,
1717 };
1718
1719
1720 static char edit_add_new_device_to_self_data[TOX_ADDRESS_SIZE * 4];
edit_add_new_device_to_self_onenter(EDIT * UNUSED (edit))1721 static void edit_add_new_device_to_self_onenter(EDIT *UNUSED(edit)) {
1722 #ifdef ENABLE_MULTIDEVICE
1723 devices_self_add(edit_add_new_device_to_self.data, edit_add_new_device_to_self.length);
1724 #endif
1725 }
1726
1727 EDIT edit_add_new_device_to_self = {
1728 .data = edit_add_new_device_to_self_data,
1729 .data_size = sizeof edit_add_new_device_to_self_data,
1730 .onenter = edit_add_new_device_to_self_onenter,
1731 };
1732