1 /*********************************************************************
2 *
3 * main.cxx
4 *
5 * Kasumi - a management tool for a private dictionary of anthy
6 *
7 * Copyright (C) 2004-2006 Takashi Nakamoto
8 * Copyright (C) 2005 Takuro Ashie
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
23 * MA 02110-1301, USA.
24 *
25 *********************************************************************/
26
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30
31 #include <gtk/gtk.h>
32 #include <cstdlib>
33 #include <cstring>
34 #include <time.h>
35 #include <iostream>
36 #include <string>
37 #include "KasumiDic.hxx"
38 #include "KasumiMainWindow.hxx"
39 #include "KasumiAddWindow.hxx"
40 #include "KasumiConfiguration.hxx"
41 #include "KasumiException.hxx"
42 #include "intl.h"
43 extern "C"{ // ad-hoc solution for a defect of Anthy
44 #include <anthy/anthy.h>
45 #include <anthy/dicutil.h>
46 }
47
48 using namespace std;
49
showHelp()50 void showHelp(){
51 cout << "Usage: kasumi [option]" << endl;
52 cout << "Option:" << endl;
53 cout << " -h --help Show this message." << endl;
54 cout << " -v --version Show Kasumi's version and copyright" << endl;;
55 cout << " information" << endl;
56 cout << " -m --manage Run Kasumi in Manage mode." << endl;
57 cout << " You may abbreviate this option." << endl;
58 cout << " -a --add Run Kasumi in Add mode." << endl;
59 cout << " -e --exclusive Run Kasumi in Exclusive mode." << endl;
60 cout << " --sound val Set default sound entry (only in Add mode)" << endl;
61 cout << " --spelling val Set default spelling entry (only in Add mode)" << endl;
62 cout << " --wordclass val Set default word class entry (only in Add mode)" << endl;
63 // cout << " -x val Set default horizontal window position" << endl;
64 // cout << " -y val Set default vertical window position" << endl;
65 cout << " -i --import Import selected text as a spelling" << endl;
66 cout << " -I --ignore Ignore selected text" << endl;
67 #ifdef HAS_ANTHY_DICUTIL_SET_ENCODING
68 cout << " -E --eucjp Use EUC-JP encoding for dictionary" << endl;
69 #endif // HAS_ANTHY_DICUTIL_SET_ENCODING
70 cout << endl;
71 }
72
showVersion()73 void showVersion(){
74 cout << "Kasumi " << VERSION << " - a personal dictionary manager for Anthy" << endl;
75 cout << "Copyright (C) 2004-2006 Takashi Nakamoto.\n";
76 cout << "This program comes with NO WARRANTY, to the extent permitted " \
77 "by law. \nYou may redistribute it under the terms of the GNU " \
78 "General Public License; \nsee the file named COPYING for " \
79 "details.";
80 cout << endl;
81 }
82
83
84 enum {
85 TARGET_STRING
86 };
87
88 static GtkTargetEntry targets[]={
89 {"STRING", 0, TARGET_STRING},
90 };
91 static GdkAtom atom0; /* for checking process */
92 static GdkAtom atom1; /* for sending arguments */
93 static gchar *arg_text = NULL;
94 static gint instance = -1;
95
cb_selection_get(GtkWidget * widget,GtkSelectionData * data,guint info,guint time,GtkWidget * window)96 static void cb_selection_get(GtkWidget *widget,
97 GtkSelectionData *data,
98 guint info,
99 guint time,
100 GtkWidget *window)
101 {
102 gchar *text = NULL;
103 gint length = 0;
104
105 if (data->selection == atom0) {
106 text = "Kasumi Selection";
107 length = strlen(text);
108 gtk_selection_convert(window, atom1,
109 GDK_SELECTION_TYPE_STRING,
110 GDK_CURRENT_TIME);
111 } else if (data->selection == atom1 && arg_text != NULL) {
112 text = arg_text;
113 arg_text = NULL;
114 length = strlen(text);
115 }
116
117 if (text != NULL) {
118 gtk_selection_data_set_text(data, text, length);
119 if (data->selection == atom1)
120 g_free(text);
121 }
122 }
123
cb_selection_received(GtkWidget * widget,GtkSelectionData * data,guint time,gpointer user_data)124 static void cb_selection_received(GtkWidget *widget,
125 GtkSelectionData *data,
126 guint time,
127 gpointer user_data)
128 {
129 if (data->selection == atom0) {
130 instance = MAX(data->length, 0);
131 } else if (data->selection == atom1 && data->length > 0) {
132 }
133 }
134
check_duplicated_process(int argc,char * argv[])135 static GtkWidget *check_duplicated_process (int argc, char *argv[])
136 {
137 GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
138 gint i, length = 0;
139
140 gtk_widget_realize(window);
141
142 atom0 = gdk_atom_intern("Kasumi InterProcess communication 0",
143 FALSE);
144 atom1 = gdk_atom_intern("Kasumi InterProcess communication 1",
145 FALSE);
146
147 gtk_selection_add_targets(window, atom0, targets, 1);
148 gtk_selection_add_targets(window, atom1, targets, 1);
149 g_signal_connect (window, "selection-get",
150 G_CALLBACK(cb_selection_get), window);
151 g_signal_connect (window, "selection-received",
152 G_CALLBACK(cb_selection_received), window);
153
154 for (i = 0; i < argc; i++) {
155 gint len;
156
157 len = strlen(argv[i]) * sizeof(gchar);
158 arg_text = (gchar*) g_realloc(arg_text,
159 length + len + sizeof(gchar));
160 g_memmove(arg_text + length, argv[i], len);
161 length += len;
162 arg_text[length++] = '\n';
163 }
164 if (length > 0) {
165 arg_text[length - 1] = '\0';
166 gtk_selection_owner_set(window, atom1, GDK_CURRENT_TIME);
167 }
168 gtk_selection_convert(window,atom0,
169 GDK_SELECTION_TYPE_STRING,
170 GDK_CURRENT_TIME);
171 while (instance < 0)
172 while (gtk_events_pending())
173 gtk_main_iteration();
174 if (instance > 0) {
175 /* Kasumi process already exists */
176 while (arg_text != NULL)
177 while (gtk_events_pending())
178 gtk_main_iteration();
179 gtk_widget_destroy(window);
180 cerr << "Kasumi process already exists." << endl;
181 return NULL;
182 }
183 g_free(arg_text);
184 arg_text = NULL;
185 gtk_selection_owner_set(window, atom0, GDK_CURRENT_TIME);
186
187 return window;
188 }
189
main(int argc,char * argv[])190 int main(int argc, char *argv[])
191 {
192 gtk_init(&argc, &argv);
193
194 #ifdef ENABLE_NLS
195 // for gettext
196 setlocale(LC_ALL, "");
197 bindtextdomain(PACKAGE, LOCALEDIR);
198 bind_textdomain_codeset(PACKAGE, "UTF-8");
199 textdomain(PACKAGE);
200 #endif // #ifdef ENABLE_NLS
201
202 GtkWidget *server = check_duplicated_process (argc, argv);
203 if (!server)
204 return 0;
205
206 try{
207 anthy_dic_util_init();
208
209 KasumiWordType::initWordTypeList();
210 KasumiConfiguration *conf = new KasumiConfiguration(argc, argv);
211
212 #ifdef HAS_ANTHY_DICUTIL_SET_ENCODING
213 if (conf->getPropertyValueByBool("UseEUCJP"))
214 anthy_dic_util_set_encoding(ANTHY_EUC_JP_ENCODING);
215 else
216 anthy_dic_util_set_encoding(ANTHY_UTF8_ENCODING);
217 #endif // HAS_ANTHY_DICUTIL_SET_ENCODING
218
219 KasumiDic *dic = new KasumiDic(conf);
220
221 string startupMode = conf->getPropertyValue("StartupMode");
222 if(startupMode == string("HELP")){
223 showHelp();
224 }else if(startupMode == string("VERSION")){
225 showVersion();
226 }else if(startupMode == string("MANAGE")){
227 new KasumiMainWindow(dic,conf);
228 gtk_main();
229 }else if(startupMode == string("ADD")){
230 new KasumiAddWindow(dic,conf);
231 gtk_main();
232 }else if(startupMode == string("EXCLUSIVE")){
233 new KasumiAddWindow(dic,conf);
234 gtk_main();
235 }
236 }catch(KasumiException e){
237 handleException(e);
238 }
239
240 gtk_widget_destroy (server);
241
242 return 0;
243 }
244
245