1 // Copyright 2010-2018, Google Inc. 2 // All rights reserved. 3 // 4 // Redistribution and use in source and binary forms, with or without 5 // modification, are permitted provided that the following conditions are 6 // met: 7 // 8 // * Redistributions of source code must retain the above copyright 9 // notice, this list of conditions and the following disclaimer. 10 // * Redistributions in binary form must reproduce the above 11 // copyright notice, this list of conditions and the following disclaimer 12 // in the documentation and/or other materials provided with the 13 // distribution. 14 // * Neither the name of Google Inc. nor the names of its 15 // contributors may be used to endorse or promote products derived from 16 // this software without specific prior written permission. 17 // 18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 30 // Session class of Mozc server. 31 32 #ifndef MOZC_SESSION_SESSION_H_ 33 #define MOZC_SESSION_SESSION_H_ 34 35 #include <memory> 36 #include <string> 37 38 #include "base/port.h" 39 #include "composer/composer.h" 40 #include "session/session_interface.h" 41 // for FRIEND_TEST() 42 #include "testing/base/public/gunit_prod.h" 43 #include "transliteration/transliteration.h" 44 45 namespace mozc { 46 namespace commands { 47 class ApplicationInfo; 48 class Capability; 49 class Command; 50 class Input; 51 class KeyEvent; 52 } // namespace commands 53 54 namespace composer { 55 class Table; 56 } // namespace composer 57 58 class EngineInterface; 59 60 namespace session { 61 class ImeContext; 62 63 class Session : public SessionInterface { 64 public: 65 explicit Session(EngineInterface *engine); 66 virtual ~Session(); 67 68 virtual bool SendKey(mozc::commands::Command *command); 69 70 // Check if the input key event will be consumed by the session. 71 virtual bool TestSendKey(mozc::commands::Command *command); 72 73 // Perform the SEND_COMMAND command defined commands.proto. 74 virtual bool SendCommand(mozc::commands::Command *command); 75 76 // Turn on IME. Do nothing (but the keyevent is consumed) when IME is already 77 // turned on. 78 bool IMEOn(mozc::commands::Command *command); 79 80 // Turn off IME. Do nothing (but the keyevent is consumed) when IME is already 81 // turned off. 82 bool IMEOff(mozc::commands::Command *command); 83 84 // Unlike IMEOn/IMEOff, these commands 1) can update compositioin mode, and 85 // 2) are functional even when IME is already turned on/off. 86 // TODO(team): Merge these into IMEOn/Off once b/10250883 is fixed. 87 bool MakeSureIMEOn(mozc::commands::Command *command); 88 bool MakeSureIMEOff(mozc::commands::Command *command); 89 90 bool EchoBack(mozc::commands::Command *command); 91 bool EchoBackAndClearUndoContext(mozc::commands::Command *command); 92 bool DoNothing(mozc::commands::Command *command); 93 94 // Tries deleting the focused candidate from the user prediction history. If 95 // that candidate, as a key value pair, doesn't exist in the user history, 96 // nothing happens. Regardless of the result of internal history deletion, 97 // invoking this method has the same effect as ConvertCancel() from the 98 // viewpoint of session, meaning that the session state gets back to 99 // composition. 100 bool DeleteSelectedCandidateFromHistory(mozc::commands::Command *command); 101 102 // Resets the composer and clear conversion segments. 103 // History segments will not be cleared. 104 // Therefore if a user commits "風"(かぜ) and Revert method is called, 105 // preedit "ひいた" will be converted into "邪引いた". 106 bool Revert(mozc::commands::Command *command); 107 // Reset the composer and clear all the segments (including history segments). 108 // Therefore preedit "ひいた" will *not* be converted into "邪引いた" 109 // on the situation described above. 110 bool ResetContext(mozc::commands::Command *command); 111 112 // Returns the current status such as a composition string, input mode, etc. 113 bool GetStatus(mozc::commands::Command *command); 114 115 // Fills Output::Callback with the CONVERT_REVERSE SessionCommand to 116 // ask the client to send back the SessionCommand to the server. 117 // This function is called when the key event representing the 118 // ConvertReverse keybinding is called. 119 bool RequestConvertReverse(mozc::commands::Command *command); 120 121 // Begins reverse conversion for the given session. This function 122 // is called when the CONVERT_REVERSE SessionCommand is called. 123 bool ConvertReverse(mozc::commands::Command *command); 124 125 // Fills Output::Callback with the Undo SessionCommand to ask the 126 // client to send back the SessionCommand to the server. 127 // This function is called when the key event representing the 128 // Undo keybinding is called. 129 bool RequestUndo(mozc::commands::Command *command); 130 131 // Undos the commitment. This function is called when the 132 // UNDO SessionCommand is called. 133 bool Undo(mozc::commands::Command *command); 134 135 bool InsertSpace(mozc::commands::Command *command); 136 bool InsertSpaceToggled(mozc::commands::Command *command); 137 bool InsertSpaceHalfWidth(mozc::commands::Command *command); 138 bool InsertSpaceFullWidth(mozc::commands::Command *command); 139 bool InsertCharacter(mozc::commands::Command *command); 140 bool Delete(mozc::commands::Command *command); 141 bool Backspace(mozc::commands::Command *command); 142 bool EditCancel(mozc::commands::Command *command); 143 bool EditCancelAndIMEOff(mozc::commands::Command *command); 144 145 bool MoveCursorRight(mozc::commands::Command *command); 146 bool MoveCursorLeft(mozc::commands::Command *command); 147 bool MoveCursorToEnd(mozc::commands::Command *command); 148 bool MoveCursorToBeginning(mozc::commands::Command *command); 149 bool MoveCursorTo(mozc::commands::Command *command); 150 bool Convert(mozc::commands::Command *command); 151 // Starts conversion not using user history. This is used for debugging. 152 bool ConvertWithoutHistory(mozc::commands::Command *command); 153 bool ConvertNext(mozc::commands::Command *command); 154 bool ConvertPrev(mozc::commands::Command *command); 155 // Shows the next page of candidates. 156 bool ConvertNextPage(mozc::commands::Command *command); 157 // Shows the previous page of candidates. 158 bool ConvertPrevPage(mozc::commands::Command *command); 159 bool ConvertCancel(mozc::commands::Command *command); 160 bool PredictAndConvert(mozc::commands::Command *command); 161 // Note: Commit() also triggers zero query suggestion. 162 // TODO(team): Rename this method to CommitWithZeroQuerySuggest. 163 bool Commit(mozc::commands::Command *command); 164 bool CommitNotTriggeringZeroQuerySuggest(commands::Command *command); 165 bool CommitFirstSuggestion(mozc::commands::Command *command); 166 // Select a candidate located by input.command.id and commit. 167 bool CommitCandidate(mozc::commands::Command *command); 168 169 // Expands suggestion candidates. 170 bool ExpandSuggestion(mozc::commands::Command *command); 171 172 // Commits only the first segment. 173 bool CommitSegment(mozc::commands::Command *command); 174 // Commits some characters at the head of the preedit. 175 bool CommitHead(size_t count, mozc::commands::Command *command); 176 // Commits preedit if in password mode. 177 bool CommitIfPassword(mozc::commands::Command *command); 178 179 bool SegmentFocusRight(mozc::commands::Command *command); 180 bool SegmentFocusLeft(mozc::commands::Command *command); 181 bool SegmentFocusLast(mozc::commands::Command *command); 182 bool SegmentFocusLeftEdge(mozc::commands::Command *command); 183 bool SegmentWidthExpand(mozc::commands::Command *command); 184 bool SegmentWidthShrink(mozc::commands::Command *command); 185 186 // Selects the transliteration candidate. If the current state is 187 // composition, candidates will be generated with only translitaration 188 // candidates. 189 bool ConvertToHiragana(mozc::commands::Command *command); 190 bool ConvertToFullKatakana(mozc::commands::Command *command); 191 bool ConvertToHalfKatakana(mozc::commands::Command *command); 192 bool ConvertToFullASCII(mozc::commands::Command *command); 193 bool ConvertToHalfASCII(mozc::commands::Command *command); 194 bool ConvertToHalfWidth(mozc::commands::Command *command); 195 // Switch the composition to Hiragana, full-width Katakana or 196 // half-width Katakana by rotation. 197 bool SwitchKanaType(mozc::commands::Command *command); 198 199 // Select the transliteration candidate if the current status is 200 // conversion. This is same with the above ConvertTo functions. If 201 // the current state is composition, the display mode is changed to the 202 // transliteration and the composition state still remains. 203 bool DisplayAsHiragana(mozc::commands::Command *command); 204 bool DisplayAsFullKatakana(mozc::commands::Command *command); 205 bool DisplayAsHalfKatakana(mozc::commands::Command *command); 206 bool TranslateFullASCII(mozc::commands::Command *command); 207 bool TranslateHalfASCII(mozc::commands::Command *command); 208 bool TranslateHalfWidth(mozc::commands::Command *command); 209 bool ToggleAlphanumericMode(mozc::commands::Command *command); 210 211 // Switch the input mode. 212 bool InputModeHiragana(mozc::commands::Command *command); 213 bool InputModeFullKatakana(mozc::commands::Command *command); 214 bool InputModeHalfKatakana(mozc::commands::Command *command); 215 bool InputModeFullASCII(mozc::commands::Command *command); 216 bool InputModeHalfASCII(mozc::commands::Command *command); 217 bool InputModeSwitchKanaType(mozc::commands::Command *command); 218 219 // Specify the input field type. 220 bool SwitchInputFieldType(mozc::commands::Command *command); 221 222 // Let client launch config dialog 223 bool LaunchConfigDialog(mozc::commands::Command *command); 224 225 // Let client launch dictionary tool 226 bool LaunchDictionaryTool(mozc::commands::Command *command); 227 228 // Let client launch word register dialog 229 bool LaunchWordRegisterDialog(mozc::commands::Command *command); 230 231 // Undo if pre-composition is empty. Rewind KANA cycle othrewise. 232 bool UndoOrRewind(mozc::commands::Command *command); 233 // Send a command to the composer to append a special string. 234 bool SendComposerCommand( 235 const mozc::composer::Composer::InternalCommand composer_command, 236 mozc::commands::Command *command); 237 238 bool ReportBug(mozc::commands::Command *command); 239 240 virtual void SetConfig(mozc::config::Config *config); 241 242 virtual void SetRequest(const mozc::commands::Request *request); 243 244 virtual void SetTable(const mozc::composer::Table *table); 245 246 // Set client capability for this session. Used by unittest. 247 virtual void set_client_capability( 248 const mozc::commands::Capability &capability); 249 250 // Set application information for this session. 251 virtual void set_application_info( 252 const mozc::commands::ApplicationInfo &application_info); 253 254 // Get application information 255 virtual const mozc::commands::ApplicationInfo &application_info() const; 256 257 // Return the time when this instance was created. 258 virtual uint64 create_session_time() const; 259 260 // return 0 (default value) if no command is executed in this session. 261 virtual uint64 last_command_time() const; 262 263 // TODO(komatsu): delete this funciton. 264 // For unittest only 265 mozc::composer::Composer *get_internal_composer_only_for_unittest(); 266 267 const ImeContext &context() const; 268 269 private: 270 FRIEND_TEST(SessionTest, OutputInitialComposition); 271 FRIEND_TEST(SessionTest, IsFullWidthInsertSpace); 272 FRIEND_TEST(SessionTest, RequestUndo); 273 274 // Underlying conversion engine for this session. Please note that: 275 // i) Session doesn't own the pointer. 276 // ii) The state of underlying converter will change because it manages user 277 // history, user dictionary, etc. 278 mozc::EngineInterface *engine_; 279 280 std::unique_ptr<ImeContext> context_; 281 std::unique_ptr<ImeContext> prev_context_; 282 283 void InitContext(ImeContext *context) const; 284 285 void PushUndoContext(); 286 void PopUndoContext(); 287 void ClearUndoContext(); 288 289 // Return true if full width space is preferred in the given new input 290 // state than half width space. When |input| does not have new input mode, 291 // the current mode will be considered. 292 bool IsFullWidthInsertSpace(const mozc::commands::Input &input) const; 293 294 bool EditCancelOnPasswordField(mozc::commands::Command *command); 295 296 bool ConvertToTransliteration( 297 mozc::commands::Command *command, 298 mozc::transliteration::TransliterationType type); 299 300 // Select a candidate located by input.command.id. This command 301 // would not be used from SendKey but used from SendCommand because 302 // it requires the argument id. 303 bool SelectCandidate(mozc::commands::Command *command); 304 305 // Calls SessionConverter::ConmmitFirstSegment() and deletes characters 306 // from the composer. 307 void CommitFirstSegmentInternal(const commands::Context &context); 308 309 // Calls SessionConverter::ConmmitHeadToFocusedSegments() 310 // and deletes characters from the composer. 311 void CommitHeadToFocusedSegmentsInternal(const commands::Context &context); 312 313 // Commits without SessionConverter. 314 void CommitCompositionDirectly(commands::Command *command); 315 void CommitSourceTextDirectly(commands::Command *command); 316 void CommitRawTextDirectly(commands::Command *command); 317 void CommitStringDirectly(const string &key, const string &preedit, 318 commands::Command *command); 319 bool CommitInternal(commands::Command *command, 320 bool trigger_zero_query_suggest); 321 322 // Calls SessionConverter::Suggest if the condition is applicable to 323 // call it. True is returned when SessionConverter::Suggest is 324 // called and results exist. False is returned when 325 // SessionConverter::Suggest is not called or no results exist. 326 bool Suggest(const mozc::commands::Input &input); 327 328 // Commands like EditCancel should restore the original string used for 329 // the reverse conversion without any modification. 330 // Returns true if the |source_text| is committed to cancel reconversion. 331 // Returns false if this function has nothing to do. 332 bool TryCancelConvertReverse(mozc::commands::Command *command); 333 334 // Set the focus to the candidate located by input.command.id. This 335 // command would not be used from SendKey but used from SendCommand 336 // because it requires the argument id. The difference from 337 // SelectCandidate is that HighlightCandidate does not close the 338 // candidate window while SelectCandidate closes the candidate 339 // window. 340 bool HighlightCandidate(mozc::commands::Command *command); 341 342 // The internal implementation of both SelectCandidate and HighlightCandidate. 343 bool SelectCandidateInternal(mozc::commands::Command *command); 344 345 // If the command is a shortcut to select a candidate from a list, 346 // Process it and return true, otherwise return false. 347 bool MaybeSelectCandidate(mozc::commands::Command *command); 348 349 // Fill command's output according to the current state. 350 void OutputFromState(mozc::commands::Command *command); 351 void Output(mozc::commands::Command *command); 352 void OutputMode(mozc::commands::Command *command) const; 353 void OutputComposition(mozc::commands::Command *command) const; 354 void OutputKey(mozc::commands::Command *command) const; 355 356 bool SendKeyDirectInputState(mozc::commands::Command *command); 357 bool SendKeyPrecompositionState(mozc::commands::Command *command); 358 bool SendKeyCompositionState(mozc::commands::Command *command); 359 bool SendKeyConversionState(mozc::commands::Command *command); 360 361 // update last_command_time; 362 void UpdateTime(); 363 364 // update preferences only affecting this session. 365 void UpdatePreferences(mozc::commands::Command *command); 366 367 // Modify input of SendKey, TestSendKey, and SendCommand. 368 void TransformInput(mozc::commands::Input *input); 369 370 // ensure session status is not DIRECT. 371 // if session status is DIRECT, set the status to PRECOMPOSITION. 372 void EnsureIMEIsOn(); 373 374 // return true if |key_event| is a triggering key_event of 375 // AutoIMEConversion. 376 bool CanStartAutoConversion(const mozc::commands::KeyEvent &key_event) const; 377 378 // Handles KeyEvent::activated to support indirect IME on/off. 379 bool HandleIndirectImeOnOff(mozc::commands::Command *command); 380 381 // Commits the raw text of the composition. 382 bool CommitRawText(commands::Command *command); 383 384 DISALLOW_COPY_AND_ASSIGN(Session); 385 }; 386 387 } // namespace session 388 } // namespace mozc 389 390 #endif // MOZC_SESSION_SESSION_H_ 391