2
* Copyright (c) 2010 Mike Qin <mikeandmore@gmail.com>
4
* The contents of this file are subject to the terms of either the GNU Lesser
5
* General Public License Version 2.1 only ("LGPL") or the Common Development and
6
* Distribution License ("CDDL")(collectively, the "License"). You may not use this
7
* file except in compliance with the License. You can obtain a copy of the CDDL at
8
* http://www.opensource.org/licenses/cddl1.php and a copy of the LGPLv2.1 at
9
* http://www.opensource.org/licenses/lgpl-license.php. See the License for the
10
* specific language governing permissions and limitations under the License. When
11
* distributing the software, include this License Header Notice in each file and
12
* include the full text of the License in the License file as well as the
15
* NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND DISTRIBUTION LICENSE
17
* For Covered Software in this distribution, this License shall be governed by the
18
* laws of the State of California (excluding conflict-of-law provisions).
19
* Any litigation relating to this License shall be subject to the jurisdiction of
20
* the Federal Courts of the Northern District of California and the state courts
21
* of the State of California, with venue lying in Santa Clara County, California.
25
* If you wish your version of this file to be governed by only the CDDL or only
26
* the LGPL Version 2.1, indicate your decision by adding "[Contributor]" elects to
27
* include this software in this distribution under the [CDDL or LGPL Version 2.1]
28
* license." If you don't indicate a single choice of license, a recipient has the
29
* option to distribute your version of this file under either the CDDL or the LGPL
30
* Version 2.1, or to extend the choice of license to its licensees as provided
31
* above. However, if you add LGPL Version 2.1 code and therefore, elected the LGPL
32
* Version 2 license, then the option applies only if the new code is made subject
33
* to such option by the copyright holder.
37
#include <sunpinyin.h>
38
#include <ime-core/imi_glibHandler.h>
43
#include "sunpinyin_preedit_ui.h"
47
class WindowHandler : public CIMIGlibHandler
50
virtual void updatePreedit(const IPreeditString* ppd);
51
virtual void updateCandidates(const ICandidateList* pcl);
52
virtual void updateStatus(int key, int value);
53
virtual void commit(const TWCHAR* str);
61
virtual ~WindowHandler();
63
PreeditUI* preedit_ui_impl() { return ui_impl_; }
64
void set_preedit_ui_impl(PreeditUI* ui_impl) {
68
void set_xim_handle(XIMHandle* handle) {
76
void update_preedit_ui(const IPreeditString* ppd, const char* utf_str);
77
void update_candidates_ui(const ICandidateList* pcl, const char* utf_str);
80
void move(int x, int y);
96
WindowHandler::WindowHandler()
98
preedit_str_ = new char[BUF_SIZE];
99
candidate_str_ = new char[BUF_SIZE];
107
WindowHandler::~WindowHandler()
109
delete [] preedit_str_;
110
delete [] candidate_str_;
114
WindowHandler::reload_ui()
117
ui_impl_->update_preedit_string(preedit_str_);
118
ui_impl_->update_candidates_string(candidate_str_);
121
ui_impl_->move(x_, y_);
128
WindowHandler::pause()
138
WindowHandler::move(int x, int y)
143
ui_impl_->move(x, y);
148
WindowHandler::go_on()
150
if (!status_ && pause_) {
158
WindowHandler::update_candidates_ui(const ICandidateList* pcl, const char* utf_str)
160
ui_impl_->update_candidates_string(utf_str);
169
WindowHandler::update_preedit_ui(const IPreeditString* ppd, const char* utf_str)
171
ui_impl_->update_preedit_string(utf_str);
172
if (ppd->size() == 0) {
180
WindowHandler::updatePreedit(const IPreeditString* ppd)
182
TIConvSrcPtr src = (TIConvSrcPtr) (ppd->string());
183
TWCHAR* front_src = new TWCHAR[BUF_SIZE];
184
TWCHAR* end_src = new TWCHAR[BUF_SIZE];
186
memset(front_src, 0, BUF_SIZE * sizeof(TWCHAR));
187
memset(end_src, 0, BUF_SIZE * sizeof(TWCHAR));
189
memcpy(front_src, src, ppd->caret() * sizeof(TWCHAR));
190
memcpy(end_src, src + ppd->caret() * sizeof(TWCHAR),
191
(ppd->size() - ppd->caret() + 1) * sizeof(TWCHAR));
193
memset(preedit_str_, 0, BUF_SIZE);
195
WCSTOMBS(preedit_str_, front_src, BUF_SIZE - 1);
196
preedit_str_[strlen(preedit_str_)] = '|';
197
WCSTOMBS(&preedit_str_[strlen(preedit_str_)], end_src, BUF_SIZE - 1);
199
// update within the ui provider
200
update_preedit_ui(ppd, preedit_str_);
207
WindowHandler::updateCandidates(const ICandidateList* pcl)
210
for (int i = 0, sz = pcl->size(); i < sz; i++) {
211
const TWCHAR* pcand = pcl->candiString(i);
212
if (pcand == NULL) break;
213
cand_str += (i == 9) ? '0' : TWCHAR('1' + i);
214
cand_str += TWCHAR('.');
216
cand_str += TWCHAR(' ');
219
TIConvSrcPtr src = (TIConvSrcPtr)(cand_str.c_str());
220
WCSTOMBS(candidate_str_, (const TWCHAR*) src, BUF_SIZE - 1);
222
// update within the ui provider
223
update_candidates_ui(pcl, candidate_str_);
227
WindowHandler::updateStatus(int key, int value)
231
WindowHandler::commit(const TWCHAR* str)
233
char* buf = new char[BUF_SIZE];
234
memset(buf, 0, BUF_SIZE);
235
WCSTOMBS(buf, str, BUF_SIZE - 1);
236
if (handle_ != NULL) {
237
xim_commit_preedit(handle_, buf);
243
static PreeditUI* ui_impl = NULL;
244
static WindowHandler* instance = NULL;
245
static CIMIView* view = NULL;
250
CSunpinyinSessionFactory& fac = CSunpinyinSessionFactory::getFactory();
251
if (settings_get_int(SHUANGPIN)) {
252
fac.setPinyinScheme(CSunpinyinSessionFactory::SHUANGPIN);
255
settings_get(SHUANGPIN_SCHEME, scheme);
256
if (strcmp(scheme, "MS2003") == 0) {
257
AShuangpinSchemePolicy::instance().setShuangpinType(MS2003);
258
} else if (strcmp(scheme, "ABC") == 0) {
259
AShuangpinSchemePolicy::instance().setShuangpinType(ABC);
260
} else if (strcmp(scheme, "ZiRanMa") == 0) {
261
AShuangpinSchemePolicy::instance().setShuangpinType(ZIRANMA);
262
} else if (strcmp(scheme, "PinYin++") == 0) {
263
AShuangpinSchemePolicy::instance().setShuangpinType(PINYINJIAJIA);
264
} else if (strcmp(scheme, "ZiGuang") == 0) {
265
AShuangpinSchemePolicy::instance().setShuangpinType(ZIGUANG);
266
} else if (strcmp(scheme, "XiaoHe") == 0) {
267
AShuangpinSchemePolicy::instance().setShuangpinType(XIAOHE);
270
fac.setPinyinScheme(CSunpinyinSessionFactory::QUANPIN);
272
view = fac.createSession();
275
settings_get(SKIN_NAME, skin_name);
276
ui_impl = create_preedit_ui(skin_name);
278
instance = new WindowHandler();
279
instance->set_preedit_ui_impl(ui_impl);
280
view->getIC()->setCharsetLevel(1);// GBK
281
view->attachWinHandler(instance);
285
preedit_finalize(void)
287
LOG("preedit_finalizing...");
288
CSunpinyinSessionFactory& fac = CSunpinyinSessionFactory::getFactory();
289
fac.destroySession(view);
298
// number of candidates
299
view->setCandiWindowSize(settings_get_int(CANDIDATES_SIZE));
302
CHotkeyProfile* prof = view->getHotkeyProfile();
304
if (settings_get_int(PAGE_MINUS_PLUS)) {
305
prof->addPageUpKey(CKeyEvent(IM_VK_MINUS));
306
prof->addPageDownKey(CKeyEvent(IM_VK_EQUALS));
308
if (settings_get_int(PAGE_COMMA_PERIOD)) {
309
prof->addPageUpKey(CKeyEvent(IM_VK_COMMA));
310
prof->addPageDownKey(CKeyEvent(IM_VK_PERIOD));
312
if (settings_get_int(PAGE_PAREN)) {
313
prof->addPageUpKey(CKeyEvent('['));
314
prof->addPageDownKey(CKeyEvent(']'));
317
// fuzzy segmentation
318
bool enable_fuzzy = settings_get_int(FUZZY_SEGMENTATION);
319
bool enable_inner = settings_get_int(FUZZY_INNER_SEGMENTATION);
320
AQuanpinSchemePolicy::instance().setFuzzySegmentation(enable_fuzzy);
321
AQuanpinSchemePolicy::instance().setInnerFuzzySegmentation(enable_inner);
323
// cancel last selection on backspace
324
view->setCancelOnBackspace(settings_get_int(CANCEL_ON_BACKSPACE));
326
// do we need to change the skin?
328
settings_get(SKIN_NAME, skin_name);
329
if (ui_impl->name() != skin_name) {
331
ui_impl = create_preedit_ui(skin_name);
332
instance->set_preedit_ui_impl(ui_impl);
335
instance->reload_ui();
339
preedit_set_handle(XIMHandle* handle)
341
instance->set_xim_handle(handle);
345
preedit_move(int x, int y)
347
instance->move(x, y);
363
preedit_on_key(XIMHandle* handle, unsigned int keycode, unsigned int state)
365
if (keycode < 0x20 && keycode > 0x7E)
367
view->onKeyEvent(CKeyEvent(keycode, keycode, state));
373
return instance->status();
377
preedit_set_full(bool full)
379
view->setStatusAttrValue(CIMIWinHandler::STATUS_ID_FULLSYMBOL, full);
383
preedit_set_chinese_punc(bool chn_punc)
385
view->setStatusAttrValue(CIMIWinHandler::STATUS_ID_FULLPUNC, chn_punc);
389
preedit_omit_next_punct()
391
view->getIC()->omitNextPunct();