1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 * 4 * Copyright (c) 2007 Sun Microsystems, Inc. All Rights Reserved. 5 * 6 * The contents of this file are subject to the terms of either the GNU Lesser 7 * General Public License Version 2.1 only ("LGPL") or the Common Development and 8 * Distribution License ("CDDL")(collectively, the "License"). You may not use this 9 * file except in compliance with the License. You can obtain a copy of the CDDL at 10 * http://www.opensource.org/licenses/cddl1.php and a copy of the LGPLv2.1 at 11 * http://www.opensource.org/licenses/lgpl-license.php. See the License for the 12 * specific language governing permissions and limitations under the License. When 13 * distributing the software, include this License Header Notice in each file and 14 * include the full text of the License in the License file as well as the 15 * following notice: 16 * 17 * NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND DISTRIBUTION LICENSE 18 * (CDDL) 19 * For Covered Software in this distribution, this License shall be governed by the 20 * laws of the State of California (excluding conflict-of-law provisions). 21 * Any litigation relating to this License shall be subject to the jurisdiction of 22 * the Federal Courts of the Northern District of California and the state courts 23 * of the State of California, with venue lying in Santa Clara County, California. 24 * 25 * Contributor(s): 26 * 27 * If you wish your version of this file to be governed by only the CDDL or only 28 * the LGPL Version 2.1, indicate your decision by adding "[Contributor]" elects to 29 * include this software in this distribution under the [CDDL or LGPL Version 2.1] 30 * license." If you don't indicate a single choice of license, a recipient has the 31 * option to distribute your version of this file under either the CDDL or the LGPL 32 * Version 2.1, or to extend the choice of license to its licensees as provided 33 * above. However, if you add LGPL Version 2.1 code and therefore, elected the LGPL 34 * Version 2 license, then the option applies only if the new code is made subject 35 * to such option by the copyright holder. 36 */ 37 38 #ifndef _IMI_OPTIONS_H 39 #define _IMI_OPTIONS_H 40 41 #include "utils.h" 42 #include "portability.h" 43 #include "imi_view.h" 44 #include "imi_view_classic.h" 45 #include "imi_funcobjs.h" 46 #include "imi_data.h" 47 #include "imi_option_event.h" 48 #include "userdict.h" 49 #include "ic_history.h" 50 #include "shuangpin_seg.h" 51 52 #ifndef SUNPINYIN_USERDATA_DIR_PREFIX 53 #define SUNPINYIN_USERDATA_DIR_PREFIX ".sunpinyin" 54 #endif 55 56 /** 57 * helper function to transform string vector to array of char* 58 */ 59 class CPairParser 60 { 61 public: 62 CPairParser() 63 : m_free(m_buf), m_end(m_buf+256) 64 {} 65 66 /** 67 * transform a string vector to interleaved <key,value> array of (char*) 68 * @param event a list of string, each element should be in the form of "key:value". 69 * @returns the number of pairs transformed 70 * @note this function uses a local buffer for the returned array 71 */ 72 size_t parse(const std::vector<std::string> pairs); 73 size_t parse(const COptionEvent& event); 74 const char* const* get_pairs() const; 75 76 private: 77 char* strdup(const std::string& s); 78 char* alloc(size_t size); 79 80 char* m_pairs[32]; 81 char m_buf[256]; 82 char* m_free; 83 const char* m_end; 84 }; 85 86 struct CSimplifiedChinesePolicy : public IConfigurable 87 { 88 CSimplifiedChinesePolicy (); 89 90 bool loadResources (); 91 92 CIMIContext* createContext (); 93 void destroyContext (CIMIContext *context); 94 95 /** 96 * set a customizable punctuation mapping 97 * @param punc_map an interleaved array of <key,value> pairs, which looks 98 * like ["key_1", "val_1", "key_2", "val_2", ...], 99 * where ispunct(key_n). system defined mapping for a 100 * given punct will be overriden by user specified one. 101 */ 102 void setPunctMapping (const char *const* map) 103 {m_getFullPunctOp.initPunctMap (map);} 104 105 void enableFullSymbol (bool v=true) {m_bEnableFullSymbol = v;} 106 void enableFullPunct (bool v=true) {m_bEnableFullPunct = v;} 107 108 void setDataDir (const std::string& data_dir) 109 {m_data_dir = data_dir;} 110 111 virtual bool onConfigChanged (const COptionEvent& event); 112 113 template<class> friend class SingletonHolder; 114 115 protected: 116 ~CSimplifiedChinesePolicy () {} 117 118 bool createDirectory (char *path); 119 bool saveUserHistory (); 120 121 CIMIData m_coreData; 122 CBigramHistory m_historyCache; 123 CUserDict m_userDict; 124 bool m_bLoaded; 125 bool m_bTried; 126 unsigned m_csLevel; 127 bool m_bEnableFullSymbol; 128 CGetFullSymbolOp m_getFullSymbolOp; 129 bool m_bEnableFullPunct; 130 CGetFullPunctOp m_getFullPunctOp; 131 std::string m_data_dir; 132 }; 133 134 typedef SingletonHolder<CSimplifiedChinesePolicy> ASimplifiedChinesePolicy; 135 136 struct CQuanpinSchemePolicy : IConfigurable 137 { 138 public: 139 140 IPySegmentor* createPySegmentor () 141 { 142 CQuanpinSegmentor *pseg = new CQuanpinSegmentor (); 143 pseg->setGetFuzzySyllablesOp (&m_getFuzzySyllablesOp); 144 pseg->setGetCorrectionPairOp (&m_getCorrectionPairOp); 145 return pseg; 146 } 147 148 void setFuzzyForwarding (bool v=true) 149 {m_getFuzzySyllablesOp.setEnable (v);} 150 151 enum { 152 MAX_FUZZY_PINYINS = 32, 153 MAX_AUTOCORRECTION_PINYINS = 32 154 }; 155 156 void setFuzzyPinyinPairs (const char* const* pairs, unsigned num) 157 {m_getFuzzySyllablesOp.initFuzzyMap (pairs, num);} 158 159 void setAutoCorrecting (bool v=true) 160 {m_getCorrectionPairOp.setEnable (v);} 161 162 void setAutoCorrectionPairs (const char* const* pairs, unsigned num) 163 {m_getCorrectionPairOp.setCorrectionPairs (pairs, num);} 164 165 virtual bool onConfigChanged(const COptionEvent& event); 166 167 template<class> friend class SingletonHolder; 168 169 protected: 170 ~CQuanpinSchemePolicy () {} 171 172 CGetFuzzySyllablesOp m_getFuzzySyllablesOp; 173 CGetCorrectionPairOp m_getCorrectionPairOp; 174 }; 175 176 typedef SingletonHolder<CQuanpinSchemePolicy> AQuanpinSchemePolicy; 177 178 struct CShuangpinSchemePolicy : public IConfigurable 179 { 180 public: 181 CShuangpinSchemePolicy(); 182 183 IPySegmentor* createPySegmentor () 184 { 185 CShuangpinSegmentor *pseg = new CShuangpinSegmentor (m_shuangpinType); 186 return pseg; 187 } 188 189 void setShuangpinType (EShuangpinType t) {m_shuangpinType = t;} 190 virtual bool onConfigChanged(const COptionEvent& event); 191 192 template<class> friend class SingletonHolder; 193 protected: 194 ~CShuangpinSchemePolicy () {} 195 EShuangpinType m_shuangpinType; 196 }; 197 198 typedef SingletonHolder<CShuangpinSchemePolicy> AShuangpinSchemePolicy; 199 200 struct CClassicStylePolicy : public IConfigurable 201 { 202 CIMIView* createView () {return new CIMIClassicView ();} 203 204 template<class> friend class SingletonHolder; 205 protected: 206 ~CClassicStylePolicy () {} 207 }; 208 209 typedef SingletonHolder<CClassicStylePolicy> AClassicStylePolicy; 210 211 struct ISunpinyinProfile 212 { 213 virtual CIMIView* createProfile () = 0; 214 virtual void destroyProfile (CIMIView *) = 0; 215 virtual ~ISunpinyinProfile () {}; 216 }; 217 218 template <class LanguagePolicy, class PinyinSchemePolicy, class InputStylePolicy> 219 class CSunpinyinProfile : public ISunpinyinProfile 220 { 221 public: 222 CSunpinyinProfile () : m_langPolicy(LanguagePolicy::instance()), 223 m_pySchemePolicy(PinyinSchemePolicy::instance()), 224 m_inputStylePolicy(InputStylePolicy::instance()) 225 {} 226 227 /* profile by itself is a profile, so we are creating a session here? */ 228 virtual CIMIView* createProfile () 229 { 230 if (!m_langPolicy.loadResources ()) 231 return NULL; 232 233 IPySegmentor* pseg = m_pySchemePolicy.createPySegmentor (); 234 if (pseg == NULL) 235 return NULL; 236 237 CIMIContext *pic = m_langPolicy.createContext (); 238 CIMIView* pview = m_inputStylePolicy.createView (); 239 pview->attachIC (pic); 240 pview->setPySegmentor (pseg); 241 242 return pview; 243 } 244 245 virtual void destroyProfile(CIMIView* pview) 246 { 247 if (pview) { 248 LanguagePolicy::instance().destroyContext(pview->getIC()); 249 delete pview->getPySegmentor(); 250 delete pview; 251 } 252 } 253 private: 254 typename LanguagePolicy::Type& m_langPolicy; 255 typename PinyinSchemePolicy::Type& m_pySchemePolicy; 256 typename InputStylePolicy::Type& m_inputStylePolicy; 257 }; 258 259 class CSunpinyinSessionFactory : private CNonCopyable 260 { 261 public: 262 typedef enum { 263 QUANPIN, 264 SHUANGPIN, 265 YUEPIN, 266 ZHUYIN, 267 } EPyScheme; 268 269 typedef enum { 270 MSPY_STYLE, 271 CLASSIC_STYLE, 272 } EInputStyle; 273 274 typedef enum { 275 SIMPLIFIED_CHINESE, 276 TRADITIONAL_CHINESE, 277 } ELanguage; 278 279 public: 280 static CSunpinyinSessionFactory& getFactory () 281 { 282 static CSunpinyinSessionFactory inst; 283 return inst; 284 } 285 286 void setLanguage (ELanguage lang) {m_lang = lang;} 287 void setInputStyle (EInputStyle inputStyle) {m_inputStyle = inputStyle;} 288 void setPinyinScheme (EPyScheme pyScheme) {m_pyScheme = pyScheme;} 289 void setCandiWindowSize (unsigned size) {m_candiWindowSize = size;} 290 291 CIMIView* createSession () 292 { 293 unsigned key = _policiesToKey (m_lang, m_pyScheme, m_inputStyle); 294 ISunpinyinProfile *profile = _getProfile(key); 295 if (!profile) 296 return NULL; 297 298 CIMIView *pview = profile->createProfile (); 299 if (!pview) 300 return NULL; 301 302 pview->setHotkeyProfile (&m_hotkeyProfile); 303 pview->setCandiWindowSize (m_candiWindowSize); 304 return pview; 305 } 306 307 void destroySession (CIMIView* pview) 308 { 309 unsigned key = _policiesToKey (m_lang, m_pyScheme, m_inputStyle); 310 ISunpinyinProfile *profile = _getProfile(key); 311 if (!profile) 312 return; 313 profile->destroyProfile(pview); 314 } 315 316 private: 317 CSunpinyinSessionFactory () 318 : m_pyScheme (QUANPIN), m_inputStyle(CLASSIC_STYLE), m_lang(SIMPLIFIED_CHINESE), 319 m_candiWindowSize(10) 320 { 321 m_profiles [_policiesToKey (SIMPLIFIED_CHINESE, QUANPIN, CLASSIC_STYLE)] = 322 new CSunpinyinProfile <ASimplifiedChinesePolicy, AQuanpinSchemePolicy, AClassicStylePolicy> (); 323 324 m_profiles [_policiesToKey (SIMPLIFIED_CHINESE, SHUANGPIN, CLASSIC_STYLE)] = 325 new CSunpinyinProfile <ASimplifiedChinesePolicy, AShuangpinSchemePolicy, AClassicStylePolicy> (); 326 } 327 328 ~CSunpinyinSessionFactory () 329 { 330 std::map <unsigned, ISunpinyinProfile*>::iterator it = m_profiles.begin (); 331 std::map <unsigned, ISunpinyinProfile*>::iterator ite = m_profiles.end (); 332 333 for (; it != ite; ++it) 334 delete it->second; 335 } 336 337 ISunpinyinProfile* _getProfile(unsigned key) 338 { 339 std::map <unsigned, ISunpinyinProfile*>::iterator it = m_profiles.find (key); 340 if (it != m_profiles.end()) { 341 return it->second; 342 } else { 343 return NULL; 344 } 345 } 346 347 unsigned _policiesToKey (ELanguage lang, EPyScheme pyScheme, EInputStyle inputStyle) 348 {return (lang<<16) + (pyScheme<<8) + inputStyle;} 349 350 std::map <unsigned, ISunpinyinProfile*> m_profiles; 351 352 EPyScheme m_pyScheme; 353 EInputStyle m_inputStyle; 354 ELanguage m_lang; 355 unsigned m_candiWindowSize; 356 CHotkeyProfile m_hotkeyProfile; 357 }; 358 359 #endif 360
