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