1 /*
2 * Copyright (C) 2020 The HIME team, Taiwan
3 * Copyright (C) 2011 Edward Der-Hua Liu, Hsin-Chu, Taiwan
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation version 2.1
8 * of the License.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 #include "hime.h"
21
22 #include "gtab.h"
23 #include "pho.h"
24 #include "win-save-phrase.h"
25
26 extern int c_len;
27 extern gboolean test_mode;
28
29 typedef struct {
30 WSP_S *mywsp;
31 int mywspN;
32 GtkWidget *label_countdown, *win;
33 int countdown, countdown_handle;
34 } SAVE_SESS;
35
wsp_str(WSP_S * wsp,int wspN,char * out)36 static void wsp_str (WSP_S *wsp, int wspN, char *out) {
37 int i;
38 int ofs = 0;
39
40 for (i = 0; i < wspN; i++) {
41 // utf8_putchar(wsp[i].ch);
42 int n = utf8cpy (out + ofs, wsp[i].ch);
43 ofs += n;
44 }
45
46 // out[ofs]=0;
47 // dbg(" c_len:%d wsp %s\n", c_len, out);
48 }
49
free_mywsp(SAVE_SESS * sess)50 static void free_mywsp (SAVE_SESS *sess) {
51 free (sess->mywsp);
52 sess->mywsp = NULL;
53 free (sess);
54 }
55
close_win_save_phrase(GtkWidget * widget,gpointer data)56 static gboolean close_win_save_phrase (GtkWidget *widget, gpointer data) {
57 SAVE_SESS *sess = (SAVE_SESS *) data;
58
59 g_source_remove (sess->countdown_handle);
60 gtk_widget_destroy (sess->win);
61 free_mywsp (sess);
62 return TRUE;
63 }
64
65 #if 0
66 static gint delete_event( GtkWidget *widget,
67 GdkEvent *event,
68 gpointer data)
69 {
70 free_mywsp(data);
71 return FALSE;
72 }
73 #endif
74
75 extern int ph_key_sz;
76
cb_ok(GtkWidget * widget,gpointer data)77 static gboolean cb_ok (GtkWidget *widget, gpointer data) {
78 SAVE_SESS *sess = (SAVE_SESS *) data;
79 g_source_remove (sess->countdown_handle);
80
81 int i;
82 phokey_t pho[MAX_PHRASE_LEN];
83 u_int pho32[MAX_PHRASE_LEN];
84 u_int64_t pho64[MAX_PHRASE_LEN];
85 char tt[512];
86 void *dat = NULL;
87 wsp_str (sess->mywsp, sess->mywspN, tt);
88
89 if (ph_key_sz == 2) {
90 for (i = 0; i < sess->mywspN; i++)
91 pho[i] = sess->mywsp[i].key;
92 dat = pho;
93 } else if (ph_key_sz == 4) {
94 for (i = 0; i < sess->mywspN; i++) {
95 pho32[i] = sess->mywsp[i].key;
96 }
97 dat = pho32;
98 } else if (ph_key_sz == 8) {
99 for (i = 0; i < sess->mywspN; i++)
100 pho64[i] = sess->mywsp[i].key;
101 dat = pho64;
102 }
103
104 save_phrase_to_db (dat, tt, sess->mywspN, 1);
105
106 gtk_widget_destroy (sess->win);
107
108 free_mywsp (sess);
109 return TRUE;
110 }
111
disp_countdown(SAVE_SESS * sess)112 static void disp_countdown (SAVE_SESS *sess) {
113 char tt[64];
114
115 snprintf (tt, sizeof (tt), _ ("Auto-append after %d second(s)"), sess->countdown);
116 gtk_label_set_text (GTK_LABEL (sess->label_countdown), tt);
117 }
118
timeout_countdown(gpointer data)119 gboolean timeout_countdown (gpointer data) {
120 SAVE_SESS *sess = (SAVE_SESS *) data;
121
122 if (!sess->countdown) {
123 cb_ok (NULL, data);
124 return FALSE;
125 }
126
127 sess->countdown--;
128 disp_countdown (sess);
129 return TRUE;
130 }
131
create_win_save_phrase(WSP_S * wsp,int wspN)132 void create_win_save_phrase (WSP_S *wsp, int wspN) {
133 if (!wspN)
134 return;
135
136 SAVE_SESS *sess = tzmalloc (SAVE_SESS, 1);
137
138 GtkWidget *main_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
139 gtk_window_set_has_resize_grip (GTK_WINDOW (main_window), FALSE);
140 sess->win = main_window;
141
142 gtk_window_set_default_size (GTK_WINDOW (main_window), 20, 10);
143
144 gtk_window_set_title (GTK_WINDOW (main_window), _ ("Add phrase to Tsin's database"));
145
146 #if 0
147 g_signal_connect (G_OBJECT (main_window), "delete-event",
148 G_CALLBACK (delete_event), sess);
149 #endif
150
151 GtkWidget *vbox = gtk_vbox_new (FALSE, 0);
152 gtk_orientable_set_orientation (GTK_ORIENTABLE (vbox), GTK_ORIENTATION_VERTICAL);
153 gtk_container_add (GTK_CONTAINER (main_window), vbox);
154
155 char tt[512];
156 tt[0] = 0;
157 wsp_str (wsp, wspN, tt);
158
159 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new (tt), FALSE, FALSE, 0);
160
161 int i;
162 for (i = 0; i < wspN; i++) {
163 if (ph_key_sz == 2)
164 strcat (tt, phokey_to_str (wsp[i].key));
165 strcat (tt, " ");
166 }
167
168 if (tt[0])
169 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new (tt), FALSE, FALSE, 0);
170
171 sess->mywsp = tmemdup (wsp, WSP_S, wspN);
172 sess->mywspN = wspN;
173
174 GtkWidget *hbox_cancel_ok = gtk_hbox_new (FALSE, 10);
175 gtk_box_pack_start (GTK_BOX (vbox), hbox_cancel_ok, FALSE, FALSE, 5);
176
177 GtkWidget *button_ok = gtk_button_new_from_stock (GTK_STOCK_OK);
178 gtk_box_pack_start (GTK_BOX (hbox_cancel_ok), button_ok, TRUE, TRUE, 5);
179
180 GtkWidget *button_cancel = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
181 gtk_box_pack_start (GTK_BOX (hbox_cancel_ok), button_cancel, TRUE, TRUE, 0);
182
183 sess->label_countdown = gtk_label_new (NULL);
184 gtk_box_pack_start (GTK_BOX (vbox), sess->label_countdown, FALSE, FALSE, 5);
185
186 gtk_widget_realize (main_window);
187 set_no_focus (main_window);
188
189 // dbg("mmmmmmmmmmmmm\n");
190
191 gtk_widget_set_can_default (button_ok, 1);
192 gtk_widget_grab_default (button_ok);
193
194 #if 1
195 // dbg("main_window %x\n", main_window);
196 g_signal_connect (G_OBJECT (button_cancel), "clicked",
197 G_CALLBACK (close_win_save_phrase),
198 sess);
199
200 g_signal_connect (G_OBJECT (button_ok), "clicked",
201 G_CALLBACK (cb_ok),
202 sess);
203 #endif
204
205 gtk_window_present (GTK_WINDOW (main_window));
206 gtk_window_set_keep_above (GTK_WINDOW (main_window), TRUE);
207 // gtk_window_set_modal(GTK_WINDOW(main_window), TRUE);
208
209 sess->countdown = 3;
210 disp_countdown (sess);
211 sess->countdown_handle = g_timeout_add (1000, timeout_countdown, sess);
212 gtk_widget_show_all (main_window);
213 }
214