~ubuntu-branches/ubuntu/trusty/fcitx/trusty-proposed

« back to all changes in this revision

Viewing changes to src/module/punc/punc.c

  • Committer: Package Import Robot
  • Author(s): Aron Xu
  • Date: 2013-02-10 17:03:56 UTC
  • mfrom: (1.3.18) (33.1.3 experimental)
  • Revision ID: package-import@ubuntu.com-20130210170356-2yuv6xy3ed378kn0
Tags: 1:4.2.7-1
* New upstream release.
* New binary packages:
  - fcitx-libs-gclient: D-Bus client library for Glib
  - fcitx-libs-qt: D-Bus client library for Qt
  - fcitx-module-quickphrase-editor: Quick Phrase editor module

Show diffs side-by-side

added added

removed removed

Lines of Context:
37
37
#include "fcitx-config/xdg.h"
38
38
#include "fcitx-utils/log.h"
39
39
#include "fcitx-utils/utils.h"
 
40
#include "fcitx-utils/bitset.h"
40
41
 
41
42
/**
42
43
 * @file punc.c
49
50
 
50
51
struct _FcitxPuncState;
51
52
typedef struct _WidePunc {
52
 
    int             ASCII;
53
 
    char            strWidePunc[MAX_PUNC_NO][MAX_PUNC_LENGTH * UTF8_MAX_LENGTH + 1];
54
 
    unsigned        iCount: 2;
55
 
    unsigned        iWhich: 2;
 
53
    char ASCII;
 
54
    char strWidePunc[MAX_PUNC_NO][MAX_PUNC_LENGTH * UTF8_MAX_LENGTH + 1];
 
55
    unsigned iCount: 2;
56
56
} WidePunc;
57
57
 
 
58
typedef struct _PuncWhich {
 
59
    FcitxBitSet* bitset;
 
60
    WidePunc* lastPunc;
 
61
} PuncWhich;
 
62
 
58
63
typedef struct _FcitxPunc {
59
64
    char* langCode;
60
65
    WidePunc* curPunc;
69
74
static void* PuncCreate(FcitxInstance* instance);
70
75
static boolean PuncPreFilter(void* arg, FcitxKeySym sym, unsigned int state, INPUT_RETURN_VALUE* retVal);
71
76
static boolean ProcessPunc(void* arg, FcitxKeySym sym, unsigned int state, INPUT_RETURN_VALUE* retVal);
72
 
static void* PuncGetPunc(void* a, FcitxModuleFunctionArg arg);
73
 
static void* PuncGetPunc2(void* a, FcitxModuleFunctionArg arg);
74
77
static void TogglePuncState(void *arg);
75
78
static boolean GetPuncState(void *arg);
76
79
static void ReloadPunc(void *arg);
80
83
static boolean IsHotKeyPunc(FcitxKeySym sym, unsigned int state);
81
84
static void PuncLanguageChanged(void* arg, const void* value);
82
85
 
 
86
static void* PuncWhichAlloc(void* arg);
 
87
static void* PuncWhichCopy(void* arg, void* data, void* src);
 
88
static void PuncWhichFree(void* arg, void* data);
 
89
 
 
90
DECLARE_ADDFUNCTIONS(Punc)
 
91
 
83
92
typedef struct _FcitxPuncState {
84
93
    char cLastIsAutoConvert;
85
94
    boolean bLastIsNumber;
86
95
    FcitxInstance* owner;
87
96
    FcitxPunc* puncSet;
88
97
    WidePunc* curPunc;
 
98
    int slot;
89
99
} FcitxPuncState;
90
100
 
91
 
FCITX_EXPORT_API
92
 
FcitxModule module = {
 
101
FCITX_DEFINE_PLUGIN(fcitx_punc, module, FcitxModule) = {
93
102
    PuncCreate,
94
103
    NULL,
95
104
    NULL,
97
106
    ReloadPunc
98
107
};
99
108
 
100
 
FCITX_EXPORT_API
101
 
int ABI_VERSION = FCITX_ABI_VERSION;
102
 
 
103
109
void* PuncCreate(FcitxInstance* instance)
104
110
{
105
111
    FcitxPuncState* puncState = fcitx_utils_malloc0(sizeof(FcitxPuncState));
106
 
    FcitxAddon* puncaddon = FcitxAddonsGetAddonByName(FcitxInstanceGetAddons(instance), FCITX_PUNC_NAME);
107
112
    puncState->owner = instance;
108
113
    LoadPuncDict(puncState);
109
114
    FcitxKeyFilterHook hk;
134
139
 
135
140
    FcitxInstanceRegisterInputUnFocusHook(instance, hook);
136
141
 
137
 
    FcitxInstanceWatchContext(instance, CONTEXT_IM_LANGUAGE, PuncLanguageChanged, puncState);
 
142
    FcitxInstanceWatchContext(instance, CONTEXT_IM_LANGUAGE,
 
143
                              PuncLanguageChanged, puncState);
138
144
 
139
145
    FcitxProfile* profile = FcitxInstanceGetProfile(instance);
140
146
    FcitxUIRegisterStatus(instance, puncState, "punc",
141
 
                          profile->bUseWidePunc ? _("Full width punct") :  _("Latin punct"),
142
 
                          _("Toggle Full Width Punctuation"), TogglePuncState, GetPuncState);
143
 
 
144
 
    AddFunction(puncaddon, PuncGetPunc);
145
 
    AddFunction(puncaddon, PuncGetPunc2);
 
147
                          profile->bUseWidePunc ? _("Full width punct") :
 
148
                          _("Latin punct"),
 
149
                          _("Toggle Full Width Punctuation"), TogglePuncState,
 
150
                          GetPuncState);
 
151
 
 
152
    puncState->slot = FcitxInstanceAllocDataForIC(instance, PuncWhichAlloc,
 
153
                                                  PuncWhichCopy, PuncWhichFree,
 
154
                                                  puncState);
 
155
 
 
156
    FcitxPuncAddFunctions(instance);
146
157
    return puncState;
147
158
}
148
159
 
 
160
void* PuncWhichAlloc(void *arg)
 
161
{
 
162
    FcitxPunc *puncState = arg;
 
163
    PuncWhich *which = fcitx_utils_new(PuncWhich);
 
164
    which->lastPunc = puncState->curPunc;
 
165
    which->bitset = fcitx_bitset_new(256);
 
166
    return which;
 
167
}
 
168
 
 
169
void* PuncWhichCopy(void* arg, void* data, void* src)
 
170
{
 
171
    FCITX_UNUSED(arg);
 
172
    PuncWhich *which = data;
 
173
    PuncWhich *whichsrc = src;
 
174
    which->lastPunc = whichsrc->lastPunc;
 
175
    memcpy(which->bitset, whichsrc->bitset, fcitx_bitset_size(256));
 
176
    return data;
 
177
}
 
178
 
 
179
void PuncWhichFree(void* arg, void* data)
 
180
{
 
181
    FCITX_UNUSED(arg);
 
182
    PuncWhich *which = data;
 
183
    free(which->bitset);
 
184
    free(data);
 
185
}
 
186
 
149
187
void PuncLanguageChanged(void* arg, const void* value)
150
188
{
151
189
    FcitxPuncState* puncState = (FcitxPuncState*) arg;
163
201
    FcitxUISetStatusVisable (puncState->owner, "punc",  puncState->curPunc != NULL) ;
164
202
}
165
203
 
166
 
void* PuncGetPunc(void* a, FcitxModuleFunctionArg arg)
167
 
{
168
 
    FcitxPuncState* puncState = (FcitxPuncState*) a;
169
 
    int *key = arg.args[0];
170
 
    return GetPunc(puncState, *key);
171
 
}
172
 
 
173
 
 
174
 
void* PuncGetPunc2(void* a, FcitxModuleFunctionArg arg)
175
 
{
176
 
    FcitxPuncState* puncState = (FcitxPuncState*) a;
177
 
    int *key = arg.args[0];
178
 
    char** p1 = arg.args[1];
179
 
    char** p2 = arg.args[2];
180
 
    int             iIndex = 0;
181
 
    WidePunc       *curPunc = puncState->curPunc;
 
204
static void
 
205
PuncGetPunc2(FcitxPuncState *puncState, int key, char **p1, char **p2)
 
206
{
 
207
    int iIndex = 0;
 
208
    WidePunc *curPunc = puncState->curPunc;
182
209
 
183
210
    if (!curPunc)
184
 
        return NULL;
 
211
        return;
185
212
 
186
213
    while (curPunc[iIndex].ASCII) {
187
 
        if (curPunc[iIndex].ASCII == *key) {
 
214
        if (curPunc[iIndex].ASCII == key) {
188
215
            if (p1)
189
216
                *p1 = curPunc[iIndex].strWidePunc[0];
190
217
            if (curPunc[iIndex].iCount > 1 && p2)
193
220
        }
194
221
        iIndex++;
195
222
    }
196
 
 
197
 
    return NULL;
198
223
}
199
224
 
200
225
void ResetPunc(void* arg)
212
237
    if (!curPunc)
213
238
        return;
214
239
 
215
 
    int iIndex = 0;
216
 
 
217
 
    while (curPunc[iIndex].ASCII) {
218
 
        curPunc[iIndex].iWhich = 0;
219
 
        iIndex++;
220
 
    }
 
240
    FcitxInputContext* ic = FcitxInstanceGetCurrentIC(puncState->owner);
 
241
    if (!ic)
 
242
        return;
 
243
    PuncWhich* puncWhich = FcitxInstanceGetICData(puncState->owner, ic, puncState->slot);
 
244
    fcitx_bitset_clear(puncWhich->bitset);
221
245
}
222
246
 
223
 
boolean PuncPreFilter(void* arg, FcitxKeySym sym, unsigned int state, INPUT_RETURN_VALUE* retVal)
 
247
boolean PuncPreFilter(void* arg, FcitxKeySym sym, unsigned int state,
 
248
                      INPUT_RETURN_VALUE* retVal)
224
249
{
225
 
    if (!FcitxHotkeyIsHotKeySimple(sym, state))
226
 
        return false;
227
 
 
228
 
    FcitxPuncState* puncState = (FcitxPuncState*) arg;
229
 
    if (!FcitxHotkeyIsHotKeyDigit(sym, state) && !IsHotKeyPunc(sym, state))
 
250
    FCITX_UNUSED(retVal);
 
251
    FcitxPuncState *puncState = (FcitxPuncState*)arg;
 
252
    if (FcitxHotkeyIsHotKeySimple(sym, state) &&
 
253
        !FcitxHotkeyIsHotKeyDigit(sym, state) && !IsHotKeyPunc(sym, state))
230
254
        puncState->bLastIsNumber = false;
231
 
 
232
255
    return false;
233
256
}
234
257
 
245
268
    if (*retVal != IRV_TO_PROCESS)
246
269
        return false;
247
270
 
 
271
    FcitxCandidateWordList *candList = FcitxInputStateGetCandidateList(input);
 
272
    if (FcitxCandidateWordGetListSize(candList) != 0) {
 
273
        if (FcitxCandidateWordGetHasGoneToNextPage(candList) &&
 
274
            FcitxHotkeyIsHotKey(sym, state,
 
275
                                FcitxConfigPrevPageKey(instance, config))) {
 
276
            return false;
 
277
        }
 
278
        /*
 
279
         * comparing with upper case, if paging is occupied,
 
280
         * punc will not let next page pass
 
281
         */
 
282
        if (FcitxHotkeyIsHotKey(sym, state,
 
283
                                FcitxConfigNextPageKey(instance, config))) {
 
284
            return false;
 
285
        }
 
286
    }
 
287
 
248
288
    FcitxKeySym origsym = sym;
249
289
    sym = FcitxHotkeyPadToMain(sym);
250
290
    if (profile->bUseWidePunc) {
251
 
 
252
291
        if (puncState->bLastIsNumber && config->bEngPuncAfterNumber
253
292
                && (FcitxHotkeyIsHotKey(origsym, state, FCITX_PERIOD)
254
293
                    || FcitxHotkeyIsHotKey(origsym, state, FCITX_SEMICOLON)
269
308
        FcitxInputStateGetOutputString(input)[0] = '\0';
270
309
        INPUT_RETURN_VALUE ret = IRV_TO_PROCESS;
271
310
        if (!FcitxInputStateGetIsInRemind(input))
272
 
            ret = FcitxCandidateWordChooseByIndex(FcitxInputStateGetCandidateList(input), 0);
 
311
            ret = FcitxCandidateWordChooseByTotalIndex(FcitxInputStateGetCandidateList(input), 0);
273
312
 
274
313
        /* if there is nothing to commit */
275
314
        if (ret == IRV_TO_PROCESS) {
309
348
            puncState->cLastIsAutoConvert = 0;
310
349
            *retVal = IRV_DO_NOTHING;
311
350
            return true;
312
 
        } else if (FcitxHotkeyIsHotKeySimple(sym, state)) {
313
 
            if (FcitxHotkeyIsHotKeyDigit(sym, state))
314
 
                puncState->bLastIsNumber = true;
315
 
            else {
316
 
                puncState->bLastIsNumber = false;
317
 
            }
 
351
        } else if (FcitxHotkeyIsHotKeyDigit(sym, state)) {
 
352
            puncState->bLastIsNumber = true;
 
353
        } else {
 
354
            puncState->bLastIsNumber = false;
318
355
        }
319
356
    }
320
357
    puncState->cLastIsAutoConvert = 0;
395
432
                pstr++;
396
433
 
397
434
            punc[iRecordNo].iCount = 0;      // 该符号有几个转化,比如英文"就可以转换成“和”
398
 
            punc[iRecordNo].iWhich = 0;      // 标示该符号的输入状态,即处于第几个转换。如",iWhich标示是转换成“还是”
399
435
            // 依次将该ASCII码所对应的符号放入到结构中
400
436
            while (*pstr) {
401
437
                i = 0;
447
483
    }
448
484
}
449
485
 
 
486
static inline int GetPuncWhich(FcitxPuncState* puncState, WidePunc* punc)
 
487
{
 
488
    FcitxInputContext* ic = FcitxInstanceGetCurrentIC(puncState->owner);
 
489
    if (!ic)
 
490
        return 0;
 
491
    PuncWhich* puncWhich = FcitxInstanceGetICData(puncState->owner, ic, puncState->slot);
 
492
    if (puncWhich->lastPunc != puncState->curPunc) {
 
493
        fcitx_bitset_clear(puncWhich->bitset);
 
494
        puncWhich->lastPunc = puncState->curPunc;
 
495
    }
 
496
    int result = fcitx_bitset_isset(puncWhich->bitset, punc->ASCII) ? 1 : 0;
 
497
    if (result >= punc->iCount)
 
498
        result = 0;
 
499
    return result;
 
500
}
 
501
 
 
502
static inline void SetPuncWhich(FcitxPuncState* puncState, WidePunc* punc)
 
503
{
 
504
    FcitxInputContext* ic = FcitxInstanceGetCurrentIC(puncState->owner);
 
505
    if (!ic)
 
506
        return;
 
507
    PuncWhich* puncWhich = FcitxInstanceGetICData(puncState->owner, ic, puncState->slot);
 
508
    FcitxBitSet* bitset = puncWhich->bitset;
 
509
    if (punc->iCount == 1)
 
510
        fcitx_bitset_unset(bitset, punc->ASCII);
 
511
    else {
 
512
        if (fcitx_bitset_isset(bitset, punc->ASCII))
 
513
            fcitx_bitset_unset(bitset, punc->ASCII);
 
514
        else
 
515
            fcitx_bitset_set(bitset, punc->ASCII);
 
516
    }
 
517
}
 
518
 
450
519
/*
451
520
 * 根据字符得到相应的标点符号
452
521
 * 如果该字符不在标点符号集中,则返回NULL
453
522
 */
454
 
char           *GetPunc(FcitxPuncState* puncState, int iKey)
 
523
static char*
 
524
GetPunc(FcitxPuncState *puncState, int iKey)
455
525
{
456
 
    int             iIndex = 0;
457
 
    char           *pPunc;
458
 
    WidePunc       *curPunc = puncState->curPunc;
 
526
    int iIndex = 0;
 
527
    char *pPunc;
 
528
    WidePunc *curPunc = puncState->curPunc;
459
529
 
460
530
    if (!curPunc)
461
 
        return (char *) NULL;
 
531
        return NULL;
462
532
 
463
533
    while (curPunc[iIndex].ASCII) {
464
534
        if (curPunc[iIndex].ASCII == iKey) {
465
 
            pPunc = curPunc[iIndex].strWidePunc[curPunc[iIndex].iWhich];
466
 
            curPunc[iIndex].iWhich++;
467
 
            if (curPunc[iIndex].iWhich >= curPunc[iIndex].iCount)
468
 
                curPunc[iIndex].iWhich = 0;
 
535
            pPunc = curPunc[iIndex].strWidePunc[GetPuncWhich(puncState,
 
536
                                                             &curPunc[iIndex])];
 
537
            SetPuncWhich(puncState, &curPunc[iIndex]);
469
538
            return pPunc;
470
539
        }
471
540
        iIndex++;
472
541
    }
473
542
 
474
 
    return (char *) NULL;
 
543
    return NULL;
475
544
}
476
545
 
477
546
void TogglePuncState(void* arg)
482
551
    profile->bUseWidePunc = !profile->bUseWidePunc;
483
552
 
484
553
    FcitxUISetStatusString(puncState->owner, "punc",
485
 
                           profile->bUseWidePunc ? _("Full width punct") :  _("Latin punct"),
486
 
                          _("Toggle Full Width Punctuation"));
 
554
                           profile->bUseWidePunc ? _("Full width punct") :
 
555
                           _("Latin punct"),
 
556
                           _("Toggle Full Width Punctuation"));
487
557
    FcitxProfileSave(profile);
488
558
}
489
559
 
528
598
 
529
599
    return false;
530
600
}
531
 
 
532
 
 
533
 
// kate: indent-mode cstyle; space-indent on; indent-width 0;
 
601
#include "fcitx-punc-addfunctions.h"