From ec32ccb6d640439b71e154c4d48daeb8bd10ff92 Mon Sep 17 00:00:00 2001 From: Oleksiy Kurochko Date: Wed, 22 Feb 2012 17:15:02 +0200 Subject: GUI: Move predictive dialog to common gui --- gui/predictivedialog.cpp | 917 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 917 insertions(+) create mode 100644 gui/predictivedialog.cpp (limited to 'gui/predictivedialog.cpp') diff --git a/gui/predictivedialog.cpp b/gui/predictivedialog.cpp new file mode 100644 index 0000000000..ac329867d2 --- /dev/null +++ b/gui/predictivedialog.cpp @@ -0,0 +1,917 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "gui/predictivedialog.h" +#include "gui/widget.h" +#include "gui/widgets/edittext.h" +#include "gui/gui-manager.h" + +#include "common/config-manager.h" +#include "common/translation.h" +#include "common/events.h" +#include "common/debug.h" +#include "common/system.h" +#include "common/keyboard.h" +#include "common/file.h" +#include "common/savefile.h" + +using namespace Common; + +namespace GUI { + +enum { + kCancelCmd = 'CNCL', + kOkCmd = '__OK', + kBut1Cmd = 'BUT1', + kBut2Cmd = 'BUT2', + kBut3Cmd = 'BUT3', + kBut4Cmd = 'BUT4', + kBut5Cmd = 'BUT5', + kBut6Cmd = 'BUT6', + kBut7Cmd = 'BUT7', + kBut8Cmd = 'BUT8', + kBut9Cmd = 'BUT9', + kBut0Cmd = 'BUT0', + kNextCmd = 'NEXT', + kAddCmd = '_ADD', + kModeCmd = 'MODE', + kDelCmd = '_DEL', + kTestCmd = 'TEST' +}; + +enum { + kModePre = 0, + kModeNum = 1, + kModeAbc = 2 +}; + +PredictiveDialog::PredictiveDialog() : Dialog("Predictive") { + new StaticTextWidget(this, "Predictive.Headline", "Enter Text"); + + new ButtonWidget(this, "Predictive.Cancel" , _("Cancel") , 0, kCancelCmd); + new ButtonWidget(this, "Predictive.OK" , _("Ok") , 0, kOkCmd); + new ButtonWidget(this, "Predictive.Button1", "1 `-.&" , 0, kBut1Cmd); + new ButtonWidget(this, "Predictive.Button2", "2 abc" , 0, kBut2Cmd); + new ButtonWidget(this, "Predictive.Button3", "3 def" , 0, kBut3Cmd); + new ButtonWidget(this, "Predictive.Button4", "4 ghi" , 0, kBut4Cmd); + new ButtonWidget(this, "Predictive.Button5", "5 jkl" , 0, kBut5Cmd); + new ButtonWidget(this, "Predictive.Button6", "6 mno" , 0, kBut6Cmd); + new ButtonWidget(this, "Predictive.Button7", "7 pqrs" , 0, kBut7Cmd); + new ButtonWidget(this, "Predictive.Button8", "8 tuv" , 0, kBut8Cmd); + new ButtonWidget(this, "Predictive.Button9", "9 wxyz" , 0, kBut9Cmd); + new ButtonWidget(this, "Predictive.Button0", "0" , 0, kBut0Cmd); + // I18N: You must leave "#" as is, only word 'next' is translatable + new ButtonWidget(this, "Predictive.Next" , _("# next") , 0, kNextCmd); + _addBtn = new ButtonWidget(this, "Predictive.Add", _("add") , 0, kAddCmd); + _addBtn->setEnabled(false); + +#ifndef DISABLE_FANCY_THEMES + _delbtn = new PicButtonWidget(this, "Predictive.Delete", _("Delete char"), kDelCmd); + ((PicButtonWidget *)_delbtn)->useThemeTransparency(true); + ((PicButtonWidget *)_delbtn)->setGfx(g_gui.theme()->getImageSurface(ThemeEngine::kImageDelbtn)); +#endif + _delbtn = new ButtonWidget(this, "Predictive.Delete" , _("<") , 0, kDelCmd); + // I18N: Pre means 'Predictive', leave '*' as is + _modebutton = new ButtonWidget(this, "Predictive.Pre", _("* Pre"), 0, kModeCmd); + _edittext = new EditTextWidget(this, "Predictive.Word", _search, 0, 0, 0); + + _userDictHasChanged = false; + + _predictiveDict.nameDict = "predictive_dictionary"; + _predictiveDict.fnameDict = "pred.dic"; + _predictiveDict.dictActLine = NULL; + + _userDict.nameDict = "user_dictionary"; + _userDict.fnameDict = "user.dic"; + _userDict.dictActLine = NULL; + + _unitedDict.nameDict = ""; + _unitedDict.fnameDict = ""; + + _predictiveDict.dictLine = NULL; + _predictiveDict.dictText = NULL; + _predictiveDict.dictLineCount = 0; + + if (!_predictiveDict.dictText) { + loadAllDictionary(_predictiveDict); + if (!_predictiveDict.dictText) + debug("Predictive Dialog: pred.dic not loaded"); + } + + _userDict.dictLine = NULL; + _userDict.dictText = NULL; + _userDict.dictTextSize = 0; + _userDict.dictLineCount = 0; + + if (!_userDict.dictText) { + loadAllDictionary(_userDict); + if (!_userDict.dictText) + debug("Predictive Dialog: user.dic not loaded"); + } + + mergeDicts(); + + _unitedDict.dictActLine = NULL; + _unitedDict.dictText = NULL; + + memset(_repeatcount, 0, sizeof(_repeatcount)); + + _prefix.clear(); + _currentCode.clear(); + _currentWord.clear(); + _wordNumber = 0; + _numMatchingWords = 0; + + _lastbutton = kNoAct; + _mode = kModePre; + + _lastTime = 0; + _curTime = 0; + _lastPressBtn = kNoAct; + + _memoryList[0] = _predictiveDict.dictText; + _memoryList[1] = _userDict.dictText; + _numMemory = 0; + + _navigationwithkeys = false; +} + +PredictiveDialog::~PredictiveDialog() { + for (int i = 0; i < _numMemory; i++) { + free(_memoryList[i]); + } + free(_userDict.dictLine); + free(_predictiveDict.dictLine); + free(_unitedDict.dictLine); +} + +void PredictiveDialog::saveUserDictToFile() { + if (_userDictHasChanged) { + ConfMan.registerDefault("user_dictionary", "user.dic"); + + Common::OutSaveFile *file = g_system->getSavefileManager()->openForSaving(ConfMan.get("user_dictionary")); + + for (int i = 0; i < _userDict.dictLineCount; i++) { + file->writeString(_userDict.dictLine[i]); + file->writeString("\n"); + } + + file->finalize(); + delete file; + } +} + +void PredictiveDialog::handleKeyDown(Common::KeyState state) { + ButtonId act = kNoAct; + + if (getFocusWidget() == _edittext) { + setFocusWidget(_addBtn); + } + + switch (state.keycode) { + case Common::KEYCODE_ESCAPE: + saveUserDictToFile(); + close(); + return; + case Common::KEYCODE_LEFT: + _navigationwithkeys = true; + if (_lastbutton == kBtn1Act || _lastbutton == kBtn4Act || _lastbutton == kBtn7Act) + act = ButtonId(_lastbutton + 2); + else if (_lastbutton == kNextAct) + act = kBtn0Act; + else if (_lastbutton == kDelAct) + act = kDelAct; + else if (_lastbutton == kCancelAct) + act = kOkAct; + else if (_lastbutton == kModeAct) + act = kAddAct; + else + act = ButtonId(_lastbutton - 1); + _lastbutton = act; + //needRefresh = true; + break; + case Common::KEYCODE_RIGHT: + _navigationwithkeys = true; + if (_lastbutton == kBtn3Act || _lastbutton == kBtn6Act || _lastbutton == kBtn9Act) + act = ButtonId(_lastbutton - 2); + else if (_lastbutton == kAddAct) + act = kModeAct; + else if (_lastbutton == kDelAct) + act = kDelAct; + else if (_lastbutton == kOkAct) + act = kCancelAct; + else if (_lastbutton == kBtn0Act) + act = kNextAct; + else + act = ButtonId(_lastbutton + 1); + _lastbutton = act; + //needRefresh = true; + break; + case Common::KEYCODE_UP: + _navigationwithkeys = true; + if (_lastbutton <= kBtn3Act) + act = kDelAct; + else if (_lastbutton == kNextAct || _lastbutton == kAddAct) + act = ButtonId(_lastbutton - 2); + else if (_lastbutton == kDelAct) + act = kOkAct; + else if (_lastbutton == kModeAct) + act = kBtn9Act; + else if (_lastbutton == kBtn0Act) + act = kBtn7Act; + else + act = ButtonId(_lastbutton - 3); + _lastbutton = act; + //needRefresh = true; + break; + case Common::KEYCODE_DOWN: + _navigationwithkeys = true; + if (_lastbutton == kBtn7Act) + act = kBtn0Act; + else if (_lastbutton == kBtn8Act || _lastbutton == kBtn9Act) + act = ButtonId(_lastbutton + 2); + else if (_lastbutton == kDelAct) + act = kBtn1Act; + else if (_lastbutton == kCancelAct || _lastbutton == kOkAct) + act = kDelAct; + else if (_lastbutton == kModeAct || _lastbutton == kBtn0Act) + act = ButtonId(_lastbutton - 2); + else + act = ButtonId(_lastbutton + 3); + _lastbutton = act; + //needRefresh = true; + break; + case Common::KEYCODE_KP_ENTER: + if (_navigationwithkeys) { + // when the user has utilized arrow key navigation, + // interpret enter as 'click' on the act button + act = _lastbutton; + } else { + // else it is a shortcut for 'Ok' + act = kOkAct; + } + break; + case Common::KEYCODE_KP_PLUS: + act = kAddAct; + break; + case Common::KEYCODE_BACKSPACE: + case Common::KEYCODE_KP_MINUS: + act = kDelAct; + break; + case Common::KEYCODE_KP_DIVIDE: + act = kNextAct; + break; + case Common::KEYCODE_KP_MULTIPLY: + act = kModeAct; + break; + case Common::KEYCODE_KP0: + act = kBtn0Act; + break; + case Common::KEYCODE_KP1: + case Common::KEYCODE_KP2: + case Common::KEYCODE_KP3: + case Common::KEYCODE_KP4: + case Common::KEYCODE_KP5: + case Common::KEYCODE_KP6: + case Common::KEYCODE_KP7: + case Common::KEYCODE_KP8: + case Common::KEYCODE_KP9: + act = ButtonId(state.keycode - Common::KEYCODE_KP1); + break; + default: + Dialog::handleKeyDown(state); + } + + if (act != kNoAct) { + processBtnActive(act); + } +} + +void PredictiveDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { + ButtonId act = kNoAct; + + _navigationwithkeys = false; + + switch (cmd) { + case kDelCmd: + act = kDelAct; + break; + case kNextCmd: + act = kNextAct; + break; + case kAddCmd: + act = kAddAct; + break; + case kModeCmd: + act = kModeAct; + break; + case kBut1Cmd: + act = kBtn1Act; + break; + case kBut2Cmd: + act = kBtn2Act; + break; + case kBut3Cmd: + act = kBtn3Act; + break; + case kBut4Cmd: + act = kBtn4Act; + break; + case kBut5Cmd: + act = kBtn5Act; + break; + case kBut6Cmd: + act = kBtn6Act; + break; + case kBut7Cmd: + act = kBtn7Act; + break; + case kBut8Cmd: + act = kBtn8Act; + break; + case kBut9Cmd: + act = kBtn9Act; + break; + case kBut0Cmd: + act = kBtn0Act; + break; + case kCancelCmd: + saveUserDictToFile(); + close(); + return; + case kOkCmd: + act = kOkAct; + break; + default: + Dialog::handleCommand(sender, cmd, data); + } + + if (act != kNoAct) { + processBtnActive(act); + } +} + +void PredictiveDialog::processBtnActive(ButtonId button) { + uint8 x; + const char *buttonStr[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "0" }; + const char *buttons[] = { + "'-.&", "abc", "def", + "ghi", "jkl", "mno", + "pqrs", "tuv", "wxyz", + "next", "add", + "<", + "Cancel", "OK", + "Pre", "(0) ", NULL + }; + + if (_mode == kModeAbc) { + if (button >= kBtn1Act && button <= kBtn9Act ) { + if (!_lastTime) + _lastTime = g_system->getMillis(); + if (_lastPressBtn == button) { + _curTime = g_system->getMillis(); + if((_curTime - _lastTime) < kRepeatDelay) { + button = kNextAct; + _lastTime = _curTime; + } else { + _lastTime = 0; + } + } else { + _lastPressBtn = button; + _lastTime = g_system->getMillis(); + } + } + } + + if (button >= kBtn1Act) { + _lastbutton = button; + if (button == kBtn0Act && _mode != kModeNum) { // Space + // bring MRU word at the top of the list when changing words + if (_mode == kModePre && _unitedDict.dictActLine && _numMatchingWords > 1 && _wordNumber != 0) + bringWordtoTop(_unitedDict.dictActLine, _wordNumber); + + strncpy(_temp, _currentWord.c_str(), _currentCode.size()); + _temp[_currentCode.size()] = 0; + _prefix += _temp; + _prefix += " "; + _currentCode.clear(); + _currentWord.clear(); + _numMatchingWords = 0; + memset(_repeatcount, 0, sizeof(_repeatcount)); + _lastTime = 0; + _lastPressBtn = kNoAct; + _curTime = 0; + } else if (button < kNextAct || button == kDelAct || button == kBtn0Act) { // number or backspace + if (button == kDelAct) { // backspace + if (_currentCode.size()) { + _repeatcount[_currentCode.size() - 1] = 0; + _currentCode.deleteLastChar(); + if(_currentCode == Common::String("")) + _currentWord.clear(); + } else { + if (_prefix.size()) + _prefix.deleteLastChar(); + } + } else if (_prefix.size() + _currentCode.size() < MAXWORDLEN - 1) { // don't overflow the dialog line + if (button == kBtn0Act) { // zero + _currentCode += buttonStr[9]; + } else { + _currentCode += buttonStr[button]; + } + } + + switch (_mode) { + case kModeNum: + _currentWord = _currentCode; + break; + case kModePre: + if (!matchWord() && _currentCode.size()) { + _currentCode.deleteLastChar(); + matchWord(); + } + _numMatchingWords = countWordsInString(_unitedDict.dictActLine); + break; + case kModeAbc: + for (x = 0; x < _currentCode.size(); x++) + if (_currentCode[x] >= '1') + _temp[x] = buttons[_currentCode[x] - '1'][_repeatcount[x]]; + _temp[_currentCode.size()] = 0; + _currentWord = _temp; + } + } else if (button == kNextAct) { // next + if (_mode == kModePre) { + if (_unitedDict.dictActLine && _numMatchingWords > 1) { + _wordNumber = (_wordNumber + 1) % _numMatchingWords; + char tmp[MAXLINELEN]; + strncpy(tmp, _unitedDict.dictActLine, MAXLINELEN); + tmp[MAXLINELEN - 1] = 0; + char *tok = strtok(tmp, " "); + for (uint8 i = 0; i <= _wordNumber; i++) + tok = strtok(NULL, " "); + _currentWord = Common::String(tok, _currentCode.size()); + } + } else if (_mode == kModeAbc) { + x = _currentCode.size(); + if (x) { + if (_currentCode.lastChar() == '1' || _currentCode.lastChar() == '7' || _currentCode.lastChar() == '9') + _repeatcount[x - 1] = (_repeatcount[x - 1] + 1) % 4; + else + _repeatcount[x - 1] = (_repeatcount[x - 1] + 1) % 3; + + if (_currentCode.lastChar() >= '1') + _currentWord.setChar(buttons[_currentCode[x - 1] - '1'][_repeatcount[x - 1]], x-1); + } + } + } else if (button == kAddAct) { // add + if (_mode == kModeAbc) + addWordToDict(); + else + debug("Predictive Dialog: button Add doesn't work in this mode"); + } else if (button == kOkAct) { // Ok + // bring MRU word at the top of the list when ok'ed out of the dialog + if (_mode == kModePre && _unitedDict.dictActLine && _numMatchingWords > 1 && _wordNumber != 0) + bringWordtoTop(_unitedDict.dictActLine, _wordNumber); + + goto press; + } else if (button == kModeAct) { // Mode + _mode++; + _addBtn->setEnabled(false); + if (_mode > kModeAbc) { + _mode = kModePre; + // I18N: Pre means 'Predictive', leave '*' as is + _modebutton->setLabel("* Pre"); + // I18N: 'Num' means Numbers, 'Abc' means Latin alphabet input + } else (_mode == kModeNum) ? _modebutton->setLabel("* Num") : (_modebutton->setLabel("* Abc"), _addBtn->setEnabled(true)); + + // truncate current input at mode change + strncpy(_temp, _currentWord.c_str(), _currentCode.size()); + _temp[_currentCode.size()] = 0; + _prefix += _temp; + _currentCode.clear(); + _currentWord.clear(); + memset(_repeatcount, 0, sizeof(_repeatcount)); + + _lastTime = 0; + _lastPressBtn = kNoAct; + _curTime = 0; + } else { + goto press; + } + } + +press: + pressEditText(); + + if (button == kOkAct) close(); +} + +void PredictiveDialog::handleTickle() { + if (!_lastTime) + if ((_curTime - _lastTime) > kRepeatDelay) { + _lastTime = 0; + } +} + +void PredictiveDialog::mergeDicts() { + _unitedDict.dictLineCount = _predictiveDict.dictLineCount + _userDict.dictLineCount; + _unitedDict.dictLine = (char **)calloc(1, sizeof(char *) * _unitedDict.dictLineCount); + + if (!_unitedDict.dictLine) { + debug("Predictive Dialog: cannot allocate memory for united dic"); + return; + } + + int lenUserDictCode, lenPredictiveDictCode, lenCode; + int i, j, k; + i = j = k = 0; + + while ((i < _userDict.dictLineCount) && (j < _predictiveDict.dictLineCount)) { + lenUserDictCode = strchr(_userDict.dictLine[i], ' ') - _userDict.dictLine[i]; + lenPredictiveDictCode = strchr(_predictiveDict.dictLine[j], ' ') - _predictiveDict.dictLine[j]; + lenCode = (lenUserDictCode >= lenPredictiveDictCode) ? lenUserDictCode : lenPredictiveDictCode; + if (strncmp(_userDict.dictLine[i], _predictiveDict.dictLine[j], lenCode) >= 0) { + _unitedDict.dictLine[k++] = _predictiveDict.dictLine[j++]; + } else { + _unitedDict.dictLine[k++] = _userDict.dictLine[i++]; + } + } + + while (i < _userDict.dictLineCount) { + _unitedDict.dictLine[k++] = _userDict.dictLine[i++]; + } + + while (j < _predictiveDict.dictLineCount) { + _unitedDict.dictLine[k++] = _predictiveDict.dictLine[j++]; + } +} + +uint8 PredictiveDialog::countWordsInString(char *str) { + // Count the number of (space separated) words in the given string. + char *ptr; + + if (!str) + return 0; + + ptr = strchr(str, ' '); + if (!ptr) { + debug("Predictive Dialog: Invalid dictionary line"); + return 0; + } + + uint8 num = 1; + ptr++; + while ((ptr = strchr(ptr, ' '))) { + ptr++; + num++; + } + return num; +} + +void PredictiveDialog::bringWordtoTop(char *str, int wordnum) { + // This function reorders the words on the given pred.dic line + // by moving the word at position 'wordnum' to the front (that is, right behind + // right behind the numerical code word at the start of the line). + Common::Array words; + char buf[MAXLINELEN]; + + if (!str) + return; + strncpy(buf, str, MAXLINELEN); + buf[MAXLINELEN - 1] = 0; + char *word = strtok(buf, " "); + if (!word) { + debug("Predictive Dialog: Invalid dictionary line"); + return; + } + + words.push_back(word); + while ((word = strtok(NULL, " ")) != NULL) + words.push_back(word); + words.insert_at(1, words.remove_at(wordnum + 1)); + + Common::String tmp; + for (uint8 i = 0; i < words.size(); i++) + tmp += words[i] + " "; + tmp.deleteLastChar(); + memcpy(str, tmp.c_str(), strlen(str)); +} + +int PredictiveDialog::binarySearch(char **dictLine, const String &code, int dictLineCount) { + int hi = dictLineCount - 1; + int lo = 0; + int line = 0; + while (lo <= hi) { + line = (lo + hi) / 2; + int cmpVal = strncmp(dictLine[line], code.c_str(), code.size()); + if (cmpVal > 0) + hi = line - 1; + else if (cmpVal < 0) + lo = line + 1; + else { + break; + } + } + + if (hi < lo) { + return -(lo + 1); + } else { + return line; + } +} + +bool PredictiveDialog::matchWord() { + // If no text has been entered, then there is no match. + if (_currentCode.empty()) + return false; + + // If the currently entered text is too long, it cannot match anything. + if (_currentCode.size() > MAXWORDLEN) + return false; + + // The entries in the dictionary consist of a code, a space, and then + // a space-separated list of words matching this code. + // To exactly match a code, we therefore match the code plus the trailing + // space in the dictionary. + Common::String code = _currentCode + " "; + + int line = binarySearch(_unitedDict.dictLine, code, _unitedDict.dictLineCount); + if (line < 0) { + line = -(line + 1); + _unitedDict.dictActLine = NULL; + } else { + _unitedDict.dictActLine = _unitedDict.dictLine[line]; + } + + _currentWord.clear(); + _wordNumber = 0; + if (0 == strncmp(_unitedDict.dictLine[line], _currentCode.c_str(), _currentCode.size())) { + char tmp[MAXLINELEN]; + strncpy(tmp, _unitedDict.dictLine[line], MAXLINELEN); + tmp[MAXLINELEN - 1] = 0; + char *tok = strtok(tmp, " "); + tok = strtok(NULL, " "); + _currentWord = Common::String(tok, _currentCode.size()); + return true; + } else { + return false; + } +} + +bool PredictiveDialog::searchWord(char *where, const String &whatCode) { + char *ptr = where; + ptr += whatCode.size(); + + char *newPtr; + bool is = false; + while((newPtr = strchr(ptr, ' '))) { + if (0 == strncmp(ptr, _currentWord.c_str(), newPtr - ptr)) { + is = true; + break; + } + ptr = newPtr + 1; + } + if (!is) { + if (0 == strcmp(ptr, _currentWord.c_str())) { + is = true; + } + } + return is; +} + +void PredictiveDialog::addWord(Dict &dict, const String &word, const String &code) { + char *newLine; + Common::String tmpCode = code + ' '; + int line = binarySearch(dict.dictLine, tmpCode, dict.dictLineCount); + if (line >= 0) { + if (searchWord(dict.dictLine[line], tmpCode)) { + // if we found code and word, we should not insert/expands any word + return; + } else { + // if we found the code, but did not find a word, we must + // EXPANDS the currnent line with new word + int oldLineSize = strlen(dict.dictLine[line]); + int newLineSize = oldLineSize + word.size() + 1; + + newLine = (char *)malloc(newLineSize + 1); + + char *ptr = newLine; + strncpy(ptr, dict.dictLine[line], oldLineSize); + ptr += oldLineSize; + Common::String tmp = ' ' + word + '\0'; + strncpy(ptr, tmp.c_str(), tmp.size()); + + dict.dictLine[line] = newLine; + _memoryList[_numMemory++] = newLine; + + if (dict.nameDict == "user_dictionary") + _userDictHasChanged = true; + + return; + } + } else { // if we didn't find the code, we need to INSERT new line with code and word + if (dict.nameDict == "user_dictionary") { + // if we must INSERT new line(code and word) to user_dictionary, we need to + // check if there is a line that we want to INSERT in predictive dictionay + int predictLine = binarySearch(_predictiveDict.dictLine, tmpCode, _predictiveDict.dictLineCount); + if (predictLine >= 0) { + if (searchWord(_predictiveDict.dictLine[predictLine], tmpCode)) { + // if code and word is in predictive dictionary, we need to copy + // this line to user dictionary + int len = (predictLine == _predictiveDict.dictLineCount - 1) ? &_predictiveDict.dictText[_predictiveDict.dictTextSize] - _predictiveDict.dictLine[predictLine] : + _predictiveDict.dictLine[predictLine + 1] - _predictiveDict.dictLine[predictLine]; + newLine = (char *)malloc(len); + strncpy(newLine, _predictiveDict.dictLine[predictLine], len); + } else { + // if there is no word in predictive dictionary, we need to copy to + // user dictionary mathed line + new word. + int len = (predictLine == _predictiveDict.dictLineCount - 1) ? &_predictiveDict.dictText[_predictiveDict.dictTextSize] - _predictiveDict.dictLine[predictLine] : + _predictiveDict.dictLine[predictLine + 1] - _predictiveDict.dictLine[predictLine]; + newLine = (char *)malloc(len + word.size() + 1); + char *ptr = newLine; + strncpy(ptr, _predictiveDict.dictLine[predictLine], len); + ptr[len - 1] = ' '; + ptr += len; + strncpy(ptr, word.c_str(), word.size()); + ptr[len + word.size()] = '\0'; + } + } else { + // if we didnt find line in predictive dialog, we should copy to user dictionary + // code + word + Common::String tmp; + tmp = tmpCode + word + '\0'; + newLine = (char *)malloc(tmp.size()); + strncpy(newLine, tmp.c_str(), tmp.size()); + } + } else { + // if want to insert line to different from user dictionary, we should copy to this + // dictionary code + word + Common::String tmp; + tmp = tmpCode + word + '\0'; + newLine = (char *)malloc(tmp.size()); + strncpy(newLine, tmp.c_str(), tmp.size()); + } + } + + // start from here are INSERTING new line to dictionaty ( dict ) + char **newDictLine = (char **)calloc(1, sizeof(char *) * (dict.dictLineCount + 1)); + if (!newDictLine) { + warning("Predictive Dialog: cannot allocate memory for index buffer"); + return; + } + newDictLine[dict.dictLineCount] = '\0'; + + int k = 0; + bool inserted = false; + for (int i = 0; i < dict.dictLineCount; i++) { + uint lenPredictiveDictCode = strchr(dict.dictLine[i], ' ') - dict.dictLine[i]; + uint lenCode = (lenPredictiveDictCode >= (code.size() - 1)) ? lenPredictiveDictCode : code.size() - 1; + if ((strncmp(dict.dictLine[i], code.c_str(), lenCode) > 0) && !inserted) { + newDictLine[k++] = newLine; + inserted = true; + } + if (k != (dict.dictLineCount + 1)) { + newDictLine[k++] = dict.dictLine[i]; + } + } + if (!inserted) + newDictLine[k] = newLine; + + _memoryList[_numMemory++] = newLine; + + free(dict.dictLine); + dict.dictLineCount += 1; + dict.dictLine = (char **)calloc(1, sizeof(char *) * dict.dictLineCount); + if (!dict.dictLine) { + warning("Predictive Dialog: cannot allocate memory for index buffer"); + free(newDictLine); + return; + } + + for (int i = 0; i < dict.dictLineCount; i++) { + dict.dictLine[i] = newDictLine[i]; + } + + if (dict.nameDict == "user_dictionary") + _userDictHasChanged = true; + + free(newDictLine); +} + +void PredictiveDialog::addWordToDict() { + if (_numMemory < MAXWORD) { + addWord(_unitedDict, _currentWord, _currentCode); + addWord(_userDict, _currentWord, _currentCode); + } else { + warning("Predictive Dialog: You cannot add word to user dictionary..."); + } +} + +void PredictiveDialog::loadDictionary(Common::SeekableReadStream *in, Dict &dict) { + int lines = 0; + + uint32 time1 = g_system->getMillis(); + + dict.dictTextSize = in->size(); + dict.dictText = (char *)malloc(dict.dictTextSize + 1); + + if (!dict.dictText) { + warning("Predictive Dialog: Not enough memory to load the file user.dic"); + return; + } + + in->read(dict.dictText, dict.dictTextSize); + dict.dictText[dict.dictTextSize] = 0; + uint32 time2 = g_system->getMillis(); + debug("Predictive Dialog: Time to read %s: %d bytes, %d ms", ConfMan.get(dict.nameDict).c_str(), dict.dictTextSize, time2-time1); + delete in; + + char *ptr = dict.dictText; + lines = 1; + while ((ptr = strchr(ptr, '\n'))) { + lines++; + ptr++; + } + + dict.dictLine = (char **)calloc(1, sizeof(char *) * lines); + if (dict.dictLine == NULL) { + warning("Predictive Dialog: Cannot allocate memory for line index buffer"); + return; + } + dict.dictLine[0] = dict.dictText; + ptr = dict.dictText; + int i = 1; + while ((ptr = strchr(ptr, '\n'))) { + *ptr = 0; + ptr++; +#ifdef __DS__ + // Pass the line on to the DS word list + DS::addAutoCompleteLine(dict.dictLine[i - 1]); +#endif + dict.dictLine[i++] = ptr; + } + if (dict.dictLine[lines - 1][0] == 0) + lines--; + + dict.dictLineCount = lines; + debug("Predictive Dialog: Loaded %d lines", dict.dictLineCount); + + // FIXME: We use binary search on _predictiveDict.dictLine, yet we make no at_tempt + // to ever sort this array (except for the DS port). That seems risky, doesn't it? + +#ifdef __DS__ + // Sort the DS word completion list, to allow for a binary chop later (in the ds backend) + DS::sortAutoCompleteWordList(); +#endif + + uint32 time3 = g_system->getMillis(); + debug("Predictive Dialog: Time to parse %s: %d, total: %d", ConfMan.get(dict.nameDict).c_str(), time3-time2, time3-time1); +} + +void PredictiveDialog::loadAllDictionary(Dict &dict) { + ConfMan.registerDefault(dict.nameDict, dict.fnameDict); + + if (dict.nameDict == "predictive_dictionary") { + Common::File *inFile = new File(); + if (!inFile->open(ConfMan.get(dict.nameDict))) { + warning("Predictive Dialog: cannot read file: %s", dict.fnameDict.c_str()); + return; + } + loadDictionary(inFile, dict); + } else { + Common::InSaveFile *inFile = g_system->getSavefileManager()->openForLoading(ConfMan.get(dict.nameDict)); + if (!inFile) { + warning("Predictive Dialog: cannot read file: %s", dict.fnameDict.c_str()); + return; + } + loadDictionary(inFile, dict); + } +} + +void PredictiveDialog::pressEditText() { + Common::strlcpy(_predictiveResult, _prefix.c_str(), sizeof(_predictiveResult)); + Common::strlcat(_predictiveResult, _currentWord.c_str(), sizeof(_predictiveResult)); + _edittext->setEditString(_predictiveResult); + //_edittext->setCaretPos(_prefix.size() + _currentWord.size()); + _edittext->draw(); +} + +} // namespace GUI \ No newline at end of file -- cgit v1.2.3 From 9e93b8306dad9d596827d1674c789057483f20e9 Mon Sep 17 00:00:00 2001 From: D G Turner Date: Sun, 25 Mar 2012 20:15:53 +0100 Subject: GUI: Fix for NDS compile failure after predictive dialog changes. --- gui/predictivedialog.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'gui/predictivedialog.cpp') diff --git a/gui/predictivedialog.cpp b/gui/predictivedialog.cpp index ac329867d2..9b678552af 100644 --- a/gui/predictivedialog.cpp +++ b/gui/predictivedialog.cpp @@ -825,6 +825,10 @@ void PredictiveDialog::addWordToDict() { } } +#ifdef __DS__ +#include "backends/platform/ds/arm9/source/wordcompletion.h" +#endif + void PredictiveDialog::loadDictionary(Common::SeekableReadStream *in, Dict &dict) { int lines = 0; -- cgit v1.2.3 From 8b1a01b12d44dddfb8804cb71ddbbf0693722d58 Mon Sep 17 00:00:00 2001 From: D G Turner Date: Sun, 25 Mar 2012 20:23:16 +0100 Subject: GUI: Corrected fix for NDS compile failure... Header needed to be in global, not GUI namespace. --- gui/predictivedialog.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'gui/predictivedialog.cpp') diff --git a/gui/predictivedialog.cpp b/gui/predictivedialog.cpp index 9b678552af..a0b183fa7d 100644 --- a/gui/predictivedialog.cpp +++ b/gui/predictivedialog.cpp @@ -34,6 +34,10 @@ #include "common/file.h" #include "common/savefile.h" +#ifdef __DS__ +#include "backends/platform/ds/arm9/source/wordcompletion.h" +#endif + using namespace Common; namespace GUI { @@ -825,10 +829,6 @@ void PredictiveDialog::addWordToDict() { } } -#ifdef __DS__ -#include "backends/platform/ds/arm9/source/wordcompletion.h" -#endif - void PredictiveDialog::loadDictionary(Common::SeekableReadStream *in, Dict &dict) { int lines = 0; @@ -918,4 +918,4 @@ void PredictiveDialog::pressEditText() { _edittext->draw(); } -} // namespace GUI \ No newline at end of file +} // namespace GUI -- cgit v1.2.3 From 371bc1ddc123984b5334a6bbfc105493306ffc3b Mon Sep 17 00:00:00 2001 From: D G Turner Date: Sun, 25 Mar 2012 23:29:19 +0100 Subject: GUI: Fix for WinCE compile failure after predictive dialog changes. This is probably due to a collision with WinCE toolchain system define, so changing the enum from all capitalised to Camel Case constant style. --- gui/predictivedialog.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'gui/predictivedialog.cpp') diff --git a/gui/predictivedialog.cpp b/gui/predictivedialog.cpp index a0b183fa7d..d9c3a58e24 100644 --- a/gui/predictivedialog.cpp +++ b/gui/predictivedialog.cpp @@ -435,7 +435,7 @@ void PredictiveDialog::processBtnActive(ButtonId button) { if (_prefix.size()) _prefix.deleteLastChar(); } - } else if (_prefix.size() + _currentCode.size() < MAXWORDLEN - 1) { // don't overflow the dialog line + } else if (_prefix.size() + _currentCode.size() < kMaxWordLen - 1) { // don't overflow the dialog line if (button == kBtn0Act) { // zero _currentCode += buttonStr[9]; } else { @@ -465,9 +465,9 @@ void PredictiveDialog::processBtnActive(ButtonId button) { if (_mode == kModePre) { if (_unitedDict.dictActLine && _numMatchingWords > 1) { _wordNumber = (_wordNumber + 1) % _numMatchingWords; - char tmp[MAXLINELEN]; - strncpy(tmp, _unitedDict.dictActLine, MAXLINELEN); - tmp[MAXLINELEN - 1] = 0; + char tmp[kMaxLineLen]; + strncpy(tmp, _unitedDict.dictActLine, kMaxLineLen); + tmp[kMaxLineLen - 1] = 0; char *tok = strtok(tmp, " "); for (uint8 i = 0; i <= _wordNumber; i++) tok = strtok(NULL, " "); @@ -595,12 +595,12 @@ void PredictiveDialog::bringWordtoTop(char *str, int wordnum) { // by moving the word at position 'wordnum' to the front (that is, right behind // right behind the numerical code word at the start of the line). Common::Array words; - char buf[MAXLINELEN]; + char buf[kMaxLineLen]; if (!str) return; - strncpy(buf, str, MAXLINELEN); - buf[MAXLINELEN - 1] = 0; + strncpy(buf, str, kMaxLineLen); + buf[kMaxLineLen - 1] = 0; char *word = strtok(buf, " "); if (!word) { debug("Predictive Dialog: Invalid dictionary line"); @@ -648,7 +648,7 @@ bool PredictiveDialog::matchWord() { return false; // If the currently entered text is too long, it cannot match anything. - if (_currentCode.size() > MAXWORDLEN) + if (_currentCode.size() > kMaxWordLen) return false; // The entries in the dictionary consist of a code, a space, and then @@ -668,9 +668,9 @@ bool PredictiveDialog::matchWord() { _currentWord.clear(); _wordNumber = 0; if (0 == strncmp(_unitedDict.dictLine[line], _currentCode.c_str(), _currentCode.size())) { - char tmp[MAXLINELEN]; - strncpy(tmp, _unitedDict.dictLine[line], MAXLINELEN); - tmp[MAXLINELEN - 1] = 0; + char tmp[kMaxLineLen]; + strncpy(tmp, _unitedDict.dictLine[line], kMaxLineLen); + tmp[kMaxLineLen - 1] = 0; char *tok = strtok(tmp, " "); tok = strtok(NULL, " "); _currentWord = Common::String(tok, _currentCode.size()); @@ -821,7 +821,7 @@ void PredictiveDialog::addWord(Dict &dict, const String &word, const String &cod } void PredictiveDialog::addWordToDict() { - if (_numMemory < MAXWORD) { + if (_numMemory < kMaxWord) { addWord(_unitedDict, _currentWord, _currentCode); addWord(_userDict, _currentWord, _currentCode); } else { -- cgit v1.2.3 From 15ff9380b5d9fcd0b39bbf5a3253e012039639e2 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Thu, 29 Mar 2012 01:48:37 +0200 Subject: GUI: Formatting fixes in the PredictiveDialog code. --- gui/predictivedialog.cpp | 133 ++++++++++++++++++++++++++--------------------- 1 file changed, 73 insertions(+), 60 deletions(-) (limited to 'gui/predictivedialog.cpp') diff --git a/gui/predictivedialog.cpp b/gui/predictivedialog.cpp index d9c3a58e24..4d640c7104 100644 --- a/gui/predictivedialog.cpp +++ b/gui/predictivedialog.cpp @@ -71,21 +71,21 @@ enum { PredictiveDialog::PredictiveDialog() : Dialog("Predictive") { new StaticTextWidget(this, "Predictive.Headline", "Enter Text"); - new ButtonWidget(this, "Predictive.Cancel" , _("Cancel") , 0, kCancelCmd); - new ButtonWidget(this, "Predictive.OK" , _("Ok") , 0, kOkCmd); - new ButtonWidget(this, "Predictive.Button1", "1 `-.&" , 0, kBut1Cmd); - new ButtonWidget(this, "Predictive.Button2", "2 abc" , 0, kBut2Cmd); - new ButtonWidget(this, "Predictive.Button3", "3 def" , 0, kBut3Cmd); - new ButtonWidget(this, "Predictive.Button4", "4 ghi" , 0, kBut4Cmd); - new ButtonWidget(this, "Predictive.Button5", "5 jkl" , 0, kBut5Cmd); - new ButtonWidget(this, "Predictive.Button6", "6 mno" , 0, kBut6Cmd); - new ButtonWidget(this, "Predictive.Button7", "7 pqrs" , 0, kBut7Cmd); - new ButtonWidget(this, "Predictive.Button8", "8 tuv" , 0, kBut8Cmd); - new ButtonWidget(this, "Predictive.Button9", "9 wxyz" , 0, kBut9Cmd); + new ButtonWidget(this, "Predictive.Cancel" , _("Cancel"), 0, kCancelCmd); + new ButtonWidget(this, "Predictive.OK" , _("Ok") , 0, kOkCmd); + new ButtonWidget(this, "Predictive.Button1", "1 `-.&" , 0, kBut1Cmd); + new ButtonWidget(this, "Predictive.Button2", "2 abc" , 0, kBut2Cmd); + new ButtonWidget(this, "Predictive.Button3", "3 def" , 0, kBut3Cmd); + new ButtonWidget(this, "Predictive.Button4", "4 ghi" , 0, kBut4Cmd); + new ButtonWidget(this, "Predictive.Button5", "5 jkl" , 0, kBut5Cmd); + new ButtonWidget(this, "Predictive.Button6", "6 mno" , 0, kBut6Cmd); + new ButtonWidget(this, "Predictive.Button7", "7 pqrs" , 0, kBut7Cmd); + new ButtonWidget(this, "Predictive.Button8", "8 tuv" , 0, kBut8Cmd); + new ButtonWidget(this, "Predictive.Button9", "9 wxyz" , 0, kBut9Cmd); new ButtonWidget(this, "Predictive.Button0", "0" , 0, kBut0Cmd); // I18N: You must leave "#" as is, only word 'next' is translatable - new ButtonWidget(this, "Predictive.Next" , _("# next") , 0, kNextCmd); - _addBtn = new ButtonWidget(this, "Predictive.Add", _("add") , 0, kAddCmd); + new ButtonWidget(this, "Predictive.Next" , _("# next"), 0, kNextCmd); + _addBtn = new ButtonWidget(this, "Predictive.Add", _("add"), 0, kAddCmd); _addBtn->setEnabled(false); #ifndef DISABLE_FANCY_THEMES @@ -93,7 +93,7 @@ PredictiveDialog::PredictiveDialog() : Dialog("Predictive") { ((PicButtonWidget *)_delbtn)->useThemeTransparency(true); ((PicButtonWidget *)_delbtn)->setGfx(g_gui.theme()->getImageSurface(ThemeEngine::kImageDelbtn)); #endif - _delbtn = new ButtonWidget(this, "Predictive.Delete" , _("<") , 0, kDelCmd); + _delbtn = new ButtonWidget(this, "Predictive.Delete" , _("<"), 0, kDelCmd); // I18N: Pre means 'Predictive', leave '*' as is _modebutton = new ButtonWidget(this, "Predictive.Pre", _("* Pre"), 0, kModeCmd); _edittext = new EditTextWidget(this, "Predictive.Word", _search, 0, 0, 0); @@ -114,7 +114,7 @@ PredictiveDialog::PredictiveDialog() : Dialog("Predictive") { _predictiveDict.dictLine = NULL; _predictiveDict.dictText = NULL; _predictiveDict.dictLineCount = 0; - + if (!_predictiveDict.dictText) { loadAllDictionary(_predictiveDict); if (!_predictiveDict.dictText) @@ -144,7 +144,7 @@ PredictiveDialog::PredictiveDialog() : Dialog("Predictive") { _currentWord.clear(); _wordNumber = 0; _numMatchingWords = 0; - + _lastbutton = kNoAct; _mode = kModePre; @@ -310,7 +310,7 @@ void PredictiveDialog::handleKeyDown(Common::KeyState state) { } } -void PredictiveDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { +void PredictiveDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { ButtonId act = kNoAct; _navigationwithkeys = false; @@ -376,24 +376,30 @@ void PredictiveDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 d void PredictiveDialog::processBtnActive(ButtonId button) { uint8 x; - const char *buttonStr[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "0" }; + const char *buttonStr[] = { + "1", "2", "3", + "4", "5", "6", + "7", "8", "9", + "0" + }; + const char *buttons[] = { - "'-.&", "abc", "def", - "ghi", "jkl", "mno", - "pqrs", "tuv", "wxyz", - "next", "add", - "<", - "Cancel", "OK", - "Pre", "(0) ", NULL + "'-.&", "abc", "def", + "ghi", "jkl", "mno", + "pqrs", "tuv", "wxyz", + "next", "add", + "<", + "Cancel", "OK", + "Pre", "(0) ", NULL }; if (_mode == kModeAbc) { - if (button >= kBtn1Act && button <= kBtn9Act ) { + if (button >= kBtn1Act && button <= kBtn9Act) { if (!_lastTime) _lastTime = g_system->getMillis(); if (_lastPressBtn == button) { _curTime = g_system->getMillis(); - if((_curTime - _lastTime) < kRepeatDelay) { + if ((_curTime - _lastTime) < kRepeatDelay) { button = kNextAct; _lastTime = _curTime; } else { @@ -429,7 +435,7 @@ void PredictiveDialog::processBtnActive(ButtonId button) { if (_currentCode.size()) { _repeatcount[_currentCode.size() - 1] = 0; _currentCode.deleteLastChar(); - if(_currentCode == Common::String("")) + if (_currentCode == Common::String("")) _currentWord.clear(); } else { if (_prefix.size()) @@ -471,20 +477,20 @@ void PredictiveDialog::processBtnActive(ButtonId button) { char *tok = strtok(tmp, " "); for (uint8 i = 0; i <= _wordNumber; i++) tok = strtok(NULL, " "); - _currentWord = Common::String(tok, _currentCode.size()); - } - } else if (_mode == kModeAbc) { - x = _currentCode.size(); - if (x) { - if (_currentCode.lastChar() == '1' || _currentCode.lastChar() == '7' || _currentCode.lastChar() == '9') - _repeatcount[x - 1] = (_repeatcount[x - 1] + 1) % 4; - else + _currentWord = Common::String(tok, _currentCode.size()); + } + } else if (_mode == kModeAbc) { + x = _currentCode.size(); + if (x) { + if (_currentCode.lastChar() == '1' || _currentCode.lastChar() == '7' || _currentCode.lastChar() == '9') + _repeatcount[x - 1] = (_repeatcount[x - 1] + 1) % 4; + else _repeatcount[x - 1] = (_repeatcount[x - 1] + 1) % 3; - if (_currentCode.lastChar() >= '1') - _currentWord.setChar(buttons[_currentCode[x - 1] - '1'][_repeatcount[x - 1]], x-1); - } + if (_currentCode.lastChar() >= '1') + _currentWord.setChar(buttons[_currentCode[x - 1] - '1'][_repeatcount[x - 1]], x - 1); } + } } else if (button == kAddAct) { // add if (_mode == kModeAbc) addWordToDict(); @@ -494,17 +500,22 @@ void PredictiveDialog::processBtnActive(ButtonId button) { // bring MRU word at the top of the list when ok'ed out of the dialog if (_mode == kModePre && _unitedDict.dictActLine && _numMatchingWords > 1 && _wordNumber != 0) bringWordtoTop(_unitedDict.dictActLine, _wordNumber); - + goto press; } else if (button == kModeAct) { // Mode _mode++; _addBtn->setEnabled(false); - if (_mode > kModeAbc) { - _mode = kModePre; - // I18N: Pre means 'Predictive', leave '*' as is - _modebutton->setLabel("* Pre"); - // I18N: 'Num' means Numbers, 'Abc' means Latin alphabet input - } else (_mode == kModeNum) ? _modebutton->setLabel("* Num") : (_modebutton->setLabel("* Abc"), _addBtn->setEnabled(true)); + if (_mode > kModeAbc) { + _mode = kModePre; + // I18N: Pre means 'Predictive', leave '*' as is + _modebutton->setLabel("* Pre"); + // I18N: 'Num' means Numbers, 'Abc' means Latin alphabet input + } else if (_mode == kModeNum) { + _modebutton->setLabel("* Num"); + } else { + _modebutton->setLabel("* Abc"); + _addBtn->setEnabled(true); + } // truncate current input at mode change strncpy(_temp, _currentWord.c_str(), _currentCode.size()); @@ -513,7 +524,7 @@ void PredictiveDialog::processBtnActive(ButtonId button) { _currentCode.clear(); _currentWord.clear(); memset(_repeatcount, 0, sizeof(_repeatcount)); - + _lastTime = 0; _lastPressBtn = kNoAct; _curTime = 0; @@ -525,14 +536,16 @@ void PredictiveDialog::processBtnActive(ButtonId button) { press: pressEditText(); - if (button == kOkAct) close(); + if (button == kOkAct) + close(); } void PredictiveDialog::handleTickle() { - if (!_lastTime) + if (!_lastTime) { if ((_curTime - _lastTime) > kRepeatDelay) { _lastTime = 0; } + } } void PredictiveDialog::mergeDicts() { @@ -569,7 +582,7 @@ void PredictiveDialog::mergeDicts() { } uint8 PredictiveDialog::countWordsInString(char *str) { - // Count the number of (space separated) words in the given string. + // Count the number of (space separated) words in the given string. char *ptr; if (!str) @@ -614,7 +627,7 @@ void PredictiveDialog::bringWordtoTop(char *str, int wordnum) { Common::String tmp; for (uint8 i = 0; i < words.size(); i++) - tmp += words[i] + " "; + tmp += words[i] + " "; tmp.deleteLastChar(); memcpy(str, tmp.c_str(), strlen(str)); } @@ -686,7 +699,7 @@ bool PredictiveDialog::searchWord(char *where, const String &whatCode) { char *newPtr; bool is = false; - while((newPtr = strchr(ptr, ' '))) { + while ((newPtr = strchr(ptr, ' '))) { if (0 == strncmp(ptr, _currentWord.c_str(), newPtr - ptr)) { is = true; break; @@ -733,22 +746,22 @@ void PredictiveDialog::addWord(Dict &dict, const String &word, const String &cod } } else { // if we didn't find the code, we need to INSERT new line with code and word if (dict.nameDict == "user_dictionary") { - // if we must INSERT new line(code and word) to user_dictionary, we need to + // if we must INSERT new line(code and word) to user_dictionary, we need to // check if there is a line that we want to INSERT in predictive dictionay int predictLine = binarySearch(_predictiveDict.dictLine, tmpCode, _predictiveDict.dictLineCount); - if (predictLine >= 0) { + if (predictLine >= 0) { if (searchWord(_predictiveDict.dictLine[predictLine], tmpCode)) { // if code and word is in predictive dictionary, we need to copy // this line to user dictionary int len = (predictLine == _predictiveDict.dictLineCount - 1) ? &_predictiveDict.dictText[_predictiveDict.dictTextSize] - _predictiveDict.dictLine[predictLine] : - _predictiveDict.dictLine[predictLine + 1] - _predictiveDict.dictLine[predictLine]; + _predictiveDict.dictLine[predictLine + 1] - _predictiveDict.dictLine[predictLine]; newLine = (char *)malloc(len); strncpy(newLine, _predictiveDict.dictLine[predictLine], len); } else { // if there is no word in predictive dictionary, we need to copy to // user dictionary mathed line + new word. int len = (predictLine == _predictiveDict.dictLineCount - 1) ? &_predictiveDict.dictText[_predictiveDict.dictTextSize] - _predictiveDict.dictLine[predictLine] : - _predictiveDict.dictLine[predictLine + 1] - _predictiveDict.dictLine[predictLine]; + _predictiveDict.dictLine[predictLine + 1] - _predictiveDict.dictLine[predictLine]; newLine = (char *)malloc(len + word.size() + 1); char *ptr = newLine; strncpy(ptr, _predictiveDict.dictLine[predictLine], len); @@ -796,7 +809,7 @@ void PredictiveDialog::addWord(Dict &dict, const String &word, const String &cod newDictLine[k++] = dict.dictLine[i]; } } - if (!inserted) + if (!inserted) newDictLine[k] = newLine; _memoryList[_numMemory++] = newLine; @@ -823,7 +836,7 @@ void PredictiveDialog::addWord(Dict &dict, const String &word, const String &cod void PredictiveDialog::addWordToDict() { if (_numMemory < kMaxWord) { addWord(_unitedDict, _currentWord, _currentCode); - addWord(_userDict, _currentWord, _currentCode); + addWord(_userDict, _currentWord, _currentCode); } else { warning("Predictive Dialog: You cannot add word to user dictionary..."); } @@ -845,7 +858,7 @@ void PredictiveDialog::loadDictionary(Common::SeekableReadStream *in, Dict &dict in->read(dict.dictText, dict.dictTextSize); dict.dictText[dict.dictTextSize] = 0; uint32 time2 = g_system->getMillis(); - debug("Predictive Dialog: Time to read %s: %d bytes, %d ms", ConfMan.get(dict.nameDict).c_str(), dict.dictTextSize, time2-time1); + debug("Predictive Dialog: Time to read %s: %d bytes, %d ms", ConfMan.get(dict.nameDict).c_str(), dict.dictTextSize, time2 - time1); delete in; char *ptr = dict.dictText; @@ -887,7 +900,7 @@ void PredictiveDialog::loadDictionary(Common::SeekableReadStream *in, Dict &dict #endif uint32 time3 = g_system->getMillis(); - debug("Predictive Dialog: Time to parse %s: %d, total: %d", ConfMan.get(dict.nameDict).c_str(), time3-time2, time3-time1); + debug("Predictive Dialog: Time to parse %s: %d, total: %d", ConfMan.get(dict.nameDict).c_str(), time3 - time2, time3 - time1); } void PredictiveDialog::loadAllDictionary(Dict &dict) { -- cgit v1.2.3 From f3a19ea6aa39c66653fb0b012506c5aa7e091c71 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Thu, 29 Mar 2012 01:50:52 +0200 Subject: GUI: Get rid of "using namespace Common" in predictivedialog.cpp. --- gui/predictivedialog.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'gui/predictivedialog.cpp') diff --git a/gui/predictivedialog.cpp b/gui/predictivedialog.cpp index 4d640c7104..aa2a358fa3 100644 --- a/gui/predictivedialog.cpp +++ b/gui/predictivedialog.cpp @@ -38,8 +38,6 @@ #include "backends/platform/ds/arm9/source/wordcompletion.h" #endif -using namespace Common; - namespace GUI { enum { @@ -907,7 +905,7 @@ void PredictiveDialog::loadAllDictionary(Dict &dict) { ConfMan.registerDefault(dict.nameDict, dict.fnameDict); if (dict.nameDict == "predictive_dictionary") { - Common::File *inFile = new File(); + Common::File *inFile = new Common::File(); if (!inFile->open(ConfMan.get(dict.nameDict))) { warning("Predictive Dialog: cannot read file: %s", dict.fnameDict.c_str()); return; -- cgit v1.2.3 From 02e77dd7b25c47b10eef57bb59385e43d22b8b87 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Thu, 29 Mar 2012 01:53:09 +0200 Subject: GUI: Don't typedef Common::String in PredictiveDialog code. --- gui/predictivedialog.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'gui/predictivedialog.cpp') diff --git a/gui/predictivedialog.cpp b/gui/predictivedialog.cpp index aa2a358fa3..fd86fb4ac9 100644 --- a/gui/predictivedialog.cpp +++ b/gui/predictivedialog.cpp @@ -630,7 +630,7 @@ void PredictiveDialog::bringWordtoTop(char *str, int wordnum) { memcpy(str, tmp.c_str(), strlen(str)); } -int PredictiveDialog::binarySearch(char **dictLine, const String &code, int dictLineCount) { +int PredictiveDialog::binarySearch(char **dictLine, const Common::String &code, int dictLineCount) { int hi = dictLineCount - 1; int lo = 0; int line = 0; @@ -691,7 +691,7 @@ bool PredictiveDialog::matchWord() { } } -bool PredictiveDialog::searchWord(char *where, const String &whatCode) { +bool PredictiveDialog::searchWord(char *where, const Common::String &whatCode) { char *ptr = where; ptr += whatCode.size(); @@ -712,7 +712,7 @@ bool PredictiveDialog::searchWord(char *where, const String &whatCode) { return is; } -void PredictiveDialog::addWord(Dict &dict, const String &word, const String &code) { +void PredictiveDialog::addWord(Dict &dict, const Common::String &word, const Common::String &code) { char *newLine; Common::String tmpCode = code + ' '; int line = binarySearch(dict.dictLine, tmpCode, dict.dictLineCount); -- cgit v1.2.3 From 988c3fd6c5d77b711c449a79693ba9981289e721 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Thu, 29 Mar 2012 02:00:25 +0200 Subject: GUI: Make some static strings in PredictiveDialog static + const. --- gui/predictivedialog.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'gui/predictivedialog.cpp') diff --git a/gui/predictivedialog.cpp b/gui/predictivedialog.cpp index fd86fb4ac9..6f52f0a1d4 100644 --- a/gui/predictivedialog.cpp +++ b/gui/predictivedialog.cpp @@ -374,14 +374,14 @@ void PredictiveDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 d void PredictiveDialog::processBtnActive(ButtonId button) { uint8 x; - const char *buttonStr[] = { + static const char *const buttonStr[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "0" }; - const char *buttons[] = { + static const char *const buttons[] = { "'-.&", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz", -- cgit v1.2.3 From 7414544121bacef05eb6c4e9a1cf63f225db84be Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Thu, 29 Mar 2012 02:05:45 +0200 Subject: GUI: Constify some parameters/methods in PredictiveDialog. --- gui/predictivedialog.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'gui/predictivedialog.cpp') diff --git a/gui/predictivedialog.cpp b/gui/predictivedialog.cpp index 6f52f0a1d4..7d5181c9e2 100644 --- a/gui/predictivedialog.cpp +++ b/gui/predictivedialog.cpp @@ -579,9 +579,9 @@ void PredictiveDialog::mergeDicts() { } } -uint8 PredictiveDialog::countWordsInString(char *str) { +uint8 PredictiveDialog::countWordsInString(const char *const str) { // Count the number of (space separated) words in the given string. - char *ptr; + const char *ptr; if (!str) return 0; @@ -630,7 +630,7 @@ void PredictiveDialog::bringWordtoTop(char *str, int wordnum) { memcpy(str, tmp.c_str(), strlen(str)); } -int PredictiveDialog::binarySearch(char **dictLine, const Common::String &code, int dictLineCount) { +int PredictiveDialog::binarySearch(const char *const *const dictLine, const Common::String &code, const int dictLineCount) { int hi = dictLineCount - 1; int lo = 0; int line = 0; @@ -691,11 +691,11 @@ bool PredictiveDialog::matchWord() { } } -bool PredictiveDialog::searchWord(char *where, const Common::String &whatCode) { - char *ptr = where; +bool PredictiveDialog::searchWord(const char *const where, const Common::String &whatCode) { + const char *ptr = where; ptr += whatCode.size(); - char *newPtr; + const char *newPtr; bool is = false; while ((newPtr = strchr(ptr, ' '))) { if (0 == strncmp(ptr, _currentWord.c_str(), newPtr - ptr)) { -- cgit v1.2.3 From 6ed2d15c44ce7ccea005e02f0a8744b2fa9cc807 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Thu, 29 Mar 2012 02:07:02 +0200 Subject: GUI: Take advantage of Common::String::empty. --- gui/predictivedialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gui/predictivedialog.cpp') diff --git a/gui/predictivedialog.cpp b/gui/predictivedialog.cpp index 7d5181c9e2..c5c4331ab3 100644 --- a/gui/predictivedialog.cpp +++ b/gui/predictivedialog.cpp @@ -433,7 +433,7 @@ void PredictiveDialog::processBtnActive(ButtonId button) { if (_currentCode.size()) { _repeatcount[_currentCode.size() - 1] = 0; _currentCode.deleteLastChar(); - if (_currentCode == Common::String("")) + if (_currentCode.empty()) _currentWord.clear(); } else { if (_prefix.size()) -- cgit v1.2.3 From a7ee1dc42bc288a3748014d9e2c3ec57f61eb079 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Thu, 29 Mar 2012 02:08:09 +0200 Subject: GUI: Remove unnecessary goto in PredictiveDialog code. --- gui/predictivedialog.cpp | 5 ----- 1 file changed, 5 deletions(-) (limited to 'gui/predictivedialog.cpp') diff --git a/gui/predictivedialog.cpp b/gui/predictivedialog.cpp index c5c4331ab3..4ce2a51979 100644 --- a/gui/predictivedialog.cpp +++ b/gui/predictivedialog.cpp @@ -498,8 +498,6 @@ void PredictiveDialog::processBtnActive(ButtonId button) { // bring MRU word at the top of the list when ok'ed out of the dialog if (_mode == kModePre && _unitedDict.dictActLine && _numMatchingWords > 1 && _wordNumber != 0) bringWordtoTop(_unitedDict.dictActLine, _wordNumber); - - goto press; } else if (button == kModeAct) { // Mode _mode++; _addBtn->setEnabled(false); @@ -526,12 +524,9 @@ void PredictiveDialog::processBtnActive(ButtonId button) { _lastTime = 0; _lastPressBtn = kNoAct; _curTime = 0; - } else { - goto press; } } -press: pressEditText(); if (button == kOkAct) -- cgit v1.2.3 From 388e04bb6dcdf33ee26c2efe5163642fa17189c0 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Thu, 29 Mar 2012 02:12:32 +0200 Subject: GUI: Add TODO/FIXME to PredictiveDialog::handleTickle. --- gui/predictivedialog.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'gui/predictivedialog.cpp') diff --git a/gui/predictivedialog.cpp b/gui/predictivedialog.cpp index 4ce2a51979..238a832b10 100644 --- a/gui/predictivedialog.cpp +++ b/gui/predictivedialog.cpp @@ -534,6 +534,10 @@ void PredictiveDialog::processBtnActive(ButtonId button) { } void PredictiveDialog::handleTickle() { + // TODO/FIXME: This code does not seem to make any sense. It is only + // triggered when _lastTime is zero and sets _lastTime to zero again + // under some condition. This should really be a nop. Probably this + // code intends to check "_lastTime" instead of "!_lastTime". if (!_lastTime) { if ((_curTime - _lastTime) > kRepeatDelay) { _lastTime = 0; -- cgit v1.2.3 From b8065a4392c2be51983d68f5631814a572d2c975 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Thu, 29 Mar 2012 02:23:44 +0200 Subject: GUI: Move "I18N" tagged comment to matching strings. The strings are not marked for translation, so I am not sure why the comments are tagged with I18N though. --- gui/predictivedialog.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'gui/predictivedialog.cpp') diff --git a/gui/predictivedialog.cpp b/gui/predictivedialog.cpp index 238a832b10..9cd18b81ba 100644 --- a/gui/predictivedialog.cpp +++ b/gui/predictivedialog.cpp @@ -505,10 +505,11 @@ void PredictiveDialog::processBtnActive(ButtonId button) { _mode = kModePre; // I18N: Pre means 'Predictive', leave '*' as is _modebutton->setLabel("* Pre"); - // I18N: 'Num' means Numbers, 'Abc' means Latin alphabet input } else if (_mode == kModeNum) { + // I18N: 'Num' means Numbers _modebutton->setLabel("* Num"); } else { + // I18N: 'Abc' means Latin alphabet input _modebutton->setLabel("* Abc"); _addBtn->setEnabled(true); } -- cgit v1.2.3 From 24a45beceb1d9228168fc0911b90da3bd45a923e Mon Sep 17 00:00:00 2001 From: Oleksiy Kurochko Date: Thu, 3 May 2012 19:32:34 +0300 Subject: GUI: Use pressed state in predictive dialog in keyboard mode. This adds more visual feedback to the user. --- gui/predictivedialog.cpp | 288 +++++++++++++++++++++++++++++------------------ 1 file changed, 177 insertions(+), 111 deletions(-) (limited to 'gui/predictivedialog.cpp') diff --git a/gui/predictivedialog.cpp b/gui/predictivedialog.cpp index 9cd18b81ba..b827d49416 100644 --- a/gui/predictivedialog.cpp +++ b/gui/predictivedialog.cpp @@ -69,31 +69,33 @@ enum { PredictiveDialog::PredictiveDialog() : Dialog("Predictive") { new StaticTextWidget(this, "Predictive.Headline", "Enter Text"); - new ButtonWidget(this, "Predictive.Cancel" , _("Cancel"), 0, kCancelCmd); - new ButtonWidget(this, "Predictive.OK" , _("Ok") , 0, kOkCmd); - new ButtonWidget(this, "Predictive.Button1", "1 `-.&" , 0, kBut1Cmd); - new ButtonWidget(this, "Predictive.Button2", "2 abc" , 0, kBut2Cmd); - new ButtonWidget(this, "Predictive.Button3", "3 def" , 0, kBut3Cmd); - new ButtonWidget(this, "Predictive.Button4", "4 ghi" , 0, kBut4Cmd); - new ButtonWidget(this, "Predictive.Button5", "5 jkl" , 0, kBut5Cmd); - new ButtonWidget(this, "Predictive.Button6", "6 mno" , 0, kBut6Cmd); - new ButtonWidget(this, "Predictive.Button7", "7 pqrs" , 0, kBut7Cmd); - new ButtonWidget(this, "Predictive.Button8", "8 tuv" , 0, kBut8Cmd); - new ButtonWidget(this, "Predictive.Button9", "9 wxyz" , 0, kBut9Cmd); - new ButtonWidget(this, "Predictive.Button0", "0" , 0, kBut0Cmd); - // I18N: You must leave "#" as is, only word 'next' is translatable - new ButtonWidget(this, "Predictive.Next" , _("# next"), 0, kNextCmd); - _addBtn = new ButtonWidget(this, "Predictive.Add", _("add"), 0, kAddCmd); - _addBtn->setEnabled(false); - -#ifndef DISABLE_FANCY_THEMES - _delbtn = new PicButtonWidget(this, "Predictive.Delete", _("Delete char"), kDelCmd); - ((PicButtonWidget *)_delbtn)->useThemeTransparency(true); - ((PicButtonWidget *)_delbtn)->setGfx(g_gui.theme()->getImageSurface(ThemeEngine::kImageDelbtn)); -#endif - _delbtn = new ButtonWidget(this, "Predictive.Delete" , _("<"), 0, kDelCmd); - // I18N: Pre means 'Predictive', leave '*' as is - _modebutton = new ButtonWidget(this, "Predictive.Pre", _("* Pre"), 0, kModeCmd); + _btns = (ButtonWidget **)calloc(1, sizeof(ButtonWidget *) * 16); + + _btns[kCancelAct] = new ButtonWidget(this, "Predictive.Cancel", _("Cancel") , 0, kCancelCmd); + _btns[kOkAct] = new ButtonWidget(this, "Predictive.OK", _("Ok") , 0, kOkCmd); + _btns[kBtn1Act] = new ButtonWidget(this, "Predictive.Button1", "1 `-.&" , 0, kBut1Cmd); + _btns[kBtn2Act] = new ButtonWidget(this, "Predictive.Button2", "2 abc" , 0, kBut2Cmd); + _btns[kBtn3Act] = new ButtonWidget(this, "Predictive.Button3", "3 def" , 0, kBut3Cmd); + _btns[kBtn4Act] = new ButtonWidget(this, "Predictive.Button4", "4 ghi" , 0, kBut4Cmd); + _btns[kBtn5Act] = new ButtonWidget(this, "Predictive.Button5", "5 jkl" , 0, kBut5Cmd); + _btns[kBtn6Act] = new ButtonWidget(this, "Predictive.Button6", "6 mno" , 0, kBut6Cmd); + _btns[kBtn7Act] = new ButtonWidget(this, "Predictive.Button7", "7 pqrs" , 0, kBut7Cmd); + _btns[kBtn8Act] = new ButtonWidget(this, "Predictive.Button8", "8 tuv" , 0, kBut8Cmd); + _btns[kBtn9Act] = new ButtonWidget(this, "Predictive.Button9", "9 wxyz" , 0, kBut9Cmd); + _btns[kBtn0Act] = new ButtonWidget(this, "Predictive.Button0", "0" , 0, kBut0Cmd); + // I18N: You must leave "#" as is, only word 'next' is translatable + _btns[kNextAct] = new ButtonWidget(this, "Predictive.Next", _("# next") , 0, kNextCmd); + _btns[kAddAct] = new ButtonWidget(this, "Predictive.Add", _("add") , 0, kAddCmd); + _btns[kAddAct]->setEnabled(false); + + #ifndef DISABLE_FANCY_THEMES + _btns[kDelAct] = new PicButtonWidget(this, "Predictive.Delete", _("Delete char"), kDelCmd); + ((PicButtonWidget *)_btns[kDelAct])->useThemeTransparency(true); + ((PicButtonWidget *)_btns[kDelAct])->setGfx(g_gui.theme()->getImageSurface(ThemeEngine::kImageDelbtn)); + #endif + _btns[kDelAct] = new ButtonWidget(this, "Predictive.Delete" , _("<") , 0, kDelCmd); + // I18N: Pre means 'Predictive', leave '*' as is + _btns[kModeAct] = new ButtonWidget(this, "Predictive.Pre", _("* Pre"), 0, kModeCmd); _edittext = new EditTextWidget(this, "Predictive.Word", _search, 0, 0, 0); _userDictHasChanged = false; @@ -164,6 +166,8 @@ PredictiveDialog::~PredictiveDialog() { free(_userDict.dictLine); free(_predictiveDict.dictLine); free(_unitedDict.dictLine); + + free(_btns); } void PredictiveDialog::saveUserDictToFile() { @@ -182,11 +186,23 @@ void PredictiveDialog::saveUserDictToFile() { } } +void PredictiveDialog::handleKeyUp(Common::KeyState state) { + if (_currBtn != kNoAct && !_needRefresh) { + _btns[_currBtn]->startAnimatePressedState(); + processBtnActive(_currBtn); + } +} + void PredictiveDialog::handleKeyDown(Common::KeyState state) { - ButtonId act = kNoAct; + _currBtn = kNoAct; + _needRefresh = false; if (getFocusWidget() == _edittext) { - setFocusWidget(_addBtn); + setFocusWidget(_btns[kAddAct]); + } + + if (_lastbutton == kNoAct) { + _lastbutton = kBtn5Act; } switch (state.keycode) { @@ -197,96 +213,126 @@ void PredictiveDialog::handleKeyDown(Common::KeyState state) { case Common::KEYCODE_LEFT: _navigationwithkeys = true; if (_lastbutton == kBtn1Act || _lastbutton == kBtn4Act || _lastbutton == kBtn7Act) - act = ButtonId(_lastbutton + 2); + _currBtn = ButtonId(_lastbutton + 2); + else if (_lastbutton == kDelAct) + _currBtn = kBtn1Act; + else if (_lastbutton == kModeAct) + _currBtn = kNextAct; else if (_lastbutton == kNextAct) - act = kBtn0Act; - else if (_lastbutton == kDelAct) - act = kDelAct; + _currBtn = kBtn0Act; + else if (_lastbutton == kAddAct) + _currBtn = kOkAct; else if (_lastbutton == kCancelAct) - act = kOkAct; - else if (_lastbutton == kModeAct) - act = kAddAct; + _currBtn = kAddAct; else - act = ButtonId(_lastbutton - 1); - _lastbutton = act; - //needRefresh = true; + _currBtn = ButtonId(_lastbutton - 1); + + + if (_mode != kModeAbc && _lastbutton == kCancelAct) + _currBtn = kOkAct; + + _needRefresh = true; break; case Common::KEYCODE_RIGHT: _navigationwithkeys = true; - if (_lastbutton == kBtn3Act || _lastbutton == kBtn6Act || _lastbutton == kBtn9Act) - act = ButtonId(_lastbutton - 2); + if (_lastbutton == kBtn3Act || _lastbutton == kBtn6Act || _lastbutton == kBtn9Act || _lastbutton == kOkAct) + _currBtn = ButtonId(_lastbutton - 2); + else if (_lastbutton == kDelAct) + _currBtn = kBtn3Act; + else if (_lastbutton == kBtn0Act) + _currBtn = kNextAct; + else if (_lastbutton == kNextAct) + _currBtn = kModeAct; else if (_lastbutton == kAddAct) - act = kModeAct; - else if (_lastbutton == kDelAct) - act = kDelAct; + _currBtn = kCancelAct; else if (_lastbutton == kOkAct) - act = kCancelAct; - else if (_lastbutton == kBtn0Act) - act = kNextAct; + _currBtn = kAddAct; else - act = ButtonId(_lastbutton + 1); - _lastbutton = act; - //needRefresh = true; + _currBtn = ButtonId(_lastbutton + 1); + + if (_mode != kModeAbc && _lastbutton == kOkAct) + _currBtn = kCancelAct; + _needRefresh = true; break; case Common::KEYCODE_UP: _navigationwithkeys = true; if (_lastbutton <= kBtn3Act) - act = kDelAct; - else if (_lastbutton == kNextAct || _lastbutton == kAddAct) - act = ButtonId(_lastbutton - 2); + _currBtn = kDelAct; else if (_lastbutton == kDelAct) - act = kOkAct; - else if (_lastbutton == kModeAct) - act = kBtn9Act; + _currBtn = kOkAct; + else if (_lastbutton == kModeAct) + _currBtn = kBtn7Act; else if (_lastbutton == kBtn0Act) - act = kBtn7Act; + _currBtn = kBtn8Act; + else if (_lastbutton == kNextAct) + _currBtn = kBtn9Act; + else if (_lastbutton == kAddAct) + _currBtn = kModeAct; + else if (_lastbutton == kCancelAct) + _currBtn = kBtn0Act; + else if (_lastbutton == kOkAct) + _currBtn = kNextAct; else - act = ButtonId(_lastbutton - 3); - _lastbutton = act; - //needRefresh = true; + _currBtn = ButtonId(_lastbutton - 3); + _needRefresh = true; break; case Common::KEYCODE_DOWN: _navigationwithkeys = true; - if (_lastbutton == kBtn7Act) - act = kBtn0Act; - else if (_lastbutton == kBtn8Act || _lastbutton == kBtn9Act) - act = ButtonId(_lastbutton + 2); - else if (_lastbutton == kDelAct) - act = kBtn1Act; - else if (_lastbutton == kCancelAct || _lastbutton == kOkAct) - act = kDelAct; - else if (_lastbutton == kModeAct || _lastbutton == kBtn0Act) - act = ButtonId(_lastbutton - 2); + if (_lastbutton == kDelAct) + _currBtn = kBtn3Act; + else if (_lastbutton == kBtn7Act) + _currBtn = kModeAct; + else if (_lastbutton == kBtn8Act) + _currBtn = kBtn0Act; + else if (_lastbutton == kBtn9Act) + _currBtn = kNextAct; + else if (_lastbutton == kModeAct) + _currBtn = kAddAct; + else if (_lastbutton == kBtn0Act) + _currBtn = kCancelAct; + else if (_lastbutton == kNextAct) + _currBtn = kOkAct; + else if (_lastbutton == kAddAct || _lastbutton == kCancelAct || _lastbutton == kOkAct) + _currBtn = kDelAct; else - act = ButtonId(_lastbutton + 3); - _lastbutton = act; - //needRefresh = true; + _currBtn = ButtonId(_lastbutton + 3); + + if (_mode != kModeAbc && _lastbutton == kModeAct) + _currBtn = kCancelAct; + + _needRefresh = true; break; case Common::KEYCODE_KP_ENTER: + case Common::KEYCODE_RETURN: + if (state.flags & Common::KBD_CTRL) { + _currBtn = kOkAct; + break; + } if (_navigationwithkeys) { // when the user has utilized arrow key navigation, - // interpret enter as 'click' on the act button - act = _lastbutton; + // interpret enter as 'click' on the _currBtn button + _currBtn = _lastbutton; + _needRefresh = false; } else { // else it is a shortcut for 'Ok' - act = kOkAct; + _currBtn = kOkAct; } break; case Common::KEYCODE_KP_PLUS: - act = kAddAct; + _currBtn = kAddAct; break; case Common::KEYCODE_BACKSPACE: case Common::KEYCODE_KP_MINUS: - act = kDelAct; + _currBtn = kDelAct; break; case Common::KEYCODE_KP_DIVIDE: - act = kNextAct; + _currBtn = kNextAct; break; case Common::KEYCODE_KP_MULTIPLY: - act = kModeAct; + _currBtn = kModeAct; break; case Common::KEYCODE_KP0: - act = kBtn0Act; + _currBtn = kBtn0Act; break; case Common::KEYCODE_KP1: case Common::KEYCODE_KP2: @@ -297,78 +343,93 @@ void PredictiveDialog::handleKeyDown(Common::KeyState state) { case Common::KEYCODE_KP7: case Common::KEYCODE_KP8: case Common::KEYCODE_KP9: - act = ButtonId(state.keycode - Common::KEYCODE_KP1); + _currBtn = ButtonId(state.keycode - Common::KEYCODE_KP1); break; default: Dialog::handleKeyDown(state); } - if (act != kNoAct) { - processBtnActive(act); + if (_lastbutton != _currBtn) + _btns[_lastbutton]->stopAnimatePressedState(); + + if (_currBtn != kNoAct && !_needRefresh) + _btns[_currBtn]->setPressedState(); + else + updateHighLightedButton(_currBtn); +} + +void PredictiveDialog::updateHighLightedButton(ButtonId act) { + if (_currBtn != kNoAct) { + _btns[_lastbutton]->setHighLighted(false); + _lastbutton = act; + _btns[_lastbutton]->setHighLighted(true); } } void PredictiveDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { - ButtonId act = kNoAct; + _currBtn = kNoAct; _navigationwithkeys = false; + if (_lastbutton != kNoAct) + _btns[_lastbutton]->setHighLighted(false); + switch (cmd) { case kDelCmd: - act = kDelAct; + _currBtn = kDelAct; break; case kNextCmd: - act = kNextAct; + _currBtn = kNextAct; break; case kAddCmd: - act = kAddAct; + _currBtn = kAddAct; break; case kModeCmd: - act = kModeAct; + _currBtn = kModeAct; break; case kBut1Cmd: - act = kBtn1Act; + _currBtn = kBtn1Act; break; case kBut2Cmd: - act = kBtn2Act; + _currBtn = kBtn2Act; break; case kBut3Cmd: - act = kBtn3Act; + _currBtn = kBtn3Act; break; case kBut4Cmd: - act = kBtn4Act; + _currBtn = kBtn4Act; break; case kBut5Cmd: - act = kBtn5Act; + _currBtn = kBtn5Act; break; case kBut6Cmd: - act = kBtn6Act; + _currBtn = kBtn6Act; break; case kBut7Cmd: - act = kBtn7Act; + _currBtn = kBtn7Act; break; case kBut8Cmd: - act = kBtn8Act; + _currBtn = kBtn8Act; break; case kBut9Cmd: - act = kBtn9Act; + _currBtn = kBtn9Act; break; case kBut0Cmd: - act = kBtn0Act; + _currBtn = kBtn0Act; break; case kCancelCmd: saveUserDictToFile(); close(); return; case kOkCmd: - act = kOkAct; + _currBtn = kOkAct; break; default: Dialog::handleCommand(sender, cmd, data); } - if (act != kNoAct) { - processBtnActive(act); + if (_currBtn != kNoAct) { + processBtnActive(_currBtn); } } @@ -500,18 +561,18 @@ void PredictiveDialog::processBtnActive(ButtonId button) { bringWordtoTop(_unitedDict.dictActLine, _wordNumber); } else if (button == kModeAct) { // Mode _mode++; - _addBtn->setEnabled(false); + _btns[kAddAct]->setEnabled(false); if (_mode > kModeAbc) { _mode = kModePre; // I18N: Pre means 'Predictive', leave '*' as is - _modebutton->setLabel("* Pre"); + _btns[kModeAct]->setLabel("* Pre"); } else if (_mode == kModeNum) { // I18N: 'Num' means Numbers - _modebutton->setLabel("* Num"); + _btns[kModeAct]->setLabel("* Num"); } else { // I18N: 'Abc' means Latin alphabet input - _modebutton->setLabel("* Abc"); - _addBtn->setEnabled(true); + _btns[kModeAct]->setLabel("* Abc"); + _btns[kAddAct]->setEnabled(true); } // truncate current input at mode change @@ -532,18 +593,23 @@ void PredictiveDialog::processBtnActive(ButtonId button) { if (button == kOkAct) close(); + + if (button == kCancelAct) { + saveUserDictToFile(); + close(); + } } void PredictiveDialog::handleTickle() { - // TODO/FIXME: This code does not seem to make any sense. It is only - // triggered when _lastTime is zero and sets _lastTime to zero again - // under some condition. This should really be a nop. Probably this - // code intends to check "_lastTime" instead of "!_lastTime". - if (!_lastTime) { + if (_lastTime) { if ((_curTime - _lastTime) > kRepeatDelay) { _lastTime = 0; } } + + if (getTickleWidget()) { + getTickleWidget()->handleTickle(); + } } void PredictiveDialog::mergeDicts() { @@ -664,7 +730,7 @@ bool PredictiveDialog::matchWord() { // The entries in the dictionary consist of a code, a space, and then // a space-separated list of words matching this code. - // To exactly match a code, we therefore match the code plus the trailing + // To ex_currBtnly match a code, we therefore match the code plus the trailing // space in the dictionary. Common::String code = _currentCode + " "; -- cgit v1.2.3 From 89abab97e3124fa25eb4c7d3e8b38501747a8d17 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Wed, 26 Sep 2012 04:17:31 +0200 Subject: JANITORIAL: Remove trailing whitespaces. Powered by: git ls-files "*.cpp" "*.h" "*.m" "*.mm" | xargs sed -i -e 's/[ \t]*$//' --- gui/predictivedialog.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'gui/predictivedialog.cpp') diff --git a/gui/predictivedialog.cpp b/gui/predictivedialog.cpp index b827d49416..ed18847a40 100644 --- a/gui/predictivedialog.cpp +++ b/gui/predictivedialog.cpp @@ -71,7 +71,7 @@ PredictiveDialog::PredictiveDialog() : Dialog("Predictive") { _btns = (ButtonWidget **)calloc(1, sizeof(ButtonWidget *) * 16); - _btns[kCancelAct] = new ButtonWidget(this, "Predictive.Cancel", _("Cancel") , 0, kCancelCmd); + _btns[kCancelAct] = new ButtonWidget(this, "Predictive.Cancel", _("Cancel") , 0, kCancelCmd); _btns[kOkAct] = new ButtonWidget(this, "Predictive.OK", _("Ok") , 0, kOkCmd); _btns[kBtn1Act] = new ButtonWidget(this, "Predictive.Button1", "1 `-.&" , 0, kBut1Cmd); _btns[kBtn2Act] = new ButtonWidget(this, "Predictive.Button2", "2 abc" , 0, kBut2Cmd); @@ -84,10 +84,10 @@ PredictiveDialog::PredictiveDialog() : Dialog("Predictive") { _btns[kBtn9Act] = new ButtonWidget(this, "Predictive.Button9", "9 wxyz" , 0, kBut9Cmd); _btns[kBtn0Act] = new ButtonWidget(this, "Predictive.Button0", "0" , 0, kBut0Cmd); // I18N: You must leave "#" as is, only word 'next' is translatable - _btns[kNextAct] = new ButtonWidget(this, "Predictive.Next", _("# next") , 0, kNextCmd); + _btns[kNextAct] = new ButtonWidget(this, "Predictive.Next", _("# next") , 0, kNextCmd); _btns[kAddAct] = new ButtonWidget(this, "Predictive.Add", _("add") , 0, kAddCmd); _btns[kAddAct]->setEnabled(false); - + #ifndef DISABLE_FANCY_THEMES _btns[kDelAct] = new PicButtonWidget(this, "Predictive.Delete", _("Delete char"), kDelCmd); ((PicButtonWidget *)_btns[kDelAct])->useThemeTransparency(true); @@ -214,7 +214,7 @@ void PredictiveDialog::handleKeyDown(Common::KeyState state) { _navigationwithkeys = true; if (_lastbutton == kBtn1Act || _lastbutton == kBtn4Act || _lastbutton == kBtn7Act) _currBtn = ButtonId(_lastbutton + 2); - else if (_lastbutton == kDelAct) + else if (_lastbutton == kDelAct) _currBtn = kBtn1Act; else if (_lastbutton == kModeAct) _currBtn = kNextAct; @@ -227,7 +227,7 @@ void PredictiveDialog::handleKeyDown(Common::KeyState state) { else _currBtn = ButtonId(_lastbutton - 1); - + if (_mode != kModeAbc && _lastbutton == kCancelAct) _currBtn = kOkAct; @@ -237,7 +237,7 @@ void PredictiveDialog::handleKeyDown(Common::KeyState state) { _navigationwithkeys = true; if (_lastbutton == kBtn3Act || _lastbutton == kBtn6Act || _lastbutton == kBtn9Act || _lastbutton == kOkAct) _currBtn = ButtonId(_lastbutton - 2); - else if (_lastbutton == kDelAct) + else if (_lastbutton == kDelAct) _currBtn = kBtn3Act; else if (_lastbutton == kBtn0Act) _currBtn = kNextAct; @@ -249,7 +249,7 @@ void PredictiveDialog::handleKeyDown(Common::KeyState state) { _currBtn = kAddAct; else _currBtn = ButtonId(_lastbutton + 1); - + if (_mode != kModeAbc && _lastbutton == kOkAct) _currBtn = kCancelAct; _needRefresh = true; @@ -260,7 +260,7 @@ void PredictiveDialog::handleKeyDown(Common::KeyState state) { _currBtn = kDelAct; else if (_lastbutton == kDelAct) _currBtn = kOkAct; - else if (_lastbutton == kModeAct) + else if (_lastbutton == kModeAct) _currBtn = kBtn7Act; else if (_lastbutton == kBtn0Act) _currBtn = kBtn8Act; @@ -286,7 +286,7 @@ void PredictiveDialog::handleKeyDown(Common::KeyState state) { _currBtn = kBtn0Act; else if (_lastbutton == kBtn9Act) _currBtn = kNextAct; - else if (_lastbutton == kModeAct) + else if (_lastbutton == kModeAct) _currBtn = kAddAct; else if (_lastbutton == kBtn0Act) _currBtn = kCancelAct; -- cgit v1.2.3