├── .gitignore ├── .gitmodules ├── LICENSE ├── LicenseHeader ├── README.md ├── config ├── config.conf ├── config.pro ├── js.sqlite ├── keywords.sqlite ├── properties.sqlite ├── py.sqlite ├── qml.sqlite └── sh.sqlite ├── developkbd ├── DevelopHandler.qml ├── develop.conf ├── develop.qml └── developkbd.pro ├── dolphin ├── AccentedCharacterKey.qml ├── BackspaceKey.qml ├── CandidateColumn.qml ├── CandidateDialog.qml ├── CandidateRow.qml ├── CharacterKey.qml ├── Close.qml ├── CommitKey.qml ├── ContextAwareKey.qml ├── CursorKey.qml ├── DeadKey.qml ├── DelegateH.qml ├── DelegateV.qml ├── EnterKey.qml ├── FunctionKey.qml ├── Help.qml ├── HwrInputHandler.qml ├── HwrLayout.qml ├── InputHandler.qml ├── KeyBase.qml ├── KeyboardBase.qml ├── KeyboardGeometry.qml ├── KeyboardLayout.qml ├── KeyboardRow.qml ├── LanguageSelectionCell.qml ├── LanguageSelectionPopup.qml ├── LayoutLoader.qml ├── LayoutRow.qml ├── LayoutSwipe.qml ├── More.qml ├── MultiCharacterKey.qml ├── Multitap.qml ├── NumberKey.qml ├── NumberLayoutLandscape.qml ├── NumberLayoutPortrait.qml ├── PasteButton.qml ├── PasteButtonBase.qml ├── PasteButtonVertical.qml ├── PasteInputHandler.qml ├── PhoneKey.qml ├── PhoneNumberLayoutLandscape.qml ├── PhoneNumberLayoutPortrait.qml ├── Popper.qml ├── PopperCell.qml ├── PreeditTestHandler.qml ├── PreeditView.qml ├── PunctuationKey.qml ├── QuickPick.qml ├── Settings.qml ├── ShiftKey.qml ├── SpacebarKey.qml ├── SpacebarRow.qml ├── SpacebarRowDeadKey.qml ├── SwipeArea.qml ├── SwipeKey.qml ├── SwipeSpacebarRow.qml ├── SymbolKey.qml ├── TabKey.qml ├── TabulatorKey.qml ├── Toolbar.qml ├── TopItem.qml ├── dolphin.pro ├── graphic-keyboard-highlight-top.png ├── keyboard_letter.wav ├── keyboard_option.wav ├── qmldir ├── tab.svg └── touchpointarray.js ├── harbour-tide.desktop ├── harbour-tide.pro ├── kbdsrc ├── database.cpp ├── database.h ├── filewatcher.cpp ├── filewatcher.h ├── kbdsrc.pro ├── qmldir ├── settings.cpp ├── settings.h ├── src.cpp └── src.h ├── roothelper ├── harbour-tide-root.desktop ├── icons │ ├── 108x108 │ │ └── harbour-tide-root.png │ ├── 128x128 │ │ └── harbour-tide-root.png │ ├── 256x256 │ │ └── harbour-tide-root.png │ └── 86x86 │ │ └── harbour-tide-root.png ├── main.cpp └── roothelper.pro └── rpm ├── harbour-tide.changes └── harbour-tide.spec /.gitignore: -------------------------------------------------------------------------------- 1 | *.directory 2 | *.old 3 | # C++ objects and libs 4 | 5 | *.slo 6 | *.lo 7 | *.o 8 | *.a 9 | *.la 10 | *.lai 11 | *.so 12 | *.dll 13 | *.dylib 14 | 15 | # Qt-es 16 | 17 | /.qmake.cache 18 | /.qmake.stash 19 | *.pro.user 20 | *.pro.user.* 21 | *.qbs.user 22 | *.qbs.user.* 23 | *.moc 24 | moc_*.cpp 25 | qrc_*.cpp 26 | ui_*.h 27 | Makefile* 28 | *build-* 29 | 30 | # QtCreator 31 | 32 | *.autosave 33 | 34 | # QtCtreator Qml 35 | *.qmlproject.user 36 | *.qmlproject.user.* 37 | 38 | # QtCtreator CMake 39 | CMakeLists.txt.user* 40 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "tide"] 2 | path = tide 3 | url = git@github.com:eekkelund/tide.git 4 | branch = devel 5 | -------------------------------------------------------------------------------- /LicenseHeader: -------------------------------------------------------------------------------- 1 | 2 | /***************************************************************************** 3 | * %FILENAME% 4 | * 5 | * Created:%YEAR% by %USER% 6 | * 7 | * Copyright %YEAR% %USER%. All rights reserved. 8 | * 9 | * This file may be distributed under the terms of GNU Public License version 10 | * 3 (GPL v3) as defined by the Free Software Foundation (FSF). A copy of the 11 | * license should have been included with this file, or the project in which 12 | * this file belongs to. You may also find the details of GPL v3 at: 13 | * http://www.gnu.org/licenses/gpl-3.0.txt 14 | * 15 | * If you have any questions regarding the use of this file, feel free to 16 | * contact the author of this file, or the owner of the project in which 17 | * this file belongs to. 18 | *****************************************************************************/ 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # tIDE 3 | 4 | tIDE, transportable IDE, is an application for SailfishOS to create new applications on the go! You can use it as pocket sized QtCreator or just normal text editor. 5 | 6 | All feature suggestions and contributions welcome! :) 7 | 8 | Includes keyboard and root mode! 9 | 10 | Winner of [Maemo Coding Competition 2016-2017 "Something new"](https://wiki.maemo.org/index.php?title=Maemo.org_Coding_Competition_2016#Results) category 11 | 12 | Check also [tIDEditor](https://github.com/eekkelund/harbour-tIDEditor), Jolla Store allowed version of tIDE. 13 | 14 | ![tIDE](https://github.com/eekkelund/tide/blob/devel/icons/128x128/harbour-tide.png?raw=true "tIDE") 15 | ![tIDEroot](https://github.com/eekkelund/harbour-tIDE/blob/devel/roothelper/icons/128x128/harbour-tide-root.png?raw=true "tIDEroot") 16 | ![tIDEditor](https://github.com/eekkelund/tide/blob/devel/icons/128x128/harbour-tide-editor.png?raw=true "tIDEditor") 17 | 18 | 19 | ## Features 20 | 21 | * Basic IDE features such as: 22 | * Syntax highlighting ( QML, JS, Bash & Python) 23 | * Project template creation for SailfishOS 24 | * Autocomplete (Installs new keyboard) 25 | * Running your application 26 | * Application output & debug log 27 | * Building a RPM (experimental) 28 | * Predictive text (QML, JS, Bash & Python) 29 | * Installing built RPM 30 | 31 | * Normal text editor features including: 32 | * Line numbers 33 | * Autosave 34 | * Themes 35 | * Font settings 36 | * Indentation 37 | * Redo/Undo 38 | * Search & Replace 39 | * Launch from terminal (harbour-tide /path/to/file.txt) 40 | * Change files on the fly 41 | * Split view. And possibility to move separator 42 | * Set as default editor 43 | 44 | * Root mode features: 45 | * Edit UI, application or system files. You name it! 46 | * Possibility to run applications in /usr/share 47 | 48 | * Keyboard: 49 | * Predictive text depending on what file opened 50 | * .qml = QML, properties, JS and common keywords 51 | * .js = JS and common keywords 52 | * .py = Pythons and common keywords 53 | * .sh = Bash and common keywords 54 | * .* = Common keywords 55 | * Tabulator button on Sym view 56 | * Tab settings real tab "\t" or amount of spaces 57 | * Arrow keys 58 | * On shift latched possibility to jump words 59 | * On shift down copying 60 | * Basic hardware support including common shortcuts 61 | * CTRL+Z, CTRL+F, CTRL+S, CTRL combinations 62 | * SHIFT combinations 63 | * etc. etc. 64 | 65 | ## Screenshots 66 | 67 | ![Dark theme](https://cloud.githubusercontent.com/assets/11635400/21082871/471aff54-bfed-11e6-8a35-63c3fbb066a8.png "Dark theme in editor") 68 | ![Settings](https://cloud.githubusercontent.com/assets/11635400/21082870/471a3cfe-bfed-11e6-8792-a330cea85d68.png "Settings") 69 | ![Predictive text](https://cloud.githubusercontent.com/assets/11635400/22042196/ceeb9e9c-dd12-11e6-9fb9-2c383892bea4.png "Predictive text") 70 | ![Building&Running](https://cloud.githubusercontent.com/assets/11635400/21082872/471b3bb8-bfed-11e6-85da-31bc6aa4f333.png "Building & Running") 71 | ![App output](https://cloud.githubusercontent.com/assets/11635400/21133077/c1fb2ef0-c11f-11e6-869b-facc0689d669.png "App output") 72 | ![Build output](https://cloud.githubusercontent.com/assets/11635400/22043760/d8b025ae-dd19-11e6-8665-000151fc3222.png "Build output") 73 | ![File open in split view](https://cloud.githubusercontent.com/assets/11635400/22042203/d5e80f14-dd12-11e6-9254-92c6269b63d2.png "File open in split view") 74 | ![Draggable separator](https://cloud.githubusercontent.com/assets/11635400/22042212/db53bd86-dd12-11e6-8293-c00726ec1c40.png "Draggable separator") 75 | ![File open](https://cloud.githubusercontent.com/assets/11635400/22042219/e339b94c-dd12-11e6-8668-730f419b342e.png "File open") 76 | 77 | ## To Do 78 | 79 | Not in particular order..:) 80 | 81 | - [ ] C++ support (v.0.3) 82 | * Syntax highlighting 83 | * Predictive 84 | * Compiling* 85 | - [ ] Git gui (v.0.3) 86 | - [X] Root mode 87 | - [X] Building (kinda, needs more work) 88 | - [ ] OBS(v.0.3-0.4) 89 | - [ ] Help mode(API's)(v.0.3-0.4) 90 | - [ ] Cover for harbour 91 | - [X] Icon 92 | - [X] Harbour version(v.0.2.6 Submitted to Jolla store) [tIDEditor](https://github.com/eekkelund/harbour-tIDEditor) 93 | - [ ] App cover(v.0.3-0.4) 94 | - [X] Fix line numbering YEA 95 | - [ ] Nemomobile version(v.0.5) 96 | - [ ] Breakpoints(v.0.5) 97 | - [X] About page 98 | - [X] Add new file 99 | - [X] Hw keyboard 100 | - [X] File navigation 101 | - [X] Arrow keys functionality 102 | - [ ] Rewrite some Python parts(v.0.5) 103 | - [X] Tab button 104 | - [X] UI for Tablet 105 | - [ ] Create patches(v.0.3) 106 | - [ ] .pro file parsing(v.0.3) 107 | - [ ] More highlighting(v.0.3) 108 | - [ ] Settings for topbar(v.0.3) 109 | - [ ] Icon edit? 110 | 111 | ## Installation 112 | 113 | Download RPM from openrepos and `pkcon install-local harbour-tide` 114 | If you have problem when installing try `pkcon refresh` and then try to install again. 115 | 116 | ## Contributing 117 | 118 | 1. Fork it! 119 | 2. Create your feature branch: `git checkout -b my-new-feature` 120 | 3. Commit your changes: `git commit -am 'Add some feature'` 121 | 4. Push to the branch: `git push origin my-new-feature` 122 | 5. Submit a pull request :D 123 | 124 | ## History 125 | 126 | [Version 0.2.5](https://openrepos.net/content/eekkelund/tide) 31/01/2017 127 | [Version 0.2](https://openrepos.net/content/eekkelund/tide) 18/01/2017 128 | [Version 0.1](https://openrepos.net/content/eekkelund/tide) 21/12/2016 129 | 130 | [Changelog](https://github.com/eekkelund/harbour-tIDE/blob/master/rpm/harbour-tide.changes) 131 | 132 | ## Contributors 133 | 134 | [wellef](https://github.com/wellef): Project deleting, wrap mode setting for the editor, Python bug fixes 135 | [GoAlexander](https://github.com/GoAlexander): Icon for searchbar 136 | 137 | ### Translations 138 | 139 | [eson57](https://github.com/eson57): Swedish 140 | [d9h02f](https://github.com/d9h02f): Dutch 141 | 142 | Thank you! :) 143 | 144 | ## Credits 145 | 146 | Base of the keyboard: Jolla's [maliit keyboard](https://github.com/maliit) and SaberAltria's [Dolphin keyboard](https://github.com/SaberAltria/harbour-dolphin-keyboard). 147 | Better 'root@tIDE' script [elros34](https://talk.maemo.org/showpost.php?p=1522202&postcount=28) 148 | SettingsPage slider: [Ancelad](https://github.com/Ancelad) 149 | Dedicated to: [Gido Griese](https://talk.maemo.org/member.php?u=60993) 150 | Icon: [gri4994](https://github.com/gri4994) SVG: [topiasv-p](https://github.com/topiasv-p) 151 | 152 | ## License 153 | 154 | Distributed under the GPLv3 license. See ``LICENSE`` for more information. 155 | 156 | Copyright (C) 2016-2017 Eetu Kahelin 157 | 158 | This program is free software: you can redistribute it and/or modify 159 | it under the terms of the GNU General Public License as published by 160 | the Free Software Foundation, either version 3 of the License, or 161 | (at your option) any later version. 162 | 163 | This program is distributed in the hope that it will be useful, 164 | but WITHOUT ANY WARRANTY; without even the implied warranty of 165 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 166 | GNU General Public License for more details. 167 | 168 | You should have received a copy of the GNU General Public License 169 | along with this program. If not, see . 170 | -------------------------------------------------------------------------------- /config/config.conf: -------------------------------------------------------------------------------- 1 | [General] 2 | keys=1 3 | word=1 4 | spacebar=0 5 | fusion=0 6 | enMode=0 7 | toolbar=1 8 | swipe=0 9 | ui-scale=1 10 | ui-color=0 11 | ui-background=0 12 | ui-fontSize=0 13 | ui-style=0 14 | ui-opacity=1 15 | ui-size=0 16 | tabsize=4 17 | [fileType] 18 | type=qml 19 | -------------------------------------------------------------------------------- /config/config.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = aux 2 | 3 | OTHER_FILES = \ 4 | config.conf 5 | 6 | DISTFILES += \ 7 | *.sqlite 8 | 9 | sql.files = $${DISTFILES} 10 | sql.path = /var/lib/harbour-tide-keyboard/database/ 11 | 12 | qml.files = $${OTHER_FILES} 13 | qml.path = /var/lib/harbour-tide-keyboard/config/ 14 | 15 | INSTALLS += qml sql 16 | -------------------------------------------------------------------------------- /config/js.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eekkelund/harbour-tIDE/f0d465ce730befdd1d4d4d64dea39d4e08187de6/config/js.sqlite -------------------------------------------------------------------------------- /config/keywords.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eekkelund/harbour-tIDE/f0d465ce730befdd1d4d4d64dea39d4e08187de6/config/keywords.sqlite -------------------------------------------------------------------------------- /config/properties.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eekkelund/harbour-tIDE/f0d465ce730befdd1d4d4d64dea39d4e08187de6/config/properties.sqlite -------------------------------------------------------------------------------- /config/py.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eekkelund/harbour-tIDE/f0d465ce730befdd1d4d4d64dea39d4e08187de6/config/py.sqlite -------------------------------------------------------------------------------- /config/qml.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eekkelund/harbour-tIDE/f0d465ce730befdd1d4d4d64dea39d4e08187de6/config/qml.sqlite -------------------------------------------------------------------------------- /config/sh.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eekkelund/harbour-tIDE/f0d465ce730befdd1d4d4d64dea39d4e08187de6/config/sh.sqlite -------------------------------------------------------------------------------- /developkbd/DevelopHandler.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2013 Jolla ltd and/or its subsidiary(-ies). All rights reserved. 3 | * 4 | * Contact: Pekka Vuorela 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * Redistributions of source code must retain the above copyright notice, this list 10 | * of conditions and the following disclaimer. 11 | * Redistributions in binary form must reproduce the above copyright notice, this list 12 | * of conditions and the following disclaimer in the documentation and/or other materials 13 | * provided with the distribution. 14 | * Neither the name of Jolla Ltd nor the names of its contributors may be 15 | * used to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 19 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 20 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 | * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | * 28 | */ 29 | import QtQuick 2.2 30 | import com.meego.maliitquick 1.0 31 | import Sailfish.Silica 1.0 32 | import com.jolla.keyboard 1.0 33 | import harbour.tide.keyboard 1.0 34 | import "../tide" 35 | 36 | InputHandler { 37 | id: inputHandler 38 | Database { 39 | id: database 40 | Component.onCompleted: database.initial("qml"); 41 | } 42 | 43 | onPreeditChanged: { 44 | if ( preedit.length > 0 ) { 45 | applyWord() 46 | } 47 | } 48 | 49 | function acceptWord(word) { 50 | if ( preedit !== "" ) { 51 | commit(word) 52 | adjustWord(word) 53 | predictWord(word) 54 | } else { 55 | commit(word) 56 | adjustPredict(word) 57 | empty() 58 | 59 | } 60 | } 61 | 62 | function applyWord() { 63 | result = database.predict(preedit, 16) 64 | candidatesUpdated() 65 | } 66 | 67 | function applyMoreWord() { 68 | if ( result.length <= 16 ) { 69 | result = database.predict(preedit, 128) 70 | candidatesUpdated() 71 | } 72 | } 73 | 74 | function predictWord(word) { 75 | result = database.predict(word, 32) 76 | candidatesUpdated() 77 | } 78 | 79 | function adjustWord(word) { 80 | if ( settings.keys === 1 ) { 81 | database.adjust("word", word) 82 | } 83 | } 84 | 85 | function adjustPredict(word) { 86 | if ( settings.word === 1 ) { 87 | database.adjust("word", word) 88 | } 89 | } 90 | 91 | topItem: Component { 92 | CandidateRow { 93 | id: container 94 | } 95 | } 96 | 97 | verticalItem: Component { 98 | CandidateColumn { 99 | id: container 100 | } 101 | } 102 | 103 | CandidateDialog { 104 | id: candidateDialog 105 | } 106 | 107 | function handleKeyClick() { 108 | var handled = false 109 | keyboard.expandedPaste = false 110 | 111 | if ( pressedKey.key === Qt.Key_Space ) { 112 | empty() 113 | if ( preedit.length > 0 && result.length > 0 && settings.spacebar === true) { 114 | 115 | preedit = "" 116 | commit(result[0]) 117 | adjustWord(result[0]) 118 | predictWord(result[0]) 119 | 120 | handled = true 121 | 122 | } else if ( preedit.length == 0 && result.length > 0 && settings.spacebar === 1 ) { 123 | commit(result[0]) 124 | adjustPredict(result[0]) 125 | empty() 126 | 127 | } else if ( preedit.length > 0 ) { 128 | commit(preedit+" ") 129 | 130 | } else { 131 | commit(" ") 132 | 133 | } 134 | handled = true 135 | } else if ( pressedKey.key === Qt.Key_Return ) { 136 | 137 | if ( preedit.length > 0 ) { 138 | commit(preedit) 139 | } 140 | empty() 141 | MInputMethodQuick.sendKey(Qt.Key_Return) 142 | handled = true 143 | 144 | } else if ( pressedKey.key === Qt.Key_Tab ) { 145 | if(settings.load("tabsize") && settings.load("tabsize") > 1){ 146 | var tabString = "" 147 | for (var i = 0; i < settings.load("tabsize"); i++) 148 | tabString += " " 149 | commit(preedit+tabString) 150 | } else { 151 | commit(preedit) 152 | MInputMethodQuick.sendKey(Qt.Key_Tab, 0, "\t", Maliit.KeyClick) 153 | } 154 | empty() 155 | handled = true 156 | 157 | } else if ( pressedKey.key === Qt.Key_Backspace ) { 158 | 159 | 160 | if ( preedit.length > 0 ) { 161 | 162 | preedit = preedit.slice(0, preedit.length-1) 163 | MInputMethodQuick.sendPreedit(preedit, Maliit.PreeditDefault) 164 | if ( preedit.length > 0 ) { 165 | applyWord(preedit) 166 | } else { 167 | 168 | empty() 169 | } 170 | 171 | } else if ( result.length > 0 ) { 172 | 173 | empty() 174 | MInputMethodQuick.sendKey(Qt.Key_Backspace) 175 | 176 | } else { 177 | MInputMethodQuick.sendKey(Qt.Key_Backspace) 178 | 179 | } 180 | 181 | handled = true 182 | 183 | } else if ( pressedKey.key === Qt.Key_Shift ) { 184 | handled = true 185 | } else if ( pressedKey.keyType === KeyType.FunctionKey && pressedKey.keyType === KeyType.SymbolKey ) { 186 | 187 | reset() 188 | empty() 189 | 190 | handled = true 191 | 192 | 193 | } else if ( pressedKey.text.match(/[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]/) !== null || ( pressedKey.text === "?" && preedit.length === 0 )) { 194 | 195 | if ( preedit.length >= 0 ) { 196 | 197 | preedit = preedit + pressedKey.text 198 | MInputMethodQuick.sendPreedit(preedit, Maliit.PreeditDefault) 199 | 200 | } else { 201 | reset() 202 | MInputMethodQuick.sendPreedit(preedit, Maliit.PreeditDefault) 203 | 204 | 205 | } 206 | if (keyboard.shiftState !== ShiftState.LockedShift) { 207 | keyboard.shiftState = ShiftState.NoShift 208 | } 209 | handled = true 210 | 211 | }else if ( pressedKey.key === Qt.Key_Clear ) { 212 | 213 | reset() 214 | empty() 215 | 216 | handled = true 217 | 218 | } else if ( pressedKey.text === "1/2" || pressedKey.text === "2/2" ) { 219 | handled = true 220 | 221 | } else { 222 | MInputMethodQuick.sendCommit(preedit) 223 | commit(pressedKey.text) 224 | handled = true 225 | } 226 | 227 | return handled 228 | } 229 | 230 | function accept(index) { 231 | console.log("attempting to accept", index) 232 | } 233 | 234 | 235 | function reset() { 236 | preedit = "" 237 | MInputMethodQuick.sendPreedit("", Maliit.PreeditDefault) 238 | } 239 | 240 | function commit(text) { 241 | MInputMethodQuick.sendCommit(text) 242 | reset() 243 | } 244 | 245 | function empty() { 246 | result = [] 247 | } 248 | 249 | } 250 | -------------------------------------------------------------------------------- /developkbd/develop.conf: -------------------------------------------------------------------------------- 1 | [develop.qml] 2 | name=Develop 3 | languageCode=Develop 4 | handler=layouts/DevelopHandler.qml 5 | -------------------------------------------------------------------------------- /developkbd/develop.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2013 Jolla ltd and/or its subsidiary(-ies). All rights reserved. 3 | * 4 | * Contact: Pekka Vuorela 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * Redistributions of source code must retain the above copyright notice, this list 10 | * of conditions and the following disclaimer. 11 | * Redistributions in binary form must reproduce the above copyright notice, this list 12 | * of conditions and the following disclaimer in the documentation and/or other materials 13 | * provided with the distribution. 14 | * Neither the name of Jolla Ltd nor the names of its contributors may be 15 | * used to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 19 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 20 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 | * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | * 28 | */ 29 | 30 | import QtQuick 2.2 31 | import Sailfish.Silica 1.0 32 | import com.meego.maliitquick 1.0 33 | import harbour.tide.keyboard 1.0 34 | import "../tide" 35 | 36 | KeyboardLayout { 37 | id: layout 38 | splitSupported: true 39 | 40 | primary: "DevelopHandler" 41 | secondary: "Xt9InputHandler" 42 | 43 | KeyboardRow { 44 | CharacterKey { caption: "q"; captionShifted: "Q"; symView: "1"; symView2: "€" } 45 | CharacterKey { caption: "w"; captionShifted: "W"; symView: "2"; symView2: "£" } 46 | CharacterKey { caption: "e"; captionShifted: "E"; symView: "3"; symView2: "$"; accents: "eèéêë€"; accentsShifted: "EÈÉÊË€" } 47 | CharacterKey { caption: "r"; captionShifted: "R"; symView: "4"; symView2: "¥" } 48 | CharacterKey { caption: "t"; captionShifted: "T"; symView: "5"; symView2: "₹"; accents: "tþ"; accentsShifted: "TÞ" } 49 | CharacterKey { caption: "y"; captionShifted: "Y"; symView: "6"; symView2: "%"; accents: "yý¥"; accentsShifted: "YÝ¥" } 50 | CharacterKey { caption: "u"; captionShifted: "U"; symView: "7"; symView2: "<"; accents: "uűûùúü"; accentsShifted: "UŰÛÙÚÜ" } 51 | CharacterKey { caption: "i"; captionShifted: "I"; symView: "8"; symView2: ">"; accents: "iîïìí"; accentsShifted: "IÎÏÌÍ" } 52 | CharacterKey { caption: "o"; captionShifted: "O"; symView: "9"; symView2: "["; accents: "oőøöôòó"; accentsShifted: "OŐØÖÔÒÓ" } 53 | CharacterKey { caption: "p"; captionShifted: "P"; symView: "0"; symView2: "]" } 54 | } 55 | 56 | KeyboardRow { 57 | splitIndex: 5 58 | 59 | CharacterKey { caption: "a"; captionShifted: "A"; symView: "*"; symView2: "`"; accents: "aäàâáãå"; accentsShifted: "AÄÀÂÁÃÅ"} 60 | CharacterKey { caption: "s"; captionShifted: "S"; symView: "#"; symView2: "^"; accents: "sß$"; accentsShifted: "S$" } 61 | CharacterKey { caption: "d"; captionShifted: "D"; symView: "+"; symView2: "|"; accents: "dð"; accentsShifted: "DÐ" } 62 | CharacterKey { caption: "f"; captionShifted: "F"; symView: "-"; symView2: "_" } 63 | CharacterKey { caption: "g"; captionShifted: "G"; symView: "="; symView2: "§" } 64 | CharacterKey { caption: "h"; captionShifted: "H"; symView: "("; symView2: "@" } 65 | CharacterKey { caption: "j"; captionShifted: "J"; symView: ")"; symView2: "&" } 66 | CharacterKey { caption: "k"; captionShifted: "K"; symView: "!"; symView2: "¡" } 67 | CharacterKey { caption: "l"; captionShifted: "L"; symView: "?"; symView2: "¿" } 68 | 69 | } 70 | 71 | KeyboardRow { 72 | splitIndex: 5 73 | 74 | ShiftKey { } 75 | 76 | CharacterKey { caption: "z"; captionShifted: "Z"; symView: "{"; symView2: "«" } 77 | CharacterKey { caption: "x"; captionShifted: "X"; symView: "}"; symView2: "»" } 78 | CharacterKey { caption: "c"; captionShifted: "C"; symView: "/"; symView2: "\""; accents: "cç"; accentsShifted: "CÇ" } 79 | CharacterKey { caption: "v"; captionShifted: "V"; symView: "\\"; symView2: "“" } 80 | CharacterKey { caption: "b"; captionShifted: "B"; symView: "'"; symView2: "”" } 81 | CharacterKey { caption: "n"; captionShifted: "N"; symView: ";"; symView2: "„"; accents: "nñ"; accentsShifted: "NÑ" } 82 | CharacterKey { caption: "m"; captionShifted: "M"; symView: ":"; symView2: "~" } 83 | 84 | BackspaceKey { } 85 | } 86 | 87 | KeyboardRow { 88 | splitIndex: 3 89 | 90 | SymbolKey { } 91 | ContextAwareKey { } 92 | SpacebarKey { } 93 | SpacebarKey { 94 | active: splitActive 95 | languageLabel: "" 96 | } 97 | CharacterKey { 98 | caption: "." 99 | captionShifted: "." 100 | accents: ":" 101 | accentsShifted: ":" 102 | implicitWidth: punctuationKeyWidth 103 | fixedWidth: !splitActive 104 | //separator: SeparatorState.HiddenSeparator 105 | } 106 | EnterKey { } 107 | } 108 | } 109 | 110 | -------------------------------------------------------------------------------- /developkbd/developkbd.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = aux 2 | 3 | OTHER_FILES = *.qml \ 4 | develop.conf 5 | 6 | qml.files = $${OTHER_FILES} 7 | qml.path = /usr/share/maliit/plugins/com/jolla/layouts/ 8 | 9 | INSTALLS += qml 10 | -------------------------------------------------------------------------------- /dolphin/AccentedCharacterKey.qml: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 Jolla Ltd. 2 | // Contact: Pekka Vuorela 3 | 4 | import QtQuick 2.2 5 | import Sailfish.Silica 1.0 6 | import com.jolla.keyboard 1.0 7 | 8 | CharacterKey { 9 | property string deadKeyAccents 10 | property string deadKeyAccentsShifted 11 | property string _deadKeyAccents: keyboard.isShifted ? deadKeyAccentsShifted : deadKeyAccents 12 | property int _deadAccentIndex: keyboard.deadKeyAccent !== "" ? _deadKeyAccents.indexOf(keyboard.deadKeyAccent) : -1 13 | property string _accentedText: _deadAccentIndex > -1 && !keyboard.inSymView ? _deadKeyAccents.substr(_deadAccentIndex+1, 1) : "" 14 | 15 | useBoldFont: _deadAccentIndex > -1 16 | keyType: _accentedText !== "" ? KeyType.PopupKey : KeyType.CharacterKey 17 | _keyText: _accentedText !== "" ? _accentedText : 18 | attributes.inSymView && symView.length > 0 ? (attributes.inSymView2 ? symView2 : symView) 19 | : (attributes.isShifted ? captionShifted : caption) 20 | } 21 | -------------------------------------------------------------------------------- /dolphin/BackspaceKey.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Jolla ltd. and/or its subsidiary(-ies). All rights reserved. 3 | * 4 | * Contact: Pekka Vuorela 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * Redistributions of source code must retain the above copyright notice, this list 10 | * of conditions and the following disclaimer. 11 | * Redistributions in binary form must reproduce the above copyright notice, this list 12 | * of conditions and the following disclaimer in the documentation and/or other materials 13 | * provided with the distribution. 14 | * Neither the name of Jolla ltd nor the names of its contributors may be 15 | * used to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 19 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 20 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 | * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | * 28 | */ 29 | 30 | import QtQuick 2.2 31 | import Sailfish.Silica 1.0 32 | 33 | FunctionKey { 34 | icon.source: "image://theme/icon-m-backspace" + (pressed ? ("?" + Theme.highlightColor) : "") 35 | repeat: true 36 | key: Qt.Key_Backspace 37 | implicitWidth: shiftKeyWidth 38 | } 39 | -------------------------------------------------------------------------------- /dolphin/CandidateColumn.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.2 2 | import Sailfish.Silica 1.0 3 | import com.meego.maliitquick 1.0 4 | import com.jolla.keyboard 1.0 5 | 6 | Rectangle { 7 | id: container 8 | anchors.fill: parent 9 | color: Theme.highlightDimmerColor 10 | 11 | 12 | //Block unwanted close keyboard gesture 13 | MultiPointTouchArea { 14 | anchors.fill: parent 15 | z: -1 16 | } 17 | 18 | More { 19 | id: more 20 | anchors.bottom: parent.bottom 21 | } 22 | 23 | Help { 24 | id: help 25 | } 26 | 27 | SilicaListView { 28 | id: listView 29 | anchors.fill: parent 30 | contentHeight: Math.max(parent.height, header.height) 31 | interactive: true 32 | flickableDirection: Flickable.VerticalFlick 33 | model: result 34 | boundsBehavior: ( !keyboard.expandedPaste && Clipboard.hasText ) || ( more.visible ) ? Flickable.DragOverBounds : Flickable.StopAtBounds 35 | clip: true 36 | 37 | header: Component { 38 | Toolbar { 39 | id: toolbar 40 | width: parent.width 41 | count: result.length 42 | //columns: 3 43 | } 44 | } 45 | 46 | delegate: DelegateH { 47 | id: delegateH 48 | width: container.width 49 | height: geometry.keyHeightLandscape * settings.scale 50 | } 51 | 52 | 53 | onDragEnded: { 54 | if ( atYEnd && result.length > 8 ) { 55 | SampleCache.play("/usr/share/sounds/jolla-ambient/stereo/keyboard_letter.wav") 56 | buttonPressEffect.play() 57 | 58 | if ( preedit !== "" && result.length <= 16 ) { 59 | applyMoreWord() 60 | } 61 | 62 | fetchMany = true 63 | } 64 | } 65 | 66 | onContentHeightChanged: { 67 | timer.restart() 68 | } 69 | 70 | Connections { 71 | target: Clipboard 72 | onTextChanged: { 73 | if (Clipboard.hasText) { 74 | //Need to have updated width before repositioning view 75 | timer.restart() 76 | } 77 | } 78 | } 79 | 80 | Timer { 81 | id: timer 82 | interval: 16 83 | onTriggered: listView.positionViewAtBeginning() 84 | } 85 | 86 | } 87 | } 88 | 89 | -------------------------------------------------------------------------------- /dolphin/CandidateDialog.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.2 2 | import Sailfish.Silica 1.0 3 | import com.meego.maliitquick 1.0 4 | import com.jolla.keyboard 1.0 5 | 6 | 7 | Rectangle { 8 | id: root 9 | visible: fetchMany 10 | parent: keyboard 11 | z: 2 12 | anchors.fill: parent 13 | anchors.topMargin:topItem.height 14 | color: Theme.rgba(Theme.highlightDimmerColor, 1) 15 | 16 | 17 | SilicaFlickable { 18 | height: parent.height 19 | anchors.top: parent.top 20 | anchors.left: parent.left 21 | anchors.right: close.left 22 | contentHeight: flow.height 23 | flickableDirection: Flickable.VerticalFlick 24 | clip: true 25 | 26 | VerticalScrollDecorator { } 27 | 28 | Flow { 29 | id: flow 30 | width: parent.width 31 | 32 | Repeater { 33 | id: repeater 34 | model: result 35 | 36 | delegate: Component { 37 | 38 | DelegateV { 39 | id: delegateV 40 | } 41 | } 42 | } 43 | } 44 | } 45 | 46 | Close { 47 | id: close 48 | onClicked: { 49 | fetchMany = false 50 | } 51 | } 52 | 53 | MultiPointTouchArea { 54 | // prevent events leaking below 55 | anchors.fill: parent 56 | z: -1 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /dolphin/CandidateRow.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.2 2 | import Sailfish.Silica 1.0 3 | import com.meego.maliitquick 1.0 4 | import com.jolla.keyboard 1.0 5 | 6 | TopItem { 7 | id: container 8 | 9 | Rectangle { 10 | anchors.fill: parent 11 | color: Theme.highlightDimmerColor 12 | opacity: 0.2 13 | 14 | Separator { 15 | color: Theme.highlightColor 16 | width: parent.width 17 | anchors.bottom: parent.bottom 18 | } 19 | } 20 | 21 | More { 22 | id: more 23 | } 24 | 25 | Help { 26 | id: help 27 | } 28 | 29 | SilicaListView { 30 | id: listView 31 | height: parent.height 32 | width: parent.width 33 | interactive: true 34 | flickableDirection: Flickable.HorizontalFlick 35 | orientation: ListView.Horizontal 36 | model: result 37 | boundsBehavior: ( !keyboard.expandedPaste && Clipboard.hasText ) || ( more.visible ) ? Flickable.DragOverBounds : Flickable.StopAtBounds 38 | 39 | header: Component { 40 | Toolbar { 41 | id: toolbar 42 | height: Theme.itemSizeSmall 43 | count: result.length 44 | } 45 | } 46 | 47 | delegate: Component { 48 | DelegateH { 49 | id: delegateH 50 | width: candidate.width + Theme.paddingMedium * 2 51 | height: container.height 52 | } 53 | } 54 | 55 | onDragEnded: { 56 | //it won't go further if has more than 8 results 57 | if ( atXEnd && result.length > 8 ) { 58 | SampleCache.play("/usr/share/sounds/jolla-ambient/stereo/keyboard_letter.wav") 59 | buttonPressEffect.play() 60 | 61 | if ( preedit !== "" && result.length <= 16 ) { 62 | applyMoreWord() 63 | } 64 | 65 | fetchMany = true 66 | } 67 | } 68 | 69 | onContentWidthChanged: { 70 | //timer.restart() 71 | } 72 | 73 | Connections { 74 | target: Clipboard 75 | onTextChanged: { 76 | if (Clipboard.hasText) { 77 | listView.positionViewAtBeginning() 78 | //timer.restart() 79 | } 80 | } 81 | } 82 | 83 | Timer { 84 | id: timer 85 | interval: 16 86 | //onTriggered: listView.positionViewAtBeginning() 87 | } 88 | 89 | 90 | } 91 | } 92 | 93 | 94 | -------------------------------------------------------------------------------- /dolphin/CharacterKey.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. 3 | * Copyright (C) 2012-2013 Jolla Ltd. 4 | * 5 | * Contact: Pekka Vuorela 6 | * 7 | * Redistribution and use in source and binary forms, with or without modification, 8 | * are permitted provided that the following conditions are met: 9 | * 10 | * Redistributions of source code must retain the above copyright notice, this list 11 | * of conditions and the following disclaimer. 12 | * Redistributions in binary form must reproduce the above copyright notice, this list 13 | * of conditions and the following disclaimer in the documentation and/or other materials 14 | * provided with the distribution. 15 | * Neither the name of Nokia Corporation nor the names of its contributors may be 16 | * used to endorse or promote products derived from this software without specific 17 | * prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 23 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | * 29 | */ 30 | 31 | import QtQuick 2.2 32 | import com.jolla.keyboard 1.0 33 | import Sailfish.Silica 1.0 34 | 35 | KeyBase { 36 | id: aCharKey 37 | 38 | property string captionShifted 39 | property string symView 40 | property string symView2 41 | property int separator: SeparatorState.AutomaticSeparator 42 | property bool implicitSeparator: true // set by layouting 43 | property bool showHighlight: true 44 | property string accents 45 | property string accentsShifted 46 | property string nativeAccents // accents considered native to the written language. not rendered. 47 | property string nativeAccentsShifted 48 | property bool fixedWidth 49 | property alias useBoldFont: primary.font.bold 50 | 51 | keyType: KeyType.CharacterKey 52 | text: primary.text 53 | keyText: primary.text 54 | 55 | Text { 56 | id: primary 57 | anchors.centerIn: parent 58 | anchors.horizontalCenterOffset: (leftPadding - rightPadding) / 2 59 | horizontalAlignment: Text.AlignHCenter 60 | verticalAlignment: Text.AlignVCenter 61 | font.family: Theme.fontFamily 62 | font.pixelSize: Theme.fontSizeLarge 63 | color: pressed ? Theme.highlightColor : Theme.primaryColor 64 | text: attributes.inSymView && symView.length > 0 ? (attributes.inSymView2 ? symView2 : symView) 65 | : (attributes.isShifted ? captionShifted : caption) 66 | } 67 | 68 | Image { 69 | source: "graphic-keyboard-highlight-top.png" 70 | anchors.right: parent.right 71 | visible: (separator === SeparatorState.AutomaticSeparator && implicitSeparator) 72 | || separator === SeparatorState.VisibleSeparator 73 | } 74 | 75 | Rectangle { 76 | anchors.fill: parent 77 | z: -1 78 | color: Theme.highlightBackgroundColor 79 | opacity: 0.5 80 | visible: pressed && showHighlight 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /dolphin/Close.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.2 2 | import Sailfish.Silica 1.0 3 | import com.jolla.keyboard 1.0 4 | 5 | BackgroundItem { 6 | id: close 7 | width: Theme.itemSizeSmall 8 | height: parent.height 9 | anchors.right: parent.right 10 | 11 | Image { 12 | width: 32 13 | height: 32 14 | opacity: 0.6 15 | anchors.centerIn: parent 16 | source: "image://theme/icon-close-vkb" 17 | } 18 | 19 | onPressed: { 20 | buttonPressEffect.play() 21 | SampleCache.play("/usr/share/sounds/jolla-ambient/stereo/keyboard_letter.wav") 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /dolphin/CommitKey.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.2 2 | import Sailfish.Silica 1.0 3 | import com.jolla.keyboard 1.0 4 | 5 | BackgroundItem { 6 | 7 | id: root 8 | property string caption 9 | property alias src: icon.source 10 | 11 | width: label.visible? label.width + Theme.paddingLarge * 2: icon.width + Theme.paddingMedium * 2 12 | height: Theme.itemSizeSmall 13 | 14 | Label { 15 | id: label 16 | visible: !icon.visible 17 | anchors.centerIn: parent 18 | text: caption 19 | font.pixelSize: Theme.fontSizeSmall 20 | } 21 | 22 | Image { 23 | id: icon 24 | visible: icon.status === Image.Error || icon.status === Image.Null || src === null || typeof src === "undefined" ? false : true 25 | source: "" 26 | asynchronous: true 27 | width: Theme.iconSizeSmall 28 | height: Theme.iconSizeSmall 29 | anchors.centerIn: parent 30 | } 31 | 32 | Image { 33 | source: "graphic-keyboard-highlight-top.png" 34 | anchors.right: parent.right 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /dolphin/ContextAwareKey.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.2 2 | import com.meego.maliitquick 1.0 3 | import com.jolla.keyboard 1.0 4 | 5 | CharacterKey { 6 | caption: MInputMethodQuick.contentType === Maliit.UrlContentType 7 | ? "/" 8 | : MInputMethodQuick.contentType === Maliit.EmailContentType 9 | ? "@" 10 | : "," 11 | captionShifted: caption 12 | symView: "," 13 | symView2: "," 14 | accents: ";" 15 | accentsShifted: ";" 16 | implicitWidth: punctuationKeyWidth 17 | fixedWidth: !splitActive 18 | separator: SeparatorState.HiddenSeparator 19 | } 20 | -------------------------------------------------------------------------------- /dolphin/CursorKey.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.2 2 | import Sailfish.Silica 1.0 3 | import com.jolla.keyboard 1.0 4 | import com.meego.maliitquick 1.0 5 | 6 | BackgroundItem { 7 | property string direction 8 | 9 | width: height 10 | height: Theme.itemSizeSmall 11 | 12 | Image { 13 | id: image 14 | anchors.centerIn: parent 15 | height: parent.height / 2 16 | fillMode: Image.PreserveAspectFit 17 | source: "image://theme/icon-m-" + direction + (pressed ? ("?" + Theme.highlightColor) : "") 18 | } 19 | 20 | onPressedChanged: { 21 | var keyboardModifier 22 | if ( pressed ) { 23 | switch(keyboard.shiftState) { 24 | case ShiftState.LockedShift: 25 | keyboardModifier = Qt.ShiftModifier 26 | break 27 | case ShiftState.LatchedShift: 28 | keyboardModifier = Qt.ControlModifier 29 | break 30 | default: 31 | keyboardModifier = 0 32 | break 33 | } 34 | switch(direction) { 35 | case"left": 36 | MInputMethodQuick.sendKey(Qt.Key_Left, keyboardModifier, "", Maliit.KeyClick) 37 | MInputMethodQuick.sendKey(Qt.Key_C, Qt.ControlModifier, 0, "", Maliit.KeyClick) 38 | break 39 | case "right": 40 | MInputMethodQuick.sendKey(Qt.Key_Right, keyboardModifier, "", Maliit.KeyClick) 41 | MInputMethodQuick.sendKey(Qt.Key_C, Qt.ControlModifier, 0, "", Maliit.KeyClick) 42 | break 43 | case "up": 44 | MInputMethodQuick.sendKey(Qt.Key_Up, keyboardModifier, "", Maliit.KeyClick) 45 | MInputMethodQuick.sendKey(Qt.Key_C, Qt.ControlModifier, 0, "", Maliit.KeyClick) 46 | break 47 | case "down": 48 | MInputMethodQuick.sendKey(Qt.Key_Down, keyboardModifier, "", Maliit.KeyClick) 49 | MInputMethodQuick.sendKey(Qt.Key_C, Qt.ControlModifier, 0, "", Maliit.KeyClick) 50 | break 51 | } 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /dolphin/DeadKey.qml: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 Jolla Ltd. 2 | // Contact: Pekka Vuorela 3 | 4 | import QtQuick 2.2 5 | import Sailfish.Silica 1.0 6 | import com.jolla.keyboard 1.0 7 | import com.meego.maliitquick 1.0 8 | 9 | CharacterKey { 10 | id: deadKey 11 | 12 | property int _charactersWhenPressed 13 | property bool _quickPicking 14 | 15 | keyType: !keyboard.inSymView ? KeyType.DeadKey : KeyType.CharacterKey 16 | useBoldFont: keyboard.deadKeyAccent === text 17 | showPopper: keyType === KeyType.CharacterKey 18 | fixedWidth: !splitActive 19 | implicitWidth: punctuationKeyWidth 20 | 21 | onPressedChanged: { 22 | if (pressed 23 | && !keyboard.inSymView 24 | && keyboard.deadKeyAccent !== text 25 | && keyboard.lastInitialKey === deadKey) { 26 | keyboard.deadKeyAccent = text 27 | _quickPicking = true 28 | } else { 29 | _quickPicking = false 30 | } 31 | 32 | _charactersWhenPressed = keyboard.characterKeyCounter 33 | } 34 | 35 | onClicked: { 36 | if (keyboard.characterKeyCounter > _charactersWhenPressed) { 37 | keyboard.deadKeyAccent = "" 38 | keyboard.updatePopper() 39 | } else if (!_quickPicking) { 40 | if (keyboard.deadKeyAccent !== text && !keyboard.inSymView) { 41 | keyboard.deadKeyAccent = text 42 | } else { 43 | keyboard.deadKeyAccent = "" 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /dolphin/DelegateH.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.2 2 | import Sailfish.Silica 1.0 3 | import com.jolla.keyboard 1.0 4 | 5 | 6 | BackgroundItem { 7 | id: root 8 | property alias candidate: candidate 9 | 10 | Label { 11 | id: candidate 12 | anchors.centerIn: parent 13 | horizontalAlignment: Text.AlignHCenter 14 | verticalAlignment: Text.AlignVCenter 15 | color: ( parent.down || index === 0 )? Theme.highlightColor : Theme.primaryColor 16 | font { pixelSize: ( settings.size === 0? Theme.fontSizeExtraSmall: ( settings.size === 1 ? Theme.fontSizeMedium : Theme.fontSizeSmall) ) } 17 | text: result[index] 18 | textFormat: Text.PlainText 19 | } 20 | 21 | onClicked: { 22 | buttonPressEffect.play() 23 | SampleCache.play("/usr/share/sounds/jolla-ambient/stereo/keyboard_letter.wav") 24 | acceptWord(result[index]) 25 | } 26 | 27 | /*onPressAndHold: { 28 | checkDictionary(result[index]) 29 | }*/ 30 | 31 | Image { 32 | source: "graphic-keyboard-highlight-top.png" 33 | anchors.right: parent.right 34 | } 35 | } 36 | 37 | 38 | -------------------------------------------------------------------------------- /dolphin/DelegateV.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.2 2 | import Sailfish.Silica 1.0 3 | import com.jolla.keyboard 1.0 4 | 5 | BackgroundItem { 6 | id: root 7 | width: character.width + Theme.paddingMedium * 2 8 | height: Theme.itemSizeSmall 9 | 10 | onClicked: { 11 | fetchMany = false 12 | buttonPressEffect.play() 13 | SampleCache.play("/usr/share/sounds/jolla-ambient/stereo/keyboard_letter.wav") 14 | acceptWord(modelData) 15 | } 16 | 17 | onPressAndHold: { 18 | checkDictionary(modelData) 19 | } 20 | 21 | Text { 22 | id: character 23 | anchors.centerIn: parent 24 | horizontalAlignment: Text.AlignHCenter 25 | verticalAlignment: Text.AlignVCenter 26 | textFormat: Text.PlainText 27 | color: ( parent.down || index === 0 ) ? Theme.highlightColor : Theme.primaryColor 28 | font { pixelSize: ( settings.size === 0? Theme.fontSizeExtraSmall: ( settings.size === 1 ? Theme.fontSizeMedium : Theme.fontSizeSmall) ) } 29 | text: modelData 30 | } 31 | 32 | Image { 33 | source: "graphic-keyboard-highlight-top.png" 34 | anchors.right: parent.right 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /dolphin/EnterKey.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Jolla ltd. and/or its subsidiary(-ies). All rights reserved. 3 | * 4 | * Contact: Pekka Vuorela 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * Redistributions of source code must retain the above copyright notice, this list 10 | * of conditions and the following disclaimer. 11 | * Redistributions in binary form must reproduce the above copyright notice, this list 12 | * of conditions and the following disclaimer in the documentation and/or other materials 13 | * provided with the distribution. 14 | * Neither the name of Jolla ltd nor the names of its contributors may be 15 | * used to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 19 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 20 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 | * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | * 28 | */ 29 | 30 | import QtQuick 2.2 31 | import Sailfish.Silica 1.0 32 | 33 | FunctionKey { 34 | property bool chineseOverride: keyboard.chineseOverrideForEnter 35 | 36 | icon.source: attributes.inSymView ? "tab.svg" : MInputMethodQuick.actionKeyOverride.icon 37 | //icon.source: !chineseOverride ? MInputMethodQuick.actionKeyOverride.icon : "" 38 | caption: !chineseOverride ? MInputMethodQuick.actionKeyOverride.label : "输入" // <= "enter" 39 | key: attributes.inSymView ? Qt.Key_Tab: Qt.Key_Return 40 | enabled: !chineseOverride ? MInputMethodQuick.actionKeyOverride.enabled : true 41 | implicitWidth: shiftKeyWidth 42 | 43 | Rectangle { 44 | color: parent.pressed ? Theme.highlightBackgroundColor : Theme.primaryColor 45 | opacity: parent.pressed ? 0.6 46 | : MInputMethodQuick.actionKeyOverride.highlighted ? 0.4 : 0.17 47 | radius: geometry.keyRadius 48 | 49 | anchors.fill: parent 50 | anchors.margins: Theme.paddingMedium 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /dolphin/FunctionKey.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. 3 | * Copyright (C) 2012-2013 Jolla Ltd. 4 | * 5 | * Contact: Pekka Vuorela 6 | * 7 | * Redistribution and use in source and binary forms, with or without modification, 8 | * are permitted provided that the following conditions are met: 9 | * 10 | * Redistributions of source code must retain the above copyright notice, this list 11 | * of conditions and the following disclaimer. 12 | * Redistributions in binary form must reproduce the above copyright notice, this list 13 | * of conditions and the following disclaimer in the documentation and/or other materials 14 | * provided with the distribution. 15 | * Neither the name of Nokia Corporation nor the names of its contributors may be 16 | * used to endorse or promote products derived from this software without specific 17 | * prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 23 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | * 29 | */ 30 | 31 | import QtQuick 2.2 32 | import com.jolla.keyboard 1.0 33 | import Sailfish.Silica 1.0 34 | 35 | KeyBase { 36 | id: aFunctKey 37 | 38 | property alias icon: image 39 | property int sourceWidth: -1 40 | property int sourceHeight: -1 41 | property bool separator 42 | 43 | keyType: KeyType.FunctionKey 44 | opacity: enabled ? (pressed ? 0.6 : 1.0) 45 | : 0.3 46 | showPopper: false 47 | 48 | Image { 49 | id: image 50 | anchors.centerIn: parent 51 | anchors.horizontalCenterOffset: (leftPadding - rightPadding) / 2 52 | } 53 | 54 | Text { 55 | anchors.centerIn: parent 56 | anchors.horizontalCenterOffset: (leftPadding - rightPadding) / 2 57 | horizontalAlignment: Text.AlignHCenter 58 | verticalAlignment: Text.AlignVCenter 59 | font.pixelSize: Theme.fontSizeMedium 60 | font.family: Theme.fontFamily 61 | color: parent.pressed ? Theme.highlightColor : Theme.primaryColor 62 | text: parent.caption 63 | } 64 | 65 | Image { 66 | source: "graphic-keyboard-highlight-top.png" 67 | anchors.right: parent.right 68 | visible: separator 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /dolphin/Help.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.2 2 | import Sailfish.Silica 1.0 3 | 4 | Rectangle { 5 | id: root 6 | z: 8192 7 | property string label 8 | width: label.width + geometry.clearPasteMargin 9 | height: label.height + geometry.clearPasteMargin 10 | radius: geometry.popperRadius 11 | color: Qt.darker(Theme.highlightBackgroundColor, 1.2) 12 | anchors.bottom: parent.top 13 | x: 0 14 | visible: false 15 | 16 | onLabelChanged: { 17 | visible = true 18 | timer.start() 19 | } 20 | 21 | Timer { 22 | id: timer 23 | interval: 4096 24 | onTriggered: { 25 | parent.visible = false 26 | } 27 | } 28 | 29 | Label { 30 | id: label 31 | anchors.centerIn: parent 32 | color: Theme.primaryColor 33 | text: parent.label 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /dolphin/HwrInputHandler.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.2 2 | import com.meego.maliitquick 1.0 3 | import Sailfish.Silica 1.0 4 | import com.jolla.hwr 1.0 5 | import com.jolla.keyboard 1.0 6 | 7 | InputHandler { 8 | id: hwrHandler 9 | 10 | property string inputMode: layoutRow.layout ? layoutRow.layout.inputMode : "" 11 | property string preedit: HwrModel.primaryCandidate 12 | 13 | onInputModeChanged: HwrModel.inputMode = inputMode 14 | 15 | onPreeditChanged: { 16 | if (active) { 17 | MInputMethodQuick.sendPreedit(preedit) 18 | } 19 | } 20 | 21 | Component { 22 | id: pasteComponent 23 | PasteButton { 24 | onClicked: { 25 | if (preedit !== "") { 26 | MInputMethodQuick.sendCommit(preedit) 27 | } 28 | MInputMethodQuick.sendCommit(Clipboard.text) 29 | HwrModel.clear() 30 | keyboard.expandedPaste = false 31 | } 32 | } 33 | } 34 | 35 | topItem: Component { 36 | TopItem { 37 | id: topItem 38 | visible: canvas.portraitLayout 39 | height: visible ? Theme.itemSizeSmall : 0 40 | 41 | Rectangle { 42 | height: parent.height 43 | width: parent.width 44 | color: Theme.rgba(Theme.highlightBackgroundColor, .05) 45 | 46 | ListView { 47 | id: listView 48 | model: HwrModel 49 | orientation: ListView.Horizontal 50 | anchors.fill: parent 51 | header: pasteComponent 52 | boundsBehavior: !keyboard.expandedPaste && Clipboard.hasText ? Flickable.DragOverBounds : Flickable.StopAtBounds 53 | 54 | onDraggingChanged: { 55 | if (!dragging && !keyboard.expandedPaste && contentX < -(headerItem.width + Theme.paddingLarge)) { 56 | keyboard.expandedPaste = true 57 | positionViewAtBeginning() 58 | } 59 | } 60 | 61 | delegate: BackgroundItem { 62 | onClicked: hwrHandler.applyCandidate(model.text) 63 | width: candidateText.width + Theme.paddingLarge * 2 64 | height: topItem.height 65 | 66 | Text { 67 | id: candidateText 68 | anchors.centerIn: parent 69 | color: highlighted ? Theme.highlightColor : Theme.primaryColor 70 | font { pixelSize: Theme.fontSizeSmall; family: Theme.fontFamily } 71 | text: model.text 72 | } 73 | } 74 | } 75 | 76 | Connections { 77 | target: Clipboard 78 | onTextChanged: { 79 | if (Clipboard.hasText) { 80 | // need to have updated width before repositioning view 81 | positionerTimer.restart() 82 | } 83 | } 84 | } 85 | 86 | Connections { 87 | target: HwrModel 88 | onModelReset: keyboard.expandedPaste = false 89 | onCharacterStarted: { 90 | if (hwrHandler.preedit !== "") { 91 | MInputMethodQuick.sendCommit(hwrHandler.preedit) 92 | } 93 | } 94 | } 95 | 96 | Timer { 97 | id: positionerTimer 98 | interval: 10 99 | onTriggered: listView.positionViewAtBeginning() 100 | } 101 | } 102 | } 103 | } 104 | 105 | onActiveChanged: { 106 | if (!active && preedit !== "") { 107 | MInputMethodQuick.sendCommit(preedit) 108 | HwrModel.clear() 109 | } 110 | } 111 | 112 | function handleKeyClick() { 113 | keyboard.expandedPaste = false 114 | if (preedit !== "") { 115 | if (pressedKey.key === Qt.Key_Space || pressedKey.key === Qt.Key_Return) { 116 | MInputMethodQuick.sendCommit(preedit) 117 | HwrModel.clear() 118 | return true 119 | } else if (pressedKey.key === Qt.Key_Backspace) { 120 | MInputMethodQuick.sendPreedit("") 121 | HwrModel.clear() 122 | return true 123 | } 124 | } 125 | return false 126 | } 127 | 128 | function applyCandidate(text) { 129 | MInputMethodQuick.sendCommit(text) 130 | HwrModel.clear() 131 | if (canvas.phraseEngine) { 132 | HwrModel.setPhraseCandidates(canvas.phraseEngine.phraseCandidates(text)) 133 | } 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /dolphin/InputHandler.qml: -------------------------------------------------------------------------------- 1 | /**************************************************************************************** 2 | ** 3 | ** Copyright (C) 2013 Jolla Ltd. 4 | ** Contact: Pekka Vuorela 5 | ** All rights reserved. 6 | ** 7 | ** You may use this file under the terms of BSD license as follows: 8 | ** 9 | ** Redistribution and use in source and binary forms, with or without 10 | ** modification, are permitted provided that the following conditions are met: 11 | ** * Redistributions of source code must retain the above copyright 12 | ** notice, this list of conditions and the following disclaimer. 13 | ** * Redistributions in binary form must reproduce the above copyright 14 | ** notice, this list of conditions and the following disclaimer in the 15 | ** documentation and/or other materials provided with the distribution. 16 | ** * Neither the name of the Jolla Ltd nor the 17 | ** names of its contributors may be used to endorse or promote products 18 | ** derived from this software without specific prior written permission. 19 | ** 20 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 21 | ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 22 | ** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | ** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 24 | ** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 25 | ** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 26 | ** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 27 | ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 | ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | ** 31 | ****************************************************************************************/ 32 | 33 | import QtQuick 2.2 34 | import com.meego.maliitquick 1.0 35 | import com.jolla.keyboard 1.0 36 | import Sailfish.Silica 1.0 as Silica 37 | import harbour.tide.keyboard 1.0 38 | 39 | 40 | Item { 41 | id: inputHandler 42 | property Item pressedKey 43 | property Component topItem 44 | property Component verticalItem 45 | property bool active 46 | 47 | Timer { 48 | id: autorepeatTimer 49 | repeat: true 50 | 51 | onTriggered: { 52 | interval = 80 53 | if (pressedKey !== null) { 54 | _handleKeyClick(pressedKey) 55 | } else { 56 | stop() 57 | } 58 | } 59 | } 60 | 61 | Multitap { 62 | id: multitap 63 | } 64 | 65 | property var trie 66 | property bool trie_built: false 67 | property int type: 0 68 | property string name: canvas.layoutModel.get(canvas.activeIndex).name 69 | 70 | property string sql: "" 71 | property string preedit: "" 72 | property var result: [] 73 | 74 | property bool fetchMany: false 75 | 76 | signal candidatesUpdated 77 | 78 | property Item settings: Settings { } 79 | 80 | //Handle Swipe 81 | property int current: 0 82 | property var distance: [0] 83 | property bool swipe: false 84 | 85 | function _handleKeyPress(key) { 86 | pressedKey = key 87 | autorepeatTimer.stop() 88 | 89 | if (handleKeyPress()) 90 | return 91 | 92 | if (pressedKey.repeat) { 93 | autorepeatTimer.interval = 500 94 | autorepeatTimer.start() 95 | } 96 | } 97 | 98 | function _handleKeyRelease() { 99 | pressedKey = null 100 | 101 | if (handleKeyRelease()) 102 | return 103 | 104 | autorepeatTimer.stop() 105 | } 106 | 107 | function _handleKeyClick(key) { 108 | pressedKey = key 109 | 110 | if (key.keyType === KeyType.CharacterKey || key.keyType === KeyType.PopupKey) { 111 | keyboard.characterKeyCounter++ 112 | } 113 | 114 | if (handleKeyClick()) 115 | return 116 | 117 | if (pressedKey.key === Qt.Key_Multi_key) { 118 | multitap.apply(pressedKey.text) 119 | return 120 | } else { 121 | multitap.flush() 122 | } 123 | 124 | var resetShift = !keyboard.isShiftLocked 125 | 126 | if (pressedKey.key === Qt.Key_Shift) { 127 | resetShift = false 128 | } 129 | 130 | if (pressedKey.text.length) { 131 | MInputMethodQuick.sendCommit(pressedKey.text) 132 | } else if (pressedKey.key === Qt.Key_Return) { 133 | MInputMethodQuick.activateActionKey() 134 | } else if (pressedKey.key === Qt.Key_Backspace) { 135 | if (MInputMethodQuick.surroundingTextValid && MInputMethodQuick.cursorPosition == 0) { 136 | resetShift = false 137 | } 138 | 139 | MInputMethodQuick.sendKey(Qt.Key_Backspace, 0, "\b", Maliit.KeyClick) 140 | } else if (pressedKey.key === Qt.Key_Paste) { 141 | MInputMethodQuick.sendCommit(Silica.Clipboard.text) 142 | } else { 143 | resetShift = false 144 | } 145 | 146 | if (resetShift) 147 | keyboard.resetShift() 148 | } 149 | 150 | function _reset() { 151 | autorepeatTimer.stop() 152 | multitap.flush() 153 | 154 | 155 | inputHandler.fetchMany = false 156 | reset() 157 | } 158 | 159 | 160 | // called when button gets down. can be reimplemented to handle input. return true input is consumed 161 | function handleKeyPress() { 162 | return false 163 | } 164 | 165 | // called when button click was fully done or on autorepeat. can be reimplemented to handle input. 166 | // return true input was consumed. 167 | function handleKeyClick() { 168 | return false 169 | } 170 | 171 | // called when button got up either by moving out of the button or after click was done. 172 | // can be reimplemented. return true if input was consumed. 173 | function handleKeyRelease() { 174 | return false 175 | } 176 | 177 | // called when input state needs to be reset 178 | function reset() { 179 | } 180 | } 181 | -------------------------------------------------------------------------------- /dolphin/KeyBase.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Jolla ltd and/or its subsidiary(-ies). All rights reserved. 3 | * 4 | * Contact: Pekka Vuorela 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * Redistributions of source code must retain the above copyright notice, this list 10 | * of conditions and the following disclaimer. 11 | * Redistributions in binary form must reproduce the above copyright notice, this list 12 | * of conditions and the following disclaimer in the documentation and/or other materials 13 | * provided with the distribution. 14 | * Neither the name of Nokia Corporation nor the names of its contributors may be 15 | * used to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 19 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 20 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 | * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 22 | INCIDENTAL, SPECIAL, 23 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | * 29 | */ 30 | 31 | import QtQuick 2.2 32 | import com.jolla.keyboard 1.0 33 | 34 | Item { 35 | property int leftPadding 36 | property int rightPadding 37 | property int topPadding 38 | property int bottomPadding 39 | property bool pressed 40 | property bool repeat 41 | property string text // text to be send 42 | property string caption // main label on the key 43 | property string keyText: caption // currently shown text 44 | property int key: Qt.Key_unknown 45 | property bool showPopper: true 46 | property int keyType: KeyType.UnknownKey 47 | property bool active: true // button in use and shown 48 | 49 | signal clicked 50 | } 51 | -------------------------------------------------------------------------------- /dolphin/KeyboardGeometry.qml: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 Jolla Ltd. 2 | // Contact: Pekka Vuorela 3 | 4 | import QtQuick 2.2 5 | import Sailfish.Silica 1.0 6 | 7 | QtObject { 8 | // FIXME: need different scale ratio for landscape in case aspect ratio changes, now assuming 16:9 9 | property bool isLargeScreen: screen.sizeCategory > Screen.Medium 10 | property real scaleRatio: isLargeScreen ? screen.width / 580 : screen.width / 480 11 | 12 | property int keyboardWidthLandscape: screen.height 13 | property int keyboardWidthPortrait: screen.width 14 | 15 | property int keyHeightLandscape: 58*scaleRatio 16 | property int keyHeightPortrait: 80*scaleRatio 17 | property int keyRadius: 4*scaleRatio 18 | 19 | property int functionKeyWidthLandscape: 145*scaleRatio 20 | property int shiftKeyWidthLandscape: 110*scaleRatio 21 | property int shiftKeyWidthLandscapeNarrow: 98*scaleRatio 22 | property int shiftKeyWidthLandscapeSplit: 77*scaleRatio 23 | property int punctuationKeyLandscape: 120*scaleRatio 24 | property int punctuationKeyLandscapeNarrow: 80*scaleRatio 25 | property int symbolKeyWidthLandscapeNarrow: 145*scaleRatio 26 | property int symbolKeyWidthLandscapeNarrowSplit: 100*scaleRatio 27 | 28 | property int functionKeyWidthPortrait: 116*scaleRatio 29 | property int shiftKeyWidthPortrait: 72*scaleRatio 30 | property int shiftKeyWidthPortraitNarrow: 60*scaleRatio 31 | property int punctuationKeyPortait: 56*scaleRatio 32 | property int punctuationKeyPortraitNarrow: 43*scaleRatio // 3*narrow + symbol narrow == 2*non-narrow + function key 33 | property int symbolKeyWidthPortraitNarrow: 99*scaleRatio 34 | 35 | property int middleBarWidth: keyboardWidthLandscape / 4 36 | 37 | property int popperHeight: 120*scaleRatio 38 | property int popperWidth: 80*scaleRatio 39 | property int popperRadius: 10*scaleRatio 40 | property int popperFontSize: 56*scaleRatio 41 | property int popperMargin: 2 42 | 43 | property int clearPasteMargin: 50*scaleRatio 44 | property int clearPasteTouchDelta: 20*scaleRatio 45 | 46 | property int accentPopperCellWidth: 47*scaleRatio 47 | property int accentPopperMargin: (popperWidth-accentPopperCellWidth) * .5 - 1 48 | 49 | property int languageSelectionTouchDelta: 35*scaleRatio 50 | property int languageSelectionInitialDeltaSquared: 20*20*scaleRatio 51 | property int languageSelectionCellMargin: 15*scaleRatio 52 | property int languageSelectionPopupMaxWidth: isLargeScreen ? screen.width * .8 : screen.height * .75 53 | property int languageSelectionPopupContentMargins: 40*scaleRatio 54 | 55 | property int hwrLineWidth: 7*Theme.pixelRatio 56 | property int hwrCanvasHeight: 300*scaleRatio 57 | property int hwrSampleThresholdSquared: 4*4*scaleRatio 58 | property int hwrPastePreviewWidth: 100*scaleRatio 59 | } 60 | -------------------------------------------------------------------------------- /dolphin/KeyboardLayout.qml: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 Jolla Ltd. 2 | // Contact: Pekka Vuorela 3 | 4 | import QtQuick 2.2 5 | import Sailfish.Silica 1.0 6 | import harbour.tide.keyboard 1.0 7 | 8 | Column { 9 | id: layout 10 | 11 | width: parent ? parent.width : 0 12 | 13 | //Dolphin Keyboard 14 | 15 | property string primary: "" 16 | property string secondary: "" 17 | 18 | property Item settings: Settings { } 19 | 20 | property Item primaryHandler 21 | property Item secondaryHandler 22 | 23 | property Item primaryHandlerLoader: Loader { 24 | onStatusChanged: { 25 | 26 | if ( primary !== "" && status === Loader.Ready ) { 27 | primaryHandler = primaryHandlerLoader.item 28 | } 29 | } 30 | } 31 | 32 | property Item secondaryHandlerLoader: Loader { 33 | onStatusChanged: { 34 | if ( secondary !== "" && status === Loader.Ready ) { 35 | secondaryHandler = secondaryHandlerLoader.item 36 | } 37 | } 38 | } 39 | 40 | //Prevent lag in switching keyboard 41 | Timer { 42 | id: timer 43 | interval: 256 44 | onTriggered: { 45 | if ( primary !== "" ) { 46 | primaryHandlerLoader.source = "/usr/share/maliit/plugins/com/jolla/layouts/" + primary + ".qml" 47 | } 48 | 49 | if ( secondary !== "" ) { 50 | secondaryHandlerLoader.source = "/usr/share/maliit/plugins/com/jolla/" + secondary + ".qml" 51 | } 52 | } 53 | 54 | Component.onCompleted: timer.start() 55 | } 56 | 57 | property bool xt9: keyboard.inputHandler !== secondaryHandler ? false : true 58 | 59 | function init() { 60 | 61 | if ( keyboard.allowLayoutChanges && primaryHandler && secondaryHandler ) { 62 | 63 | if ( keyboard.inputHandler !== primaryHandler || keyboard.inputHandler !== secondaryHandler ) { 64 | 65 | var oldHandler = keyboard.inputHandler 66 | oldHandler.active = false 67 | 68 | if ( settings.enMode === true && keyboard.inputHandler !== primaryHandler ) { 69 | 70 | keyboard.inputHandler = primaryHandler 71 | keyboard.inputHandler.active = true 72 | console.warn("primaryHandler") 73 | 74 | } else if ( settings.enMode === true && keyboard.inputHandler !== secondaryHandler ) { 75 | 76 | keyboard.inputHandler = secondaryHandler 77 | keyboard.inputHandler.active = true 78 | console.warn("secondaryHandler") 79 | } 80 | } 81 | } 82 | } 83 | 84 | Image { 85 | visible: settings.background !== "" ? true: false 86 | anchors.fill: parent 87 | parent: keyboard 88 | fillMode: Image.PreserveAspectCrop 89 | source: settings.background 90 | opacity: settings.transparency 91 | z: -4 92 | } 93 | 94 | Rectangle { 95 | z: -2 96 | visible: false 97 | parent: keyboard 98 | anchors.fill: parent 99 | gradient: Gradient { 100 | GradientStop { position: 0; color: Theme.rgba(Theme.highlightDimmerColor, 0.2) } 101 | GradientStop { position: 1; color: Theme.rgba(Theme.highlightBackgroundColor, 0.8) } 102 | } 103 | } 104 | property bool capsLockSupported: true 105 | property string type 106 | property bool portraitMode 107 | property int keyHeight 108 | property int punctuationKeyWidth 109 | property int punctuationKeyWidthNarrow 110 | property int shiftKeyWidth 111 | property int functionKeyWidth 112 | property int shiftKeyWidthNarrow 113 | property int symbolKeyWidthNarrow 114 | property QtObject attributes: visible ? keyboard : keyboard.emptyAttributes 115 | property string languageCode 116 | property string inputMode 117 | property int avoidanceWidth 118 | property bool splitActive 119 | property bool splitSupported 120 | property bool useTopItem: !splitActive 121 | 122 | Connections { 123 | target: MInputMethodQuick 124 | onCursorPositionChanged: { 125 | console.warn("onCursorPositionChanged") 126 | } 127 | 128 | onFocusTargetChanged: { 129 | console.warn("onFocusTargetChanged") 130 | //init() 131 | } 132 | 133 | onInputMethodReset: { 134 | console.warn("onInputMethodRest") 135 | //init() 136 | } 137 | } 138 | 139 | Connections { 140 | target: keyboard 141 | onFullyOpenChanged: { 142 | if ( keyboard.fullyOpen ) { 143 | console.warn("onFullyOpenChanged") 144 | //init() 145 | } 146 | } 147 | 148 | onSplitEnabledChanged: { 149 | console.warn("onSplitEnabledChanged") 150 | //init() 151 | updateSizes() 152 | } 153 | 154 | } 155 | 156 | Component.onCompleted: { 157 | console.warn("Component.onCompleted") 158 | updateSizes() 159 | //init() 160 | } 161 | 162 | onWidthChanged: { 163 | console.warn("onWidthChanged") 164 | updateSizes() 165 | //init() 166 | } 167 | 168 | onPortraitModeChanged: { 169 | console.warn("onPortraitModeChanged") 170 | updateSizes() 171 | //init() 172 | 173 | } 174 | 175 | Binding on portraitMode { 176 | when: visible 177 | value: keyboard.portraitMode 178 | } 179 | 180 | 181 | 182 | function updateSizes () { 183 | if ( width === 0 ) { 184 | return 185 | } 186 | 187 | if ( portraitMode ) { 188 | keyHeight = geometry.keyHeightPortrait * settings.scale 189 | punctuationKeyWidth = geometry.punctuationKeyPortait 190 | punctuationKeyWidthNarrow = geometry.punctuationKeyPortraitNarrow 191 | shiftKeyWidth = geometry.shiftKeyWidthPortrait 192 | functionKeyWidth = geometry.functionKeyWidthPortrait 193 | shiftKeyWidthNarrow = geometry.shiftKeyWidthPortraitNarrow 194 | symbolKeyWidthNarrow = geometry.symbolKeyWidthPortraitNarrow 195 | avoidanceWidth = 0 196 | splitActive = false 197 | } else { 198 | keyHeight = geometry.keyHeightLandscape * settings.scale 199 | punctuationKeyWidth = geometry.punctuationKeyLandscape 200 | punctuationKeyWidthNarrow = geometry.punctuationKeyLandscapeNarrow 201 | functionKeyWidth = geometry.functionKeyWidthLandscape 202 | 203 | var shouldSplit = keyboard.splitEnabled && splitSupported 204 | if ( shouldSplit ) { 205 | avoidanceWidth = geometry.middleBarWidth 206 | shiftKeyWidth = geometry.shiftKeyWidthLandscapeSplit 207 | shiftKeyWidthNarrow = geometry.shiftKeyWidthLandscapeSplit 208 | symbolKeyWidthNarrow = geometry.symbolKeyWidthLandscapeNarrowSplit 209 | } else { 210 | avoidanceWidth = 0 211 | shiftKeyWidth = geometry.shiftKeyWidthLandscape 212 | shiftKeyWidthNarrow = geometry.shiftKeyWidthLandscapeNarrow 213 | symbolKeyWidthNarrow = geometry.symbolKeyWidthLandscapeNarrow 214 | } 215 | splitActive = shouldSplit 216 | } 217 | 218 | var i 219 | var child 220 | var maxButton = width 221 | 222 | for (i = 0; i < children.length; ++i) { 223 | child = children[i] 224 | child.width = width 225 | if (child.hasOwnProperty("followRowHeight") && child.followRowHeight) { 226 | child.height = keyHeight 227 | } 228 | 229 | if (child.maximumBasicButtonWidth !== undefined) { 230 | maxButton = Math.min(child.maximumBasicButtonWidth(width), maxButton) 231 | } 232 | } 233 | 234 | for (i = 0; i < children.length; ++i) { 235 | child = children[i] 236 | 237 | if (child.relayout !== undefined) { 238 | child.relayout(maxButton) 239 | } 240 | } 241 | } 242 | } 243 | -------------------------------------------------------------------------------- /dolphin/KeyboardRow.qml: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 Jolla Ltd. 2 | // Contact: Pekka Vuorela 3 | 4 | import QtQuick 2.2 5 | 6 | Item { 7 | 8 | //Doplhin Keyboard 9 | property real ratio: 1 10 | 11 | property bool followRowHeight: true 12 | property int splitIndex: -1 13 | 14 | // calculates maximum width for a "basic" button 15 | function maximumBasicButtonWidth(shareableWidth) { 16 | if (avoidanceWidth > 0) { 17 | var split = splitIndex > 0 ? splitIndex : Math.floor(children.length / 2) 18 | shareableWidth = (shareableWidth - avoidanceWidth) / 2 19 | var first = _maximumButtonWidthPart(shareableWidth, 0, split) 20 | var second = _maximumButtonWidthPart(shareableWidth, split, children.length) 21 | return Math.min(first, second) 22 | } else { 23 | return _maximumButtonWidthPart(shareableWidth, 0, children.length) 24 | } 25 | } 26 | 27 | function _maximumButtonWidthPart(shareableWidth, startIndex, endIndex) { 28 | var basicButtonCount = 0 29 | var originalWidth = shareableWidth 30 | var i 31 | 32 | for (i = startIndex; i < endIndex; ++i) { 33 | var child = children[i] 34 | if (!child.active) { 35 | continue 36 | } 37 | 38 | if (_isBasicButton(child)) { 39 | basicButtonCount++ 40 | } else { 41 | shareableWidth -= child.implicitWidth 42 | } 43 | } 44 | 45 | return basicButtonCount !== 0 ? shareableWidth / basicButtonCount 46 | : originalWidth 47 | } 48 | 49 | function relayout(basicButtonWidth) { 50 | if (avoidanceWidth > 1) { 51 | // get middle and layout both sides separately 52 | var shareableWidth = width - avoidanceWidth 53 | var split = splitIndex > 0 ? splitIndex : Math.floor(children.length / 2) 54 | _relayoutPart(basicButtonWidth, 0, split, 0, shareableWidth / 2) 55 | _relayoutPart(basicButtonWidth, split, children.length, width / 2 + avoidanceWidth / 2, shareableWidth / 2) 56 | 57 | } else { 58 | _relayoutPart(basicButtonWidth, 0, children.length, 0, width) 59 | } 60 | } 61 | 62 | function _relayoutPart(basicButtonWidth, startIndex, endIndex, startX, shareableWidth) { 63 | var expandingKeys = [] 64 | var child 65 | var i 66 | 67 | for (i = startIndex; i < endIndex; ++i) { 68 | child = children[i] 69 | if (!child.active) { 70 | child.visible = false 71 | continue 72 | } 73 | 74 | child.visible = true 75 | child.height = parent.keyHeight * ratio 76 | 77 | if (_isExpandingKey(child)) { 78 | expandingKeys.push(child) 79 | } else if (_isBasicButton(child)) { 80 | child.width = basicButtonWidth 81 | child.leftPadding = 0 82 | child.rightPadding = 0 83 | child.implicitSeparator = true 84 | shareableWidth -= basicButtonWidth 85 | } else { 86 | child.width = undefined 87 | shareableWidth -= child.implicitWidth 88 | } 89 | } 90 | 91 | if (expandingKeys.length > 0) { 92 | // allocate extra space to expanding keys 93 | for (i = 0; i < expandingKeys.length; ++i) { 94 | expandingKeys[i].width = shareableWidth / expandingKeys.length 95 | } 96 | } else { 97 | var extra = Math.max(shareableWidth / 2, 0) 98 | 99 | // allocate extra space to first and last basic key (assuming separate keys) 100 | for (i = startIndex; i < endIndex; ++i) { 101 | child = children[i] 102 | 103 | if (child.active && _isBasicButton(child)) { 104 | child.width = basicButtonWidth + extra 105 | child.leftPadding = extra 106 | break 107 | } 108 | } 109 | 110 | for (i = endIndex - 1; i >= startIndex; --i) { 111 | child = children[i] 112 | if (child.active && _isBasicButton(child)) { 113 | child.implicitSeparator = false 114 | child.width = basicButtonWidth + extra 115 | child.rightPadding = extra 116 | break 117 | } 118 | } 119 | } 120 | 121 | // final pass, set X coordinates for all children 122 | var x = startX 123 | for (i = startIndex; i < endIndex; ++i) { 124 | child = children[i] 125 | if (!child.active) { 126 | continue 127 | } 128 | 129 | child.x = x 130 | x += child.width 131 | } 132 | } 133 | 134 | function _isBasicButton(item) { 135 | // Hack: relying on property 136 | return item.hasOwnProperty("symView") && !item.fixedWidth 137 | } 138 | 139 | function _isExpandingKey(item) { 140 | return item.hasOwnProperty("expandingKey") && item.expandingKey 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /dolphin/LanguageSelectionCell.qml: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 Jolla Ltd. 2 | // Contact: Pekka Vuorela 3 | 4 | import QtQuick 2.2 5 | import Sailfish.Silica 1.0 6 | 7 | Item { 8 | id: selectionCell 9 | 10 | property int index 11 | property bool active: popup.activeCell === index 12 | property alias text: textItem.text 13 | 14 | width: textItem.width + geometry.languageSelectionCellMargin * 2 15 | height: Theme.itemSizeSmall 16 | 17 | Text { 18 | id: textItem 19 | width: paintedWidth 20 | height: parent.height 21 | anchors.centerIn: parent 22 | horizontalAlignment: Text.AlignHCenter 23 | verticalAlignment: Text.AlignVCenter 24 | color: Theme.primaryColor 25 | opacity: selectionCell.active ? 1 : .35 26 | font.family: Theme.fontFamily 27 | font.pixelSize: Theme.fontSizeMedium 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /dolphin/LanguageSelectionPopup.qml: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 Jolla Ltd. 2 | // Contact: Pekka Vuorela 3 | 4 | import QtQuick 2.2 5 | import Sailfish.Silica 1.0 6 | import com.jolla.keyboard 1.0 7 | 8 | Rectangle { 9 | id: popup 10 | 11 | property int activeCell: -1 12 | property bool inInitialPosition 13 | property int pointId 14 | property alias opening: openAnimation.running 15 | property real bottomLine 16 | property int targetHeight 17 | 18 | y: bottomLine - height 19 | visible: false 20 | radius: geometry.popperRadius 21 | color: Qt.darker(Theme.highlightBackgroundColor, 1.3) 22 | clip: openAnimation.running 23 | 24 | Column { 25 | id: contentColumn 26 | width: parent.width 27 | anchors.verticalCenter: parent.verticalCenter 28 | } 29 | 30 | NumberAnimation on height { 31 | id: openAnimation 32 | duration: 100 33 | easing.type: Easing.OutQuad 34 | to: popup.targetHeight + Theme.paddingLarge 35 | } 36 | 37 | Component { 38 | id: listRow 39 | Row { 40 | x: parent ? (parent.width - width) * .5 : 0 41 | height: Theme.itemSizeSmall 42 | } 43 | } 44 | 45 | SequentialAnimation { 46 | id: fadeAnimation 47 | NumberAnimation { 48 | duration: 100 49 | to: 0 50 | target: popup 51 | property: "opacity" 52 | } 53 | ScriptAction { 54 | script: { 55 | visible = false 56 | contentColumn.children = [] 57 | } 58 | } 59 | } 60 | 61 | function show(touchPoint) { 62 | fadeAnimation.stop() 63 | inInitialPosition = true 64 | pointId = touchPoint.pointId 65 | height = 0 66 | targetHeight = 0 67 | bottomLine = parent.mapFromItem(touchPoint.pressedKey, 0, 0).y - Theme.paddingLarge 68 | canvas.captureFullScreen() 69 | 70 | activeCell = canvas.activeIndex 71 | 72 | var maxAllowedWidth = Math.min(parent.width - Theme.paddingSmall * 2, 73 | geometry.languageSelectionPopupMaxWidth) 74 | var maxContentWidth = maxAllowedWidth - geometry.languageSelectionPopupContentMargins 75 | var cellComponent = Qt.createComponent("LanguageSelectionCell.qml"); 76 | var row = null 77 | var maxRowWidth = 0 78 | var cells = new Array 79 | var itemsPerRow = new Array 80 | var itemsInRow = 0 81 | var rowWidth = 0 82 | 83 | // layout cells. We don't use Flow as the (possible) uneven row needs 84 | // to be topmost and rows need to be center aligned 85 | 86 | // first create cells and calculate how many cells 87 | // fit in a row. Start from the last cell and remember the cell count 88 | // for each row 89 | for (var i = canvas.layoutModel.count-1; i >= 0; --i) { 90 | if (!canvas.layoutModel.get(i).enabled) { 91 | continue 92 | } 93 | 94 | if (canvas.layoutModel.enabledCount === 2 && i !== canvas.activeIndex) { 95 | // In case there's two enabled languages, highlight the inactive one 96 | // to allow quick switching to that layout. 97 | activeCell = i 98 | } 99 | 100 | var cell = cellComponent.createObject(null, 101 | {"index": i, 102 | "text": canvas.layoutModel.get(i).name}) 103 | cells.push(cell) 104 | 105 | if (rowWidth + cell.width > maxContentWidth) { 106 | if (rowWidth > maxRowWidth) { 107 | maxRowWidth = rowWidth 108 | } 109 | itemsPerRow.push(itemsInRow) 110 | itemsInRow = 0 111 | rowWidth = 0 112 | } 113 | 114 | itemsInRow++ 115 | rowWidth += cell.width 116 | } 117 | 118 | if (itemsInRow > 0) { 119 | // close last row 120 | if (rowWidth > maxRowWidth) { 121 | maxRowWidth = rowWidth 122 | } 123 | itemsPerRow.push(itemsInRow) 124 | } 125 | 126 | // then create rows and insert cells 127 | var cellHead = cells.length 128 | for (var j = itemsPerRow.length - 1; j >= 0; j--) { 129 | itemsInRow = itemsPerRow[j] 130 | cellHead -= itemsInRow 131 | 132 | row = listRow.createObject(contentColumn) 133 | targetHeight += row.height 134 | 135 | // the order of cells in a row needs to be swapped to 136 | // maintain alphabetical order 137 | for (var k = cellHead + itemsInRow - 1; k >= cellHead; --k) { 138 | cell = cells[k] 139 | cell.parent = row 140 | row.width += cell.width 141 | } 142 | } 143 | 144 | width = Math.min(maxAllowedWidth, maxRowWidth + geometry.languageSelectionPopupContentMargins) 145 | if (parent.width - width <= Theme.paddingLarge) { 146 | // if the width of the popup is "almost" same as width of the parent, center align 147 | x = (parent.width - width) * .5 148 | } else { 149 | // else center align around the press point 150 | var xPos = Math.max(touchPoint.x - width * .5, Theme.paddingSmall) 151 | x = Math.min(parent.width - width - Theme.paddingSmall, xPos) 152 | } 153 | 154 | opacity = 1 155 | visible = true 156 | openAnimation.start() 157 | } 158 | function hide() { 159 | if (opening) { 160 | openAnimation.stop() 161 | visible = false 162 | contentColumn.children = [] 163 | } else if (visible) { 164 | fadeAnimation.start() 165 | canvas.updateIMArea() 166 | } 167 | } 168 | function handleMove(touchPoint) { 169 | if (touchPoint.pointId !== pointId) 170 | return 171 | 172 | if (inInitialPosition) { 173 | var deltaX = touchPoint.x-touchPoint.startX 174 | var deltaY = touchPoint.y-touchPoint.startY 175 | if (deltaX*deltaX + deltaY*deltaY < 176 | geometry.languageSelectionInitialDeltaSquared) { 177 | return 178 | } 179 | } 180 | 181 | inInitialPosition = false 182 | 183 | var oldActiveCell = activeCell 184 | 185 | var yInContent = parent.mapToItem(popup, touchPoint.x, touchPoint.y).y 186 | if (yInContent < 0 || yInContent > height) { 187 | activeCell = -1 188 | } 189 | 190 | var item = contentColumn 191 | do { 192 | if (item.hasOwnProperty("index")) { 193 | activeCell = item.index 194 | break 195 | } 196 | var pos = parent.mapToItem(item, touchPoint.x, touchPoint.y) 197 | pos.y -= geometry.languageSelectionTouchDelta 198 | item = item.childAt(pos.x, pos.y) 199 | } while (item); 200 | 201 | if (oldActiveCell !== activeCell && activeCell >= 0) { 202 | SampleCache.play("/usr/share/sounds/jolla-ambient/stereo/keyboard_letter.wav") 203 | buttonPressEffect.play() 204 | } 205 | } 206 | } 207 | -------------------------------------------------------------------------------- /dolphin/LayoutLoader.qml: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 Jolla Ltd. 2 | // Contact: Pekka Vuorela 3 | 4 | import QtQuick 2.2 5 | 6 | Loader { 7 | property int index: -1 8 | property int pendingIndex: -1 9 | 10 | width: parent.width 11 | source: index >= 0 ? "/usr/share/maliit/plugins/com/jolla/layouts/" + canvas.layoutModel.get(index).layout : "" 12 | onLoaded: { 13 | item.languageCode = canvas.layoutModel.count > 1 ? canvas.layoutModel.get(index).languageCode : "" 14 | if (pendingIndex >= 0) { 15 | index = pendingIndex 16 | pendingIndex = -1 17 | } else { 18 | layoutRow.startTransition() 19 | } 20 | } 21 | onVisibleChanged: if (item) item.visible = visible 22 | asynchronous: true 23 | } 24 | -------------------------------------------------------------------------------- /dolphin/LayoutRow.qml: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 Jolla Ltd. 2 | // Contact: Pekka Vuorela 3 | 4 | import QtQuick 2.2 5 | 6 | Item { 7 | id: layoutRow 8 | 9 | property int nextActiveIndex: -1 10 | property Item layout: _loader1.item 11 | property LayoutLoader loader: _loader1 12 | property LayoutLoader nextLoader: _loader2 13 | property bool loading: _loader1.status === Loader.Loading || _loader2.status === Loader.Loading 14 | property alias transitionRunning: layoutTransition.running 15 | 16 | width: parent.width 17 | 18 | LayoutLoader { 19 | id: _loader1 20 | index: canvas.activeIndex 21 | } 22 | 23 | LayoutLoader { 24 | id: _loader2 25 | } 26 | 27 | SequentialAnimation { 28 | id: layoutTransition 29 | ParallelAnimation { 30 | NumberAnimation { 31 | duration: 200 32 | target: layoutRow.layout 33 | property: "x" 34 | to: layoutRow.loader ? -layoutRow.loader.width : 0 35 | easing.type: Easing.OutCubic 36 | } 37 | NumberAnimation { 38 | duration: 200 39 | target: layoutRow.nextLoader ? layoutRow.nextLoader.item : null 40 | property: "x" 41 | to: 0 42 | easing.type: Easing.OutCubic 43 | } 44 | } 45 | ScriptAction { 46 | script: { 47 | layoutRow.finalizeTransition() 48 | canvas.saveCurrentLayoutSetting() 49 | } 50 | } 51 | } 52 | 53 | function switchLayout(layoutIndex) { 54 | if (layoutIndex >= 0 && layoutIndex !== canvas.activeIndex) { 55 | nextActiveIndex = layoutIndex 56 | if (nextLoader.status === Loader.Loading) { 57 | // loader is already busy, queue the layout 58 | nextLoader.pendingIndex = layoutIndex 59 | return 60 | } 61 | nextLoader.visible = false 62 | nextLoader.index = layoutIndex 63 | } 64 | } 65 | 66 | function startTransition() { 67 | if (nextActiveIndex >= 0) { 68 | nextLoader.item.updateSizes() 69 | nextLoader.visible = true 70 | 71 | if (!MInputMethodQuick.active) { 72 | nextLoader.item.x = 0 73 | finalizeTransition() 74 | } else { 75 | nextLoader.item.x = loader.x + loader.width 76 | layoutTransition.start() 77 | } 78 | } 79 | } 80 | 81 | function finalizeTransition() { 82 | layoutRow.layout = layoutRow.nextLoader.item 83 | if (keyboard.inputHandler) { 84 | keyboard.inputHandler.active = false // this input handler might not handle new layout 85 | } 86 | canvas.activeIndex = layoutRow.nextActiveIndex 87 | keyboard.updateInputHandler() 88 | keyboard.resetKeyboard() 89 | keyboard.applyAutocaps() 90 | var oldLoader = layoutRow.loader 91 | layoutRow.loader = layoutRow.nextLoader 92 | layoutRow.nextLoader = oldLoader 93 | oldLoader.index = -1 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /dolphin/LayoutSwipe.qml: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 Jolla Ltd. 2 | // Contact: Pekka Vuorela 3 | 4 | import QtQuick 2.2 5 | 6 | Column { 7 | width: parent ? parent.width : 0 8 | 9 | property string type 10 | property bool portraitMode: visible ? keyboard.portraitMode : portraitMode 11 | property int keyHeight 12 | property int punctuationKeyWidth 13 | property int punctuationKeyWidthNarrow 14 | property int shiftKeyWidth 15 | property int spacebarKeyWidth 16 | property int functionKeyWidth 17 | property int shiftKeyWidthNarrow 18 | property int symbolKeyWidthNarrow 19 | property QtObject attributes: visible ? keyboard : keyboard.emptyAttributes 20 | property string languageCode 21 | property string inputMode 22 | 23 | Component.onCompleted: updateSizes() 24 | onWidthChanged: updateSizes() 25 | onPortraitModeChanged: updateSizes() 26 | 27 | function updateSizes () { 28 | if (width === 0) { 29 | return 30 | } 31 | 32 | if (portraitMode) { 33 | keyHeight = geometry.keyHeightPortrait 34 | punctuationKeyWidth = geometry.punctuationKeyPortait 35 | punctuationKeyWidthNarrow = geometry.punctuationKeyPortraitNarrow 36 | shiftKeyWidth = geometry.shiftKeyWidthPortrait 37 | spacebarKeyWidth = geometry.spacebarKeyWidthPortrait 38 | functionKeyWidth = geometry.functionKeyWidthPortrait 39 | shiftKeyWidthNarrow = geometry.shiftKeyWidthPortraitNarrow 40 | symbolKeyWidthNarrow = geometry.symbolKeyWidthPortraitNarrow 41 | } else { 42 | keyHeight = geometry.keyHeightLandscape 43 | punctuationKeyWidth = geometry.punctuationKeyLandscape 44 | punctuationKeyWidthNarrow = geometry.punctuationKeyLandscapeNarrow 45 | shiftKeyWidth = geometry.shiftKeyWidthLandscape 46 | spacebarKeyWidth = geometry.spacebarKeyWidthLandscape 47 | functionKeyWidth = geometry.functionKeyWidthLandscape 48 | shiftKeyWidthNarrow = geometry.shiftKeyWidthLandscapeNarrow 49 | symbolKeyWidthNarrow = geometry.symbolKeyWidthLandscapeNarrow 50 | } 51 | 52 | var i 53 | var child 54 | var maxButton = width 55 | 56 | for (i = 0; i < children.length; ++i) { 57 | child = children[i] 58 | child.width = width 59 | if (child.hasOwnProperty("basicButtonSize")) { 60 | child.height = keyHeight 61 | } 62 | 63 | if (child.maximumBasicButtonWidth !== undefined) { 64 | maxButton = Math.min(child.maximumBasicButtonWidth(width), maxButton) 65 | } 66 | } 67 | 68 | for (i = 0; i < children.length; ++i) { 69 | child = children[i] 70 | 71 | if (child.hasOwnProperty("basicButtonSize")) { 72 | child.basicButtonSize = maxButton 73 | } 74 | 75 | if (child.relayout !== undefined) { 76 | child.relayout() 77 | } 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /dolphin/More.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.2 2 | import Sailfish.Silica 1.0 3 | import com.jolla.keyboard 1.0 4 | 5 | BackgroundItem { 6 | id: footer 7 | width: 52 8 | height: parent.height 9 | visible: ( result.length >= 8 && !fetchMany && !keyboard.inSymView && !keyboard.inSymView2 ) 10 | anchors.top: parent.top 11 | x: parent.width - 52 12 | 13 | z: 768 14 | 15 | Image { 16 | source: "image://theme/icon-lock-more?" + Theme.highlightColor 17 | anchors.centerIn: parent 18 | z: 16 19 | } 20 | 21 | onPressed: { 22 | buttonPressEffect.play() 23 | SampleCache.play("/usr/share/sounds/jolla-ambient/stereo/keyboard_letter.wav") 24 | } 25 | 26 | onClicked: { 27 | 28 | if ( preedit !== "" && result.length > 0 && result.length <= 16 ) { 29 | applyMoreWord() 30 | console.warn(result) 31 | //database.enter() 32 | } 33 | 34 | fetchMany = true 35 | 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /dolphin/MultiCharacterKey.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. 3 | * Copyright (C) 2012-2013 Jolla Ltd. 4 | * 5 | * Contact: Pekka Vuorela 6 | * 7 | * Redistribution and use in source and binary forms, with or without modification, 8 | * are permitted provided that the following conditions are met: 9 | * 10 | * Redistributions of source code must retain the above copyright notice, this list 11 | * of conditions and the following disclaimer. 12 | * Redistributions in binary form must reproduce the above copyright notice, this list 13 | * of conditions and the following disclaimer in the documentation and/or other materials 14 | * provided with the distribution. 15 | * Neither the name of Nokia Corporation nor the names of its contributors may be 16 | * used to endorse or promote products derived from this software without specific 17 | * prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 23 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | * 29 | */ 30 | 31 | import QtQuick 2.2 32 | import com.jolla.keyboard 1.0 33 | import Sailfish.Silica 1.0 34 | 35 | KeyBase { 36 | id: root 37 | 38 | property string key 39 | property string captionShifted 40 | property string symView 41 | property string symView2 42 | property string symView3 43 | property string symView4 44 | property int separator: SeparatorState.AutomaticSeparator 45 | property bool implicitSeparator: true // set by layouting 46 | property bool showHighlight: true 47 | property string accents 48 | property string accentsShifted 49 | property string nativeAccents // accents considered native to the written language. not rendered. 50 | property string nativeAccentsShifted 51 | property bool fixedWidth 52 | property alias useBoldFont: primary.font.bold 53 | 54 | keyType: KeyType.CharacterKey 55 | text: primary.text 56 | keyText: primary.text 57 | 58 | Label { 59 | id: primary 60 | anchors.top: parent.top 61 | anchors.topMargin: Theme.paddingMedium * settings.scale 62 | anchors.horizontalCenter: parent.horizontalCenter 63 | anchors.horizontalCenterOffset: (leftPadding - rightPadding) / 2 64 | horizontalAlignment: Text.AlignHCenter 65 | verticalAlignment: Text.AlignVCenter 66 | textFormat: Text.PlainText 67 | font.pixelSize: Theme.fontSizeMedium * settings.scale 68 | color: pressed ? Theme.highlightColor : Theme.primaryColor 69 | text: attributes.inSymView && symView.length > 0 ? ( 70 | attributes.inSymView2 ? ( xt9 ? symView2 : symView4 ) : ( 71 | xt9 ? symView : symView3 ) ) : ( 72 | attributes.isShifted && xt9 || settings.fusion === true ? 73 | captionShifted : ( xt9 || settings.fusion === true ? caption: key ) ) 74 | } 75 | 76 | Label { 77 | id: secondary 78 | visible: keyboard.portraitMode ? true : false 79 | anchors.bottom: parent.bottom 80 | anchors.bottomMargin: Theme.paddingMedium * settings.scale 81 | anchors.horizontalCenter: parent.horizontalCenter 82 | anchors.horizontalCenterOffset: (leftPadding - rightPadding) / 2 83 | horizontalAlignment: Text.AlignHCenter 84 | verticalAlignment: Text.AlignVCenter 85 | textFormat: Text.PlainText 86 | font.pixelSize: Theme.fontSizeTiny * settings.scale 87 | color: Theme.secondaryColor 88 | opacity: 0.8 89 | text: xt9 ? key : ( attributes.isShifted ? captionShifted : caption ) 90 | } 91 | 92 | 93 | Image { 94 | source: "graphic-keyboard-highlight-top.png" 95 | anchors.right: parent.right 96 | visible: (separator === SeparatorState.AutomaticSeparator && implicitSeparator) 97 | || separator === SeparatorState.VisibleSeparator 98 | } 99 | 100 | Rectangle { 101 | anchors.fill: parent 102 | z: -1 103 | color: Theme.highlightBackgroundColor 104 | opacity: 0.6 105 | visible: pressed && showHighlight 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /dolphin/Multitap.qml: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 Jolla Ltd. 2 | // Contact: Pekka Vuorela 3 | 4 | import QtQuick 2.2 5 | import com.meego.maliitquick 1.0 6 | 7 | QtObject { 8 | property string characters 9 | property int index: -1 10 | 11 | property Timer timer: Timer { 12 | interval: 1000 13 | onTriggered: commit() 14 | } 15 | 16 | function commit() { 17 | if (index < characters.length) { 18 | MInputMethodQuick.sendCommit(characters.charAt(index)) 19 | } else { 20 | console.log("Warning: multitap commit triggered with invalid cycle set") 21 | } 22 | 23 | timer.stop() 24 | index = -1 25 | characters = "" 26 | } 27 | 28 | function flush() { 29 | if (timer.running) { 30 | commit() 31 | } 32 | } 33 | 34 | function reset() { 35 | timer.stop() 36 | index = -1 37 | characters = "" 38 | } 39 | 40 | function apply(candidates) { 41 | if (candidates === "") { 42 | console.log("Warning: multitap called with empty cycle set") 43 | } 44 | 45 | if (candidates !== characters) { 46 | flush() 47 | } 48 | 49 | characters = candidates 50 | index++ 51 | if (index >= characters.length) { 52 | index = 0 53 | } 54 | 55 | MInputMethodQuick.sendPreedit(characters.charAt(index)) 56 | timer.restart() 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /dolphin/NumberKey.qml: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 Jolla Ltd. 2 | // Contact: Pekka Vuorela 3 | 4 | import QtQuick 2.2 5 | 6 | CharacterKey { 7 | property bool landscape 8 | 9 | captionShifted: caption 10 | showPopper: false 11 | height: geometry.keyHeightPortrait // not changing 12 | width: landscape ? geometry.keyboardWidthLandscape / 10 13 | : geometry.keyboardWidthPortrait / 4 14 | } 15 | -------------------------------------------------------------------------------- /dolphin/NumberLayoutLandscape.qml: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 Jolla Ltd. 2 | // Contact: Pekka Vuorela 3 | 4 | import QtQuick 2.2 5 | import Sailfish.Silica 1.0 as Silica 6 | 7 | KeyboardLayout { 8 | id: main 9 | 10 | width: geometry.keyboardWidthLandscape 11 | height: 2 * geometry.keyHeightPortrait 12 | 13 | Row { 14 | NumberKey { 15 | caption: "1" 16 | landscape: true 17 | } 18 | NumberKey { 19 | caption: "2" 20 | landscape: true 21 | } 22 | NumberKey { 23 | caption: "3" 24 | landscape: true 25 | } 26 | NumberKey { 27 | caption: "4" 28 | landscape: true 29 | } 30 | NumberKey { 31 | caption: "5" 32 | landscape: true 33 | } 34 | NumberKey { 35 | caption: "6" 36 | landscape: true 37 | } 38 | NumberKey { 39 | caption: "7" 40 | landscape: true 41 | } 42 | NumberKey { 43 | caption: "8" 44 | landscape: true 45 | } 46 | NumberKey { 47 | caption: "9" 48 | landscape: true 49 | } 50 | NumberKey { 51 | caption: "0" 52 | landscape: true 53 | separator: false 54 | } 55 | } 56 | 57 | Row { 58 | x: 2 * (main.width / 10) 59 | 60 | NumberKey { 61 | landscape: true 62 | enabled: Silica.Clipboard.hasText 63 | opacity: enabled ? (pressed ? 0.6 : 1.0) 64 | : 0.3 65 | key: Qt.Key_Paste 66 | 67 | Image { 68 | anchors.centerIn: parent 69 | source: "image://theme/icon-m-clipboard?" 70 | + (parent.pressed ? Silica.Theme.highlightColor : Silica.Theme.primaryColor) 71 | } 72 | } 73 | NumberKey { 74 | landscape: true 75 | key: Qt.Key_Multi_key 76 | caption: "+/-" 77 | text: "+-" 78 | } 79 | NumberKey { 80 | landscape: true 81 | caption: Qt.locale().decimalPoint 82 | separator: false 83 | } 84 | SpacebarKey { 85 | width: main.width / 5 86 | height: geometry.keyHeightPortrait 87 | } 88 | BackspaceKey { 89 | width: main.width / 10 90 | height: geometry.keyHeightPortrait 91 | } 92 | EnterKey { 93 | width: main.width / 5 94 | height: geometry.keyHeightPortrait 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /dolphin/NumberLayoutPortrait.qml: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 Jolla Ltd. 2 | // Contact: Pekka Vuorela 3 | 4 | import QtQuick 2.2 5 | import Sailfish.Silica 1.0 as Silica 6 | 7 | KeyboardLayout { 8 | id: main 9 | 10 | portraitMode: true 11 | width: geometry.keyboardWidthPortrait 12 | height: 4 * geometry.keyHeightPortrait 13 | 14 | Row { 15 | NumberKey { 16 | caption: "1" 17 | } 18 | NumberKey { 19 | caption: "2" 20 | } 21 | NumberKey { 22 | caption: "3" 23 | } 24 | NumberKey { 25 | enabled: Silica.Clipboard.hasText 26 | separator: false 27 | opacity: enabled ? (pressed ? 0.6 : 1.0) 28 | : 0.3 29 | key: Qt.Key_Paste 30 | 31 | Image { 32 | anchors.centerIn: parent 33 | source: "image://theme/icon-m-clipboard?" 34 | + (parent.pressed ? Silica.Theme.highlightColor : Silica.Theme.primaryColor) 35 | } 36 | } 37 | } 38 | 39 | Row { 40 | NumberKey { 41 | caption: "4" 42 | } 43 | NumberKey { 44 | caption: "5" 45 | } 46 | NumberKey { 47 | caption: "6" 48 | } 49 | NumberKey { 50 | separator: false 51 | key: Qt.Key_Multi_key 52 | caption: "+/-" 53 | text: "+-" 54 | } 55 | } 56 | 57 | Row { 58 | NumberKey { 59 | caption: "7" 60 | } 61 | NumberKey { 62 | caption: "8" 63 | } 64 | NumberKey { 65 | caption: "9" 66 | } 67 | BackspaceKey { 68 | width: main.width / 4 69 | height: geometry.keyHeightPortrait 70 | separator: false 71 | } 72 | } 73 | 74 | Row { 75 | NumberKey { 76 | caption: Qt.locale().decimalPoint 77 | } 78 | NumberKey { 79 | caption: "0" 80 | } 81 | SpacebarKey { 82 | width: main.width / 4 83 | height: geometry.keyHeightPortrait 84 | } 85 | EnterKey { 86 | width: main.width / 4 87 | height: geometry.keyHeightPortrait 88 | separator: false 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /dolphin/PasteButton.qml: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013-2015 Jolla Ltd. 2 | // Contact: Pekka Vuorela 3 | 4 | import QtQuick 2.2 5 | import Sailfish.Silica 1.0 6 | 7 | PasteButtonBase { 8 | id: pasteContainer 9 | 10 | property int previewWidthLimit: Screen.width / 2 11 | 12 | Row { 13 | id: pasteRow 14 | height: parent.height 15 | anchors.right: parent.right 16 | anchors.rightMargin: Theme.paddingMedium 17 | 18 | Label { 19 | id: pasteLabel 20 | 21 | height: pasteContainer.height 22 | width: Math.min(pasteContainer.previewWidthLimit, implicitWidth) 23 | font { pixelSize: Theme.fontSizeSmall; family: Theme.fontFamily } 24 | color: pasteContainer.highlighted ? Theme.highlightColor : Theme.primaryColor 25 | truncationMode: TruncationMode.Fade 26 | verticalAlignment: Text.AlignVCenter 27 | maximumLineCount: 1 28 | text: Clipboard.text.replace("\n", " ") 29 | } 30 | 31 | Image { 32 | id: pasteIcon 33 | 34 | anchors.verticalCenter: parent.verticalCenter 35 | source: "image://theme/icon-m-clipboard" 36 | + (pasteContainer.highlighted ? ("?" + Theme.highlightColor) : "") 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /dolphin/PasteButtonBase.qml: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 Jolla Ltd. 2 | // Contact: Pekka Vuorela 3 | 4 | import QtQuick 2.2 5 | import Sailfish.Silica 1.0 6 | import com.jolla.keyboard 1.0 7 | 8 | BackgroundItem { 9 | id: pasteContainer 10 | 11 | property int popupAnchor // 0 -> left, 1 -> right, 2 -> center 12 | property alias popupParent: popup.parent 13 | 14 | height: parent ? parent.height : 0 15 | width: Clipboard.hasText ? (keyboard.expandedPaste ? pasteRow.width + 2*Theme.paddingMedium 16 | : pasteIcon.width + Theme.paddingMedium) 17 | : 0 18 | 19 | preventStealing: popup.visible 20 | highlighted: down || popup.visible 21 | 22 | onPressAndHold: popup.visible = true 23 | onReleased: { 24 | if (popup.visible && popup.containsMouse) 25 | Clipboard.text = "" 26 | popup.visible = false 27 | } 28 | onCanceled: popup.visible = false 29 | onPositionChanged: { 30 | if (!popup.visible) { 31 | return 32 | } 33 | 34 | var pos = mapToItem(popup, mouse.x, mouse.y) 35 | var wasSelected = popup.containsMouse 36 | popup.containsMouse = popup.contains(Qt.point(pos.x, pos.y - geometry.clearPasteTouchDelta)) 37 | if (wasSelected != popup.containsMouse) { 38 | SampleCache.play("/usr/share/sounds/jolla-ambient/stereo/keyboard_letter.wav") 39 | buttonPressEffect.play() 40 | } 41 | } 42 | 43 | Rectangle { 44 | id: popup 45 | 46 | property bool containsMouse 47 | 48 | visible: false 49 | width: clearLabel.width + geometry.clearPasteMargin 50 | height: clearLabel.height + geometry.clearPasteMargin 51 | anchors.right: pasteContainer.popupAnchor == 1 ? parent.right : undefined 52 | anchors.horizontalCenter: pasteContainer.popupAnchor == 2 ? parent.horizontalCenter : undefined 53 | anchors.bottom: parent.top 54 | radius: geometry.popperRadius 55 | color: Qt.darker(Theme.highlightBackgroundColor, 1.3) 56 | 57 | onVisibleChanged: containsMouse = false 58 | 59 | Label { 60 | id: clearLabel 61 | anchors.centerIn: parent 62 | color: parent.containsMouse ? Theme.primaryColor : Theme.highlightColor 63 | //% "Clear clipboard" 64 | text: qsTrId("text_input-la-clear_clipboard") 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /dolphin/PasteButtonVertical.qml: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2015 Jolla Ltd. 2 | // Contact: Pekka Vuorela 3 | 4 | import QtQuick 2.2 5 | import Sailfish.Silica 1.0 6 | 7 | 8 | PasteButtonBase { 9 | id: pasteContainer 10 | 11 | Row { 12 | id: pasteRow 13 | 14 | height: parent.height 15 | anchors.horizontalCenter: parent.horizontalCenter 16 | 17 | Image { 18 | id: pasteIcon 19 | 20 | anchors.verticalCenter: parent.verticalCenter 21 | source: "image://theme/icon-m-clipboard" 22 | + (pasteContainer.highlighted ? ("?" + Theme.highlightColor) : "") 23 | } 24 | 25 | Label { 26 | id: pasteLabel 27 | 28 | height: pasteContainer.height 29 | width: Math.min(pasteContainer.width - pasteIcon.width, implicitWidth) 30 | font { pixelSize: Theme.fontSizeSmall; family: Theme.fontFamily } 31 | color: pasteContainer.highlighted ? Theme.highlightColor : Theme.primaryColor 32 | truncationMode: TruncationMode.Fade 33 | verticalAlignment: Text.AlignVCenter 34 | maximumLineCount: 1 35 | text: Clipboard.text.replace("\n", " ") 36 | } 37 | 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /dolphin/PasteInputHandler.qml: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 Jolla Ltd. 2 | // Contact: Pekka Vuorela 3 | 4 | import QtQuick 2.2 5 | import Sailfish.Silica 1.0 6 | 7 | InputHandler { 8 | topItem: Component { 9 | TopItem { 10 | SilicaFlickable { 11 | anchors.fill: parent 12 | flickableDirection: Flickable.HorizontalFlick 13 | boundsBehavior: !keyboard.expandedPaste && Clipboard.hasText ? Flickable.DragOverBounds : Flickable.StopAtBounds 14 | 15 | onDraggingChanged: { 16 | if (!dragging && !keyboard.expandedPaste && contentX < -Theme.paddingLarge) { 17 | keyboard.expandedPaste = true 18 | contentX = 0 19 | } 20 | } 21 | PasteButton { 22 | onClicked: { 23 | MInputMethodQuick.sendCommit(Clipboard.text) 24 | keyboard.expandedPaste = false 25 | } 26 | } 27 | } 28 | } 29 | } 30 | 31 | verticalItem: Component { 32 | Item { 33 | PasteButtonVertical { 34 | visible: Clipboard.hasText 35 | width: parent.width 36 | height: visible ? geometry.keyHeightLandscape : 0 37 | popupAnchor: 2 // center 38 | 39 | onClicked: MInputMethodQuick.sendCommit(Clipboard.text) 40 | } 41 | } 42 | } 43 | 44 | function handleKeyClick() { 45 | keyboard.expandedPaste = false 46 | return false 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /dolphin/PhoneKey.qml: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 Jolla Ltd. 2 | // Contact: Pekka Vuorela 3 | 4 | import QtQuick 2.2 5 | import Sailfish.Silica 1.0 6 | import com.jolla.keyboard 1.0 7 | import QtMultimedia 5.0 8 | 9 | KeyBase { 10 | id: aCharKey 11 | 12 | property alias secondaryLabel: secondaryLabel.text 13 | property bool separator: true 14 | property bool landscape 15 | 16 | keyType: KeyType.CharacterKey 17 | text: secondaryLabel.text 18 | showPopper: false 19 | Item { 20 | width: parent.width 21 | height: childrenRect.height 22 | anchors.centerIn: parent 23 | 24 | Text { 25 | id: mainLabel 26 | width: parent.width 27 | anchors.top: parent.top 28 | anchors.topMargin: 4 29 | anchors.horizontalCenter: parent.horizontalCenter 30 | lineHeight: 0.8 31 | verticalAlignment: Text.AlignVCenter 32 | horizontalAlignment: Text.AlignHCenter 33 | font.family: Theme.fontFamily 34 | font.pixelSize: keyboard.inSymView? Theme.fontSizeLarge * settings.scale: Theme.fontSizeTiny * settings.scale 35 | color: pressed ? Theme.highlightColor : Theme.primaryColor 36 | text: caption 37 | opacity: keyboard.inSymView? 0.8: 0.4 38 | } 39 | 40 | Text { 41 | id: secondaryLabel 42 | width: secondaryLabel.text.length === 4? ( keyboard.inSymView? parent.width / 3: parent.width / 2 ): parent.width 43 | wrapMode: Text.WrapAnywhere 44 | anchors.top: mainLabel.bottom 45 | anchors.topMargin: 4 46 | anchors.horizontalCenter: parent.horizontalCenter 47 | verticalAlignment: Text.AlignVCenter 48 | horizontalAlignment: Text.AlignHCenter 49 | font.family: Theme.fontFamily 50 | lineHeight: 0.64 51 | font.pixelSize: keyboard.inSymView? Theme.fontSizeTiny * settings.scale: ( secondaryLabel.text.length ===4? Theme.fontSizeMedium * settings.scale: Theme.fontSizeMedium * settings.scale ) 52 | color: pressed ? Theme.highlightColor : Theme.primaryColor 53 | opacity: keyboard.inSymView? 0.4: 0.8 54 | } 55 | } 56 | 57 | Image { 58 | source: "graphic-keyboard-highlight-top.png" 59 | anchors.right: parent.right 60 | visible: separator 61 | } 62 | 63 | Rectangle { 64 | anchors.fill: parent 65 | z: -1 66 | color: Theme.highlightBackgroundColor 67 | opacity: 0.5 68 | visible: pressed 69 | } 70 | 71 | MouseArea { 72 | id: mouseArea 73 | anchors.fill: parent 74 | //propagateComposedEvents: keyboard.inputHandler === xt9Handler? true: false 75 | //visible: keyboard.inputHandler === xt9Handler? true: false 76 | propagateComposedEvents: true 77 | visible: true 78 | 79 | property int angle: 0 80 | property int distance: 0 81 | property bool autoRepeat: false 82 | property point start: Qt.point(0, 0); 83 | property int threshold: 16 * (height * 2 > width ? 2 : 1 ) 84 | 85 | property bool swipeT: false 86 | property bool swipeB: false 87 | property bool swipeL: false 88 | property bool swipeR: false 89 | 90 | 91 | onPressed: { 92 | effectP.play() 93 | start = Qt.point(mouse.x, mouse.y) 94 | angle = 0 95 | distance = 0 96 | var pos = mapToItem(layout, mouse.x, mouse.y) 97 | mouse.accepted = true 98 | } 99 | 100 | SoundEffect { 101 | id: effectP 102 | source: "/usr/share/sounds/jolla-ambient/stereo/keyboard_letter.wav" 103 | } 104 | 105 | 106 | SoundEffect { 107 | id: effectR 108 | source: "/usr/share/sounds/jolla-ambient/stereo/keyboard_option.wav" 109 | } 110 | 111 | onClicked: { 112 | 113 | 114 | buttonPressEffect.play() 115 | 116 | 117 | if ( keyboard.inSymView === true ) { 118 | //SYMBOL MODE 119 | MInputMethodQuick.sendCommit(caption) 120 | 121 | //ENGLISH MODE 122 | } else if ( keyboard.inputHandler === xt9Handler ) { 123 | MInputMethodQuick.sendCommit(secondaryLabel.text.charAt(1)) 124 | //PINYIN MODE 125 | } else if ( secondaryLabel.text === "分詞" ) { 126 | keyboard.inputHandler.handleSW() 127 | 128 | } else { 129 | keyboard.inputHandler.handleT9(caption) 130 | } 131 | } 132 | 133 | onReleased: { 134 | buttonPressEffect.play() 135 | effectR.play() 136 | var pos = mapToItem(layout, mouse.x, mouse.y) 137 | mouse.accepted = true 138 | 139 | //9 140 | if ( swipeT === true ) { 141 | if ( keyboard.inSymView === true ) { 142 | MInputMethodQuick.sendCommit(secondaryLabel.text.charAt(1)) 143 | } else { 144 | MInputMethodQuick.sendCommit(caption) 145 | } 146 | 147 | swipeT = false 148 | } 149 | 150 | //y 151 | if ( swipeR === true ) { 152 | if ( keyboard.inSymView === true || keyboard.inputHandler === xt9Handler ) { 153 | //SYMBOL MODE && ENGLISH MODE 154 | 155 | MInputMethodQuick.sendCommit(secondaryLabel.text.charAt(2)) 156 | 157 | } else { 158 | keyboard.inputHandler.handlePY(secondaryLabel.text.charAt(2)) 159 | } 160 | 161 | swipeR = false 162 | } 163 | 164 | //z 165 | if ( swipeB === true ) { 166 | 167 | if ( keyboard.inSymView === true || keyboard.inputHandler === xt9Handler ) { 168 | //SYMBOL MODE && ENGLISH MODE 169 | 170 | MInputMethodQuick.sendCommit(secondaryLabel.text.charAt(3)) 171 | 172 | } else { 173 | keyboard.inputHandler.handlePY(secondaryLabel.text.charAt(3)) 174 | } 175 | swipeB = false 176 | } 177 | //z 178 | if ( swipeL === true ) { 179 | 180 | if ( keyboard.inSymView === true || keyboard.inputHandler === xt9Handler ) { 181 | //SYMBOL MODE && ENGLISH MODE 182 | 183 | MInputMethodQuick.sendCommit(secondaryLabel.text.charAt(0)) 184 | 185 | } else { 186 | keyboard.inputHandler.handlePY(secondaryLabel.text.charAt(0)) 187 | } 188 | swipeL = false 189 | } 190 | 191 | 192 | 193 | } 194 | 195 | onPositionChanged: { 196 | 197 | angle = Math.atan2(mouse.y - start.y, mouse.x - start.x) * 360 / Math.PI / 2 + 180 198 | var d = Math.sqrt(Math.pow(mouse.x - start.x, 2) + Math.pow(mouse.y - start.y, 2)) 199 | distance = Math.round(d / threshold) 200 | var pos = mapToItem(layout, mouse.x, mouse.y) 201 | 202 | if ( secondaryLabel.text.length === 4 ) { 203 | if ( distance > 2 && angle >= 45 && angle <= 134 ){ 204 | swipeT = true 205 | secondaryLabel.text.caption 206 | 207 | } else if ( distance > 2 && angle >= 135 && angle <= 214 ){ 208 | swipeR = true 209 | secondaryLabel.text.charAt(2) 210 | } else if ( distance > 2 && angle >= 215 && angle <= 304 ){ 211 | swipeB = true 212 | popper.label = secondaryLabel.text.charAt(3) 213 | } else if ( distance > 2 ) { 214 | swipeL = true 215 | popper.label = secondaryLabel.text.charAt(0) 216 | } 217 | 218 | } else if ( secondaryLabel.text.length === 3 ) { 219 | if ( distance > 2 && angle >= 30 && angle <= 149 ){ 220 | swipeT = true 221 | popper.label = caption 222 | } else if ( distance > 2 && angle >= 150 && angle <=269 ){ 223 | swipeR = true 224 | popper.label = secondaryLabel.text.charAt(2) 225 | } else if ( distance > 2 ) { 226 | swipeL = true 227 | popper.label = secondaryLabel.text.charAt(0) 228 | } 229 | } 230 | } 231 | 232 | //BACKGROUND 233 | Rectangle { 234 | color: parent.pressed ? Theme.highlightBackgroundColor : "#00000000" 235 | anchors.fill: parent 236 | opacity: 0.4 237 | } 238 | 239 | Rectangle { 240 | 241 | property string label: "" 242 | 243 | id: popper 244 | visible: ( parent.swipeT === true || parent.swipeR === true || parent.swipeB === true || parent.swipeL === true )? true: false 245 | anchors.bottom: parent.top 246 | color: Qt.darker(Theme.highlightBackgroundColor, 1.2) 247 | width: parent.width 248 | height: parent.height 249 | radius: geometry.popperRadius 250 | 251 | Label { 252 | anchors.centerIn: parent 253 | text: parent.label 254 | } 255 | } 256 | } 257 | 258 | 259 | } 260 | 261 | -------------------------------------------------------------------------------- /dolphin/PhoneNumberLayoutLandscape.qml: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 Jolla Ltd. 2 | // Contact: Pekka Vuorela 3 | 4 | import QtQuick 2.2 5 | import Sailfish.Silica 1.0 as Silica 6 | 7 | KeyboardLayout { 8 | id: main 9 | 10 | width: geometry.keyboardWidthLandscape 11 | height: 2 * geometry.keyHeightPortrait 12 | 13 | Row { 14 | CharacterKey { 15 | caption: "1" 16 | height: geometry.keyHeightPortrait 17 | width: main.width / 10 18 | showPopper: false 19 | } 20 | PhoneKey { 21 | caption: "2" 22 | secondaryLabel: "abc" 23 | height: geometry.keyHeightPortrait 24 | width: main.width / 10 25 | landscape: true 26 | } 27 | PhoneKey { 28 | caption: "3" 29 | secondaryLabel: "def" 30 | height: geometry.keyHeightPortrait 31 | width: main.width / 10 32 | landscape: true 33 | } 34 | PhoneKey { 35 | caption: "4" 36 | secondaryLabel: "ghi" 37 | height: geometry.keyHeightPortrait 38 | width: main.width / 10 39 | landscape: true 40 | } 41 | PhoneKey { 42 | caption: "5" 43 | secondaryLabel: "jkl" 44 | height: geometry.keyHeightPortrait 45 | width: main.width / 10 46 | landscape: true 47 | } 48 | PhoneKey { 49 | caption: "6" 50 | secondaryLabel: "mno" 51 | height: geometry.keyHeightPortrait 52 | width: main.width / 10 53 | landscape: true 54 | } 55 | PhoneKey { 56 | caption: "7" 57 | secondaryLabel: "pqrs" 58 | height: geometry.keyHeightPortrait 59 | width: main.width / 10 60 | landscape: true 61 | } 62 | PhoneKey { 63 | caption: "8" 64 | secondaryLabel: "tuv" 65 | height: geometry.keyHeightPortrait 66 | width: main.width / 10 67 | landscape: true 68 | } 69 | PhoneKey { 70 | caption: "9" 71 | secondaryLabel: "wxyz" 72 | height: geometry.keyHeightPortrait 73 | width: main.width / 10 74 | landscape: true 75 | } 76 | CharacterKey { 77 | caption: "0" 78 | height: geometry.keyHeightPortrait 79 | width: main.width / 10 80 | showPopper: false 81 | separator: false 82 | } 83 | } 84 | 85 | Row { 86 | x: 3 * (main.width / 10) 87 | 88 | NumberKey { 89 | landscape: true 90 | enabled: Silica.Clipboard.hasText 91 | key: Qt.Key_Paste 92 | opacity: enabled ? (pressed ? 0.6 : 1.0) 93 | : 0.3 94 | 95 | Image { 96 | anchors.centerIn: parent 97 | source: "image://theme/icon-m-clipboard?" 98 | + (parent.pressed ? Silica.Theme.highlightColor : Silica.Theme.primaryColor) 99 | } 100 | } 101 | CharacterKey { 102 | key: Qt.Key_Multi_key 103 | text: "*p" 104 | caption: "*p" 105 | height: geometry.keyHeightPortrait 106 | width: main.width / 10 107 | showPopper: false 108 | } 109 | CharacterKey { 110 | caption: "+" 111 | height: geometry.keyHeightPortrait 112 | width: main.width / 10 113 | showPopper: false 114 | } 115 | CharacterKey { 116 | caption: "#" 117 | height: geometry.keyHeightPortrait 118 | width: main.width / 10 119 | showPopper: false 120 | separator: false 121 | } 122 | BackspaceKey { 123 | width: main.width / 10 124 | height: geometry.keyHeightPortrait 125 | } 126 | EnterKey { 127 | width: main.width / 5 128 | height: geometry.keyHeightPortrait 129 | } 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /dolphin/PhoneNumberLayoutPortrait.qml: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 Jolla Ltd. 2 | // Contact: Pekka Vuorela 3 | 4 | import QtQuick 2.2 5 | import Sailfish.Silica 1.0 as Silica 6 | 7 | KeyboardLayout { 8 | id: main 9 | 10 | portraitMode: true 11 | width: geometry.keyboardWidthPortrait 12 | height: 4 * geometry.keyHeightPortrait 13 | 14 | Row { 15 | PhoneKey { 16 | caption: "1" 17 | height: geometry.keyHeightPortrait 18 | width: main.width / 4 19 | 20 | } 21 | PhoneKey { 22 | caption: "2" 23 | secondaryLabel: "abc" 24 | height: geometry.keyHeightPortrait 25 | width: main.width / 4 26 | } 27 | PhoneKey { 28 | caption: "3" 29 | secondaryLabel: "def" 30 | height: geometry.keyHeightPortrait 31 | width: main.width / 4 32 | } 33 | NumberKey { 34 | separator: false 35 | enabled: Silica.Clipboard.hasText 36 | key: Qt.Key_Paste 37 | opacity: enabled ? (pressed ? 0.6 : 1.0) 38 | : 0.3 39 | 40 | Image { 41 | anchors.centerIn: parent 42 | source: "image://theme/icon-m-clipboard?" 43 | + (parent.pressed ? Silica.Theme.highlightColor : Silica.Theme.primaryColor) 44 | } 45 | } 46 | } 47 | 48 | Row { 49 | PhoneKey { 50 | caption: "4" 51 | secondaryLabel: "ghi" 52 | height: geometry.keyHeightPortrait 53 | width: main.width / 4 54 | } 55 | PhoneKey { 56 | caption: "5" 57 | secondaryLabel: "jkl" 58 | height: geometry.keyHeightPortrait 59 | width: main.width / 4 60 | } 61 | PhoneKey { 62 | caption: "6" 63 | secondaryLabel: "mno" 64 | height: geometry.keyHeightPortrait 65 | width: main.width / 4 66 | } 67 | CharacterKey { 68 | key: Qt.Key_Multi_key 69 | text: "*p" 70 | caption: "*p" 71 | height: geometry.keyHeightPortrait 72 | width: main.width / 4 73 | showPopper: false 74 | separator: false 75 | } 76 | } 77 | 78 | Row { 79 | PhoneKey { 80 | caption: "7" 81 | secondaryLabel: "pqrs" 82 | height: geometry.keyHeightPortrait 83 | width: main.width / 4 84 | } 85 | PhoneKey { 86 | caption: "8" 87 | secondaryLabel: "tuv" 88 | height: geometry.keyHeightPortrait 89 | width: main.width / 4 90 | } 91 | PhoneKey { 92 | caption: "9" 93 | secondaryLabel: "wxyz" 94 | height: geometry.keyHeightPortrait 95 | width: main.width / 4 96 | } 97 | BackspaceKey { 98 | width: main.width / 4 99 | height: geometry.keyHeightPortrait 100 | separator: false 101 | } 102 | } 103 | 104 | Row { 105 | CharacterKey { 106 | caption: "+" 107 | height: geometry.keyHeightPortrait 108 | width: main.width / 4 109 | showPopper: false 110 | } 111 | CharacterKey { 112 | caption: "0" 113 | height: geometry.keyHeightPortrait 114 | width: main.width / 4 115 | showPopper: false 116 | } 117 | CharacterKey { 118 | caption: "#" 119 | height: geometry.keyHeightPortrait 120 | width: main.width / 4 121 | showPopper: false 122 | } 123 | EnterKey { 124 | width: main.width / 4 125 | height: geometry.keyHeightPortrait 126 | separator: false 127 | } 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /dolphin/PopperCell.qml: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 Jolla Ltd. 2 | // Contact: Pekka Vuorela 3 | 4 | import QtQuick 2.2 5 | import Sailfish.Silica 1.0 6 | 7 | Item { 8 | id: popperCell 9 | width: geometry.accentPopperCellWidth 10 | height: geometry.popperHeight 11 | 12 | property bool active 13 | property alias character: textItem.text 14 | property alias textVisible: textItem.visible 15 | 16 | Text { 17 | id: textItem 18 | anchors.centerIn: parent 19 | horizontalAlignment: Text.AlignHCenter 20 | verticalAlignment: Text.AlignVCenter 21 | color: Theme.primaryColor 22 | opacity: popperCell.active ? 1 : .35 23 | font.family: Theme.fontFamily 24 | font.pixelSize: geometry.popperFontSize 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /dolphin/PreeditTestHandler.qml: -------------------------------------------------------------------------------- 1 | /**************************************************************************************** 2 | ** 3 | ** Copyright (C) 2013 Jolla Ltd. 4 | ** Contact: Pekka Vuorela 5 | ** All rights reserved. 6 | ** 7 | ** You may use this file under the terms of BSD license as follows: 8 | ** 9 | ** Redistribution and use in source and binary forms, with or without 10 | ** modification, are permitted provided that the following conditions are met: 11 | ** * Redistributions of source code must retain the above copyright 12 | ** notice, this list of conditions and the following disclaimer. 13 | ** * Redistributions in binary form must reproduce the above copyright 14 | ** notice, this list of conditions and the following disclaimer in the 15 | ** documentation and/or other materials provided with the distribution. 16 | ** * Neither the name of the Jolla Ltd nor the 17 | ** names of its contributors may be used to endorse or promote products 18 | ** derived from this software without specific prior written permission. 19 | ** 20 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 21 | ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 22 | ** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | ** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 24 | ** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 25 | ** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 26 | ** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 27 | ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 | ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | ** 31 | ****************************************************************************************/ 32 | 33 | import QtQuick 2.2 34 | import com.meego.maliitquick 1.0 35 | 36 | InputHandler { 37 | property string preedit 38 | 39 | function handleKeyClick() { 40 | if ((pressedKey.text === " ") || (pressedKey.key === Qt.Key_Return) && preedit.length !== "") { 41 | MInputMethodQuick.sendCommit(preedit) 42 | preedit = "" 43 | 44 | } else if (pressedKey.text !== "" && MInputMethodQuick.predictionEnabled) { 45 | preedit = preedit + pressedKey.text 46 | MInputMethodQuick.sendPreedit(preedit, Maliit.PreeditDefault) 47 | keyboard.isShifted = false 48 | return true 49 | 50 | } else if (pressedKey.key === Qt.Key_Backspace && preedit !== "") { 51 | preedit = preedit.substring(0, preedit.length - 1) 52 | MInputMethodQuick.sendPreedit(preedit, Maliit.PreeditDefault) 53 | // need to manually check autocaps when preedit gets removed, real cursor position doesn't change 54 | if (preedit.length === 0) 55 | keyboard.applyAutocaps() 56 | else 57 | keyboard.isShifted = false 58 | return true 59 | } 60 | 61 | return false 62 | } 63 | 64 | function reset() { 65 | preedit = "" 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /dolphin/PreeditView.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.2 2 | import Sailfish.Silica 1.0 3 | import com.jolla.keyboard 1.0 4 | 5 | Rectangle { 6 | id: root 7 | 8 | height: parent.height 9 | width: label.width + Theme.paddingSmall * 2 10 | color: Theme.highlightBackgroundColor 11 | 12 | Label { 13 | id: label 14 | text: preedit 15 | color: Theme.primaryColor 16 | anchors.centerIn: parent 17 | } 18 | 19 | 20 | 21 | 22 | 23 | } 24 | -------------------------------------------------------------------------------- /dolphin/PunctuationKey.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Jolla ltd. and/or its subsidiary(-ies). All rights reserved. 3 | * 4 | * Contact: Pekka Vuorela 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * Redistributions of source code must retain the above copyright notice, this list 10 | * of conditions and the following disclaimer. 11 | * Redistributions in binary form must reproduce the above copyright notice, this list 12 | * of conditions and the following disclaimer in the documentation and/or other materials 13 | * provided with the distribution. 14 | * Neither the name of Jolla ltd nor the names of its contributors may be 15 | * used to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 19 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 20 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 | * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | * 28 | */ 29 | import QtQuick 2.2 30 | import com.jolla.keyboard 1.0 31 | import Sailfish.Silica 1.0 32 | 33 | FunctionKey { 34 | id: symbolKey 35 | 36 | property int _charactersWhenPressed 37 | property bool _quickPicking 38 | 39 | caption: "符" 40 | width: functionKeyWidth 41 | keyType: KeyType.SymbolKey 42 | 43 | onPressedChanged: { 44 | if (pressed && !keyboard.inSymView && keyboard.lastInitialKey === symbolKey) { 45 | keyboard.deadKeyAccent = "" 46 | keyboard.toggleSymbolMode() 47 | _quickPicking = true 48 | } else { 49 | _quickPicking = false 50 | } 51 | 52 | _charactersWhenPressed = keyboard.characterKeyCounter 53 | } 54 | 55 | onClicked: { 56 | if (!_quickPicking || keyboard.characterKeyCounter > _charactersWhenPressed) { 57 | keyboard.toggleSymbolMode() 58 | } 59 | } 60 | 61 | Rectangle { 62 | color: parent.pressed ? Theme.highlightBackgroundColor : Theme.primaryColor 63 | opacity: parent.pressed ? 0.6 : 0.16 64 | radius: geometry.keyRadius 65 | 66 | anchors.fill: parent 67 | anchors.margins: Theme.paddingMedium 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /dolphin/QuickPick.qml: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 Jolla Ltd. 2 | // Contact: Pekka Vuorela 3 | 4 | import QtQuick 2.2 5 | import com.jolla.keyboard 1.0 6 | 7 | QtObject { 8 | property bool _lastWasNumber 9 | property bool _doneInput 10 | 11 | function handleInput(key) { 12 | if (!key) { 13 | return 14 | } 15 | 16 | if (keyboard.inSymView 17 | && keyboard.lastInitialKey 18 | && keyboard.lastInitialKey.keyType === KeyType.SymbolKey 19 | && key.keyType === KeyType.CharacterKey 20 | && !keyboard.isPressed(KeyType.SymbolKey)) { 21 | keyboard.inSymView = false 22 | keyboard.inSymView2 = false 23 | return 24 | } 25 | 26 | if (!keyboard.inSymView 27 | || key.text === "" 28 | || keyboard.isPressed(KeyType.SymbolKey)) { 29 | return 30 | } 31 | 32 | if (key.text === " ") { 33 | if (_doneInput && !_lastWasNumber) { 34 | keyboard.inSymView = false 35 | keyboard.inSymView2 = false 36 | } 37 | } else if ("'@".indexOf(key.text) >= 0 && !_doneInput) { 38 | keyboard.inSymView = false 39 | keyboard.inSymView2 = false 40 | 41 | } else { 42 | _doneInput = true 43 | _lastWasNumber = "1234567890".indexOf(key.text) >= 0 44 | } 45 | } 46 | 47 | property variant _connection: Connections { 48 | target: keyboard 49 | onInSymViewChanged: { 50 | if (keyboard.inSymView) { 51 | _lastWasNumber = false 52 | _doneInput = false 53 | } 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /dolphin/Settings.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.2 2 | import Sailfish.Silica 1.0 3 | import harbour.tide.keyboard 1.0 4 | import org.nemomobile.configuration 1.0 5 | 6 | Item { 7 | id: settings 8 | 9 | property alias spacebar: _spacebar.value 10 | property alias keys: _keys.value 11 | property alias word: _word.value 12 | property alias fusion: _fusion.value 13 | property alias enMode: _enMode.value 14 | property alias swipe: _swipe.value 15 | 16 | property alias tabsize: _tabsize.value 17 | 18 | property alias scale: _scale.value 19 | property alias size: _size.value 20 | property alias toolbar: _toolbar.value 21 | property alias background: _background.value 22 | property alias transparency: _transparency.value 23 | 24 | 25 | // 26 | 27 | ConfigurationValue { 28 | id: _spacebar 29 | key: "/apps/harbour-tide-keyboard/settings/keyboard/spacebar" 30 | defaultValue: false 31 | } 32 | 33 | ConfigurationValue { 34 | id: _keys 35 | key: "/apps/harbour-tide-keyboard/settings/keyboard/keys" 36 | defaultValue: true 37 | } 38 | 39 | ConfigurationValue { 40 | id: _word 41 | key: "/apps/harbour-tide-keyboard/settings/keyboard/word" 42 | defaultValue: true 43 | } 44 | 45 | ConfigurationValue { 46 | id: _fusion 47 | key: "/apps/harbour-tide-keyboard/settings/keyboard/fusion" 48 | defaultValue: false 49 | } 50 | 51 | ConfigurationValue { 52 | id: _enMode 53 | key: "/apps/harbour-tide-keyboard/settings/keyboard/enmode" 54 | defaultValue: false 55 | } 56 | 57 | ConfigurationValue { 58 | id: _swipe 59 | key: "/apps/harbour-tide-keyboard/settings/keyboard/swipe" 60 | defaultValue: false 61 | } 62 | 63 | ConfigurationValue { 64 | id: _tabsize 65 | key: "/apps/harbour-tide-keyboard/settings/appearance/tabsize" 66 | defaultValue: false 67 | } 68 | 69 | //Appearance 70 | 71 | ConfigurationValue { 72 | id: _scale 73 | key: "/apps/harbour-tide-keyboard/settings/appearance/scale" 74 | defaultValue: 1 75 | } 76 | 77 | ConfigurationValue { 78 | id: _size 79 | key: "/apps/harbour-tide-keyboard/settings/appearance/size" 80 | defaultValue: 1 81 | } 82 | 83 | ConfigurationValue { 84 | id: _background 85 | key: "/apps/harbour-tide-keyboard/settings/appearance/background" 86 | defaultValue: "" 87 | } 88 | 89 | ConfigurationValue { 90 | id: _transparency 91 | key: "/apps/harbour-tide-keyboard/settings/appearance/transparency" 92 | defaultValue: 1 93 | } 94 | 95 | //Tooblar 96 | ConfigurationValue { 97 | id: _toolbar 98 | key: "/apps/harbour-tide-keyboard/settings/appearance/toolbar" 99 | defaultValue: 1 100 | } 101 | 102 | 103 | 104 | } 105 | -------------------------------------------------------------------------------- /dolphin/ShiftKey.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Jolla ltd. and/or its subsidiary(-ies). All rights reserved. 3 | * 4 | * Contact: Pekka Vuorela 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * Redistributions of source code must retain the above copyright notice, this list 10 | * of conditions and the following disclaimer. 11 | * Redistributions in binary form must reproduce the above copyright notice, this list 12 | * of conditions and the following disclaimer in the documentation and/or other materials 13 | * provided with the distribution. 14 | * Neither the name of Jolla ltd nor the names of its contributors may be 15 | * used to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 19 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 20 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 | * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | * 28 | */ 29 | 30 | import QtQuick 2.2 31 | import com.jolla.keyboard 1.0 32 | import Sailfish.Silica 1.0 33 | 34 | FunctionKey { 35 | id: shiftKey 36 | 37 | property int _charactersWhenPressed 38 | property bool _quickPicking 39 | 40 | implicitWidth: shiftKeyWidth 41 | icon.source: attributes.inSymView ? "" 42 | : (attributes.isShifted && !attributes.isShiftLocked ? "image://theme/icon-m-autocaps" 43 | : "image://theme/icon-m-capslock") 44 | + (pressed ? ("?" + Theme.highlightColor) : "") 45 | 46 | // dim normal shift mode 47 | icon.opacity: (!attributes.inSymView && !attributes.isShiftLocked && !attributes.isShifted) ? 0.2 : 1.0 48 | caption: attributes.inSymView ? (attributes.inSymView2 ? "2/2" : "1/2") : "" 49 | key: Qt.Key_Shift 50 | keyType: KeyType.ShiftKey 51 | 52 | onPressedChanged: { 53 | if (!keyboard.inSymView) { 54 | if (pressed && !keyboard.isShifted && keyboard.lastInitialKey === shiftKey) { 55 | _quickPicking = true 56 | keyboard.shiftState = ShiftState.LatchedShift 57 | } else { 58 | _quickPicking = false 59 | } 60 | 61 | _charactersWhenPressed = keyboard.characterKeyCounter 62 | keyboard.shiftKeyPressed = pressed 63 | keyboard.updatePopper() 64 | } 65 | } 66 | 67 | onClicked: { 68 | if (keyboard.characterKeyCounter > _charactersWhenPressed) { 69 | keyboard.shiftState = ShiftState.NoShift 70 | } else if (!_quickPicking) { 71 | if (keyboard.inSymView) { 72 | keyboard.inSymView2 = !keyboard.inSymView2 73 | } else { 74 | keyboard.cycleShift() 75 | } 76 | } 77 | } 78 | 79 | Rectangle { 80 | color: parent.pressed ? Theme.highlightBackgroundColor : Theme.primaryColor 81 | visible: attributes.inSymView 82 | opacity: parent.pressed ? 0.6 : 0.17 83 | radius: geometry.keyRadius 84 | 85 | anchors.fill: parent 86 | anchors.margins: Theme.paddingMedium 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /dolphin/SpacebarKey.qml: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 Jolla Ltd. 2 | // Contact: Pekka Vuorela 3 | 4 | import QtQuick 2.2 5 | import Sailfish.Silica 1.0 6 | import com.jolla.keyboard 1.0 7 | 8 | CharacterKey { 9 | property alias languageLabel: textField.text 10 | property bool expandingKey: true 11 | 12 | caption: " " 13 | captionShifted: " " 14 | showPopper: false 15 | separator: SeparatorState.HiddenSeparator 16 | showHighlight: false 17 | key: Qt.Key_Space 18 | 19 | Rectangle { 20 | color: parent.pressed ? Theme.highlightBackgroundColor : Theme.primaryColor 21 | opacity: parent.pressed ? 0.6 : 0.07 22 | radius: geometry.keyRadius 23 | 24 | anchors.fill: parent 25 | anchors.margins: Theme.paddingMedium 26 | } 27 | 28 | Text { 29 | id: textField 30 | width: parent.width 31 | height: parent.height 32 | horizontalAlignment: Text.AlignHCenter 33 | verticalAlignment: Text.AlignVCenter 34 | text: languageCode 35 | color: Theme.primaryColor 36 | opacity: .4 37 | font.pixelSize: Theme.fontSizeSmall 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /dolphin/SpacebarRow.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Jolla ltd and/or its subsidiary(-ies). All rights reserved. 3 | * 4 | * Contact: Pekka Vuorela 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * Redistributions of source code must retain the above copyright notice, this list 10 | * of conditions and the following disclaimer. 11 | * Redistributions in binary form must reproduce the above copyright notice, this list 12 | * of conditions and the following disclaimer in the documentation and/or other materials 13 | * provided with the distribution. 14 | * Neither the name of Nokia Corporation nor the names of its contributors may be 15 | * used to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 19 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 20 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 | * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | * 28 | */ 29 | import QtQuick 2.2 30 | import com.meego.maliitquick 1.0 31 | import com.jolla.keyboard 1.0 32 | 33 | 34 | KeyboardRow { 35 | splitIndex: 4 36 | 37 | property int keyWidth: parent.width / 12 38 | 39 | SymbolKey { } 40 | 41 | //LanguageKey { } 42 | 43 | ContextAwareKey { 44 | caption: MInputMethodQuick.contentType === Maliit.EmailContentType? "@": ( MInputMethodQuick.contentType === Maliit.UrlContentType? ":": ( xt9? "," : "," ) ) 45 | captionShifted: MInputMethodQuick.contentType === Maliit.EmailContentType? "@": ( MInputMethodQuick.contentType === Maliit.UrlContentType? ":": ( xt9? ",": "," ) ) 46 | symView: MInputMethodQuick.contentType === Maliit.EmailContentType? "@": ( MInputMethodQuick.contentType === Maliit.UrlContentType? ":": ( xt9? "," : "," ) ) 47 | symView2: MInputMethodQuick.contentType === Maliit.EmailContentType? "@": ( MInputMethodQuick.contentType === Maliit.UrlContentType? ":": ( xt9? "," : "," ) ) 48 | accents: ".!?@#$%" 49 | } 50 | 51 | SpacebarKey { } 52 | 53 | SpacebarKey { 54 | active: splitActive 55 | languageLabel: "" 56 | } 57 | 58 | ContextAwareKey { 59 | caption: MInputMethodQuick.contentType === Maliit.EmailContentType? ".": ( MInputMethodQuick.contentType === Maliit.UrlContentType? "/": ( xt9? ".": "。" ) ) 60 | captionShifted: MInputMethodQuick.contentType === Maliit.EmailContentType? ".": ( MInputMethodQuick.contentType === Maliit.UrlContentType? "/": ( xt9? ".": "。" ) ) 61 | symView: MInputMethodQuick.contentType === Maliit.EmailContentType? ".": ( MInputMethodQuick.contentType === Maliit.UrlContentType? "/": ( xt9? ".": "。" ) ) 62 | symView2: MInputMethodQuick.contentType === Maliit.EmailContentType? ".": ( MInputMethodQuick.contentType === Maliit.UrlContentType? "/": ( xt9? ".": "。" ) ) 63 | accents: ".!?@#$%" 64 | onPressedChanged: { 65 | if ( pressed ) { 66 | keyboard.updatePopper() 67 | } 68 | } 69 | } 70 | 71 | EnterKey { } 72 | } 73 | -------------------------------------------------------------------------------- /dolphin/SpacebarRowDeadKey.qml: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013 Jolla Ltd. 2 | // Contact: Pekka Vuorela 3 | 4 | import QtQuick 2.2 5 | import com.jolla.keyboard 1.0 6 | import ".." 7 | 8 | KeyboardRow { 9 | id: spacebarRow 10 | 11 | property alias deadKeyCaption: deadKey.caption 12 | property alias deadKeyCaptionShifted: deadKey.captionShifted 13 | 14 | splitIndex: 4 15 | 16 | SymbolKey { 17 | implicitWidth: symbolKeyWidthNarrow 18 | } 19 | DeadKey { 20 | id: deadKey 21 | implicitWidth: punctuationKeyWidthNarrow 22 | separator: SeparatorState.HiddenSeparator 23 | } 24 | ContextAwareCommaKey { 25 | implicitWidth: punctuationKeyWidthNarrow 26 | } 27 | SpacebarKey {} 28 | SpacebarKey { 29 | active: splitActive 30 | languageLabel: "" 31 | } 32 | CharacterKey { 33 | caption: "." 34 | captionShifted: "." 35 | implicitWidth: punctuationKeyWidthNarrow 36 | fixedWidth: !splitActive 37 | separator: SeparatorState.HiddenSeparator 38 | } 39 | EnterKey {} 40 | } 41 | -------------------------------------------------------------------------------- /dolphin/SwipeArea.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. 3 | * Copyright (C) 2012-2013 Jolla Ltd. 4 | * 5 | * Contact: Pekka Vuorela 6 | * 7 | * Redistribution and use in source and binary forms, with or without modification, 8 | * are permitted provided that the following conditions are met: 9 | * 10 | * Redistributions of source code must retain the above copyright notice, this list 11 | * of conditions and the following disclaimer. 12 | * Redistributions in binary form must reproduce the above copyright notice, this list 13 | * of conditions and the following disclaimer in the documentation and/or other materials 14 | * provided with the distribution. 15 | * Neither the name of Nokia Corporation nor the names of its contributors may be 16 | * used to endorse or promote products derived from this software without specific 17 | * prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 23 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | * 29 | */ 30 | 31 | import QtQuick 2.2 32 | import com.jolla.keyboard 1.0 33 | import Sailfish.Silica 1.0 34 | 35 | 36 | 37 | MouseArea { 38 | id: mouseArea 39 | parent: keyboard 40 | anchors.fill: parent 41 | propagateComposedEvents: true 42 | preventStealing: true 43 | property int angle: 0 44 | property int distance: 0 45 | property bool autoRepeat: false 46 | property point start: Qt.point(0, 0); 47 | property int threshold: 16 * (height * 2 > width ? 2 : 1 ) 48 | 49 | property bool swipeT: false 50 | property bool swipeB: false 51 | property bool swipeL: false 52 | property bool swipeR: false 53 | z: 2048 54 | 55 | onPressed: { 56 | start = Qt.point(mouse.x, mouse.y) 57 | angle = 0 58 | distance = 0 59 | var pos = mapToItem(layout, mouse.x, mouse.y) 60 | } 61 | 62 | onClicked: { 63 | root.clicked() 64 | console.warn("SwipeKey") 65 | mouse.accepted = false 66 | } 67 | 68 | onReleased: { 69 | 70 | var pos = mapToItem(layout, mouse.x, mouse.y) 71 | 72 | if ( swipeR === true ) { 73 | 74 | } 75 | 76 | } 77 | 78 | onPositionChanged: { 79 | 80 | angle = Math.atan2(mouse.y - start.y, mouse.x - start.x) * 360 / Math.PI / 2 + 180 81 | var d = Math.sqrt(Math.pow(mouse.x - start.x, 2) + Math.pow(mouse.y - start.y, 2)) 82 | distance = Math.round(d / threshold) 83 | var pos = mapToItem(layout, mouse.x, mouse.y) 84 | 85 | if ( distance > 2 && angle >= 45 && angle <= 134 ) { 86 | swipeT = true 87 | console.warn("XXXXXXXXXXXXXXXXXXXXXXXx") 88 | } else if ( distance >= 0 && angle >= 135 && angle <= 214 ) { 89 | 90 | if ( distance / 4 >= 1 ) { 91 | swipeR = true 92 | console.warn("XXXXXXXXXXXXXXXXXXXXXXXx") 93 | } else { 94 | swipeR = false 95 | console.warn("XXXXXXXXXXXXXXXXXXXXXXXx") 96 | } 97 | 98 | } else if ( distance > 2 && angle >= 215 && angle <= 304 ) { 99 | swipeB = true 100 | console.warn("XXXXXXXXXXXXXXXXXXXXXXXx") 101 | } else if ( distance > 2 ) { 102 | swipeL = true 103 | console.warn("XXXXXXXXXXXXXXXXXXXXXXXx") 104 | } else { 105 | 106 | } 107 | } 108 | 109 | } 110 | -------------------------------------------------------------------------------- /dolphin/SwipeKey.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. 3 | * Copyright (C) 2012-2013 Jolla Ltd. 4 | * 5 | * Contact: Pekka Vuorela 6 | * 7 | * Redistribution and use in source and binary forms, with or without modification, 8 | * are permitted provided that the following conditions are met: 9 | * 10 | * Redistributions of source code must retain the above copyright notice, this list 11 | * of conditions and the following disclaimer. 12 | * Redistributions in binary form must reproduce the above copyright notice, this list 13 | * of conditions and the following disclaimer in the documentation and/or other materials 14 | * provided with the distribution. 15 | * Neither the name of Nokia Corporation nor the names of its contributors may be 16 | * used to endorse or promote products derived from this software without specific 17 | * prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 23 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | * 29 | */ 30 | 31 | import QtQuick 2.2 32 | import com.jolla.keyboard 1.0 33 | import QtMultimedia 5.0 34 | import Sailfish.Silica 1.0 35 | 36 | KeyBase { 37 | id: aCharKey 38 | 39 | property string captionShifted 40 | property string symView 41 | property string symView2 42 | property bool separator: true 43 | property bool showHighlight: true 44 | property string accents 45 | property string accentsShifted 46 | property string nativeAccents // accents considered native to the written language. not rendered. 47 | property string nativeAccentsShifted 48 | property bool fixedWidth 49 | property alias useBoldFont: keyText.font.bold 50 | property alias _keyText: keyText.text 51 | 52 | //keyType: KeyType.CharacterKey 53 | text: keyText.text 54 | 55 | Text { 56 | id: keyText 57 | anchors.centerIn: parent 58 | anchors.horizontalCenterOffset: (leftPadding - rightPadding) / 2 59 | horizontalAlignment: Text.AlignHCenter 60 | verticalAlignment: Text.AlignVCenter 61 | textFormat: Text.PlainText 62 | font.pixelSize: Theme.fontSizeSmall * settings.scale 63 | color: pressed ? Theme.highlightColor : Theme.primaryColor 64 | text: attributes.inSymView && symView.length > 0 ? (attributes.inSymView2 ? symView2 : symView) 65 | : (attributes.isShifted ? captionShifted : caption) 66 | } 67 | 68 | Image { 69 | source: "graphic-keyboard-highlight-top.png" 70 | anchors.right: parent.right 71 | visible: separator 72 | } 73 | 74 | Rectangle { 75 | anchors.fill: parent 76 | z: -1 77 | color: Theme.highlightBackgroundColor 78 | opacity: 0.5 79 | visible: pressed && showHighlight 80 | } 81 | 82 | MouseArea { 83 | id: mouseArea 84 | anchors.fill: parent 85 | //propagateComposedEvents: keyboard.inputHandler === xt9Handler? true: false 86 | //visible: keyboard.inputHandler === xt9Handler? true: false 87 | //propagateComposedEvents: true 88 | //visible: true 89 | z: 1024 90 | propagateComposedEvents: true 91 | property int keyType: KeyType.CharacterKey 92 | 93 | property int angle: 0 94 | property int distance: 0 95 | property bool autoRepeat: false 96 | property point start: Qt.point(0, 0); 97 | property int threshold: 16 * (height * 2 > width ? 2 : 1 ) 98 | 99 | property bool swipeT: false 100 | property bool swipeB: false 101 | property bool swipeL: false 102 | property bool swipeR: false 103 | 104 | 105 | onPressed: { 106 | effectP.play() 107 | start = Qt.point(mouse.x, mouse.y) 108 | angle = 0 109 | distance = 0 110 | var pos = mapToItem(layout, mouse.x, mouse.y) 111 | } 112 | 113 | SoundEffect { 114 | id: effectP 115 | source: "/usr/share/sounds/jolla-ambient/stereo/keyboard_letter.wav" 116 | } 117 | 118 | SoundEffect { 119 | id: effectR 120 | source: "/usr/share/sounds/jolla-ambient/stereo/keyboard_option.wav" 121 | } 122 | 123 | onClicked: { 124 | keyboard.inputHandler.handleKey(keyText.text) 125 | buttonPressEffect.play() 126 | console.warn("SwipeKey") 127 | mouse.accepted = false 128 | } 129 | 130 | onReleased: { 131 | buttonPressEffect.play() 132 | effectR.play() 133 | var pos = mapToItem(layout, mouse.x, mouse.y) 134 | 135 | if ( swipeR === true ) { 136 | 137 | } 138 | 139 | } 140 | 141 | onPositionChanged: { 142 | 143 | angle = Math.atan2(mouse.y - start.y, mouse.x - start.x) * 360 / Math.PI / 2 + 180 144 | var d = Math.sqrt(Math.pow(mouse.x - start.x, 2) + Math.pow(mouse.y - start.y, 2)) 145 | distance = Math.round(d / threshold) 146 | var pos = mapToItem(layout, mouse.x, mouse.y) 147 | 148 | if ( distance > 2 && angle >= 45 && angle <= 134 ) { 149 | swipeT = true 150 | 151 | } else if ( distance >= 0 && angle >= 135 && angle <= 214 ) { 152 | 153 | keyboard.layout.transition = distance / 4 154 | if ( distance / 4 >= 1 ) { 155 | swipeR = true 156 | } else { 157 | swipeR = false 158 | } 159 | 160 | } else if ( distance > 2 && angle >= 215 && angle <= 304 ) { 161 | swipeB = true 162 | 163 | } else if ( distance > 2 ) { 164 | swipeL = true 165 | 166 | } else { 167 | 168 | } 169 | } 170 | 171 | //BACKGROUND 172 | Rectangle { 173 | color: parent.pressed ? Theme.highlightBackgroundColor : "#00000000" 174 | anchors.fill: parent 175 | opacity: 0.4 176 | } 177 | 178 | Rectangle { 179 | id: popper 180 | visible: parent.pressed? true: false 181 | anchors.bottom: parent.top 182 | color: Qt.darker(Theme.highlightBackgroundColor, 1.2) 183 | width: parent.width 184 | height: parent.height 185 | radius: geometry.popperRadius 186 | 187 | Label { 188 | anchors.centerIn: parent 189 | text: keyText.text 190 | } 191 | } 192 | } 193 | } 194 | -------------------------------------------------------------------------------- /dolphin/SwipeSpacebarRow.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Jolla ltd and/or its subsidiary(-ies). All rights reserved. 3 | * 4 | * Contact: Pekka Vuorela 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * Redistributions of source code must retain the above copyright notice, this list 10 | * of conditions and the following disclaimer. 11 | * Redistributions in binary form must reproduce the above copyright notice, this list 12 | * of conditions and the following disclaimer in the documentation and/or other materials 13 | * provided with the distribution. 14 | * Neither the name of Nokia Corporation nor the names of its contributors may be 15 | * used to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 19 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 20 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 | * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | * 28 | */ 29 | import QtQuick 2.2 30 | import com.meego.maliitquick 1.0 31 | import com.jolla.keyboard 1.0 32 | 33 | 34 | KeyboardRow { 35 | splitIndex: 5 36 | property int keyWidth: ( parent.width - shiftKeyWidth ) / 12 37 | 38 | PunctuationKey { 39 | width: keyWidth * 2.2 40 | } 41 | 42 | /*LanguageKey { 43 | width: keyWidth * 2.2 44 | }*/ 45 | 46 | CharacterKey { 47 | caption: MInputMethodQuick.contentType === Maliit.EmailContentType? ".": ( MInputMethodQuick.contentType === Maliit.UrlContentType? ".": ( xt9? ".": "。" ) ) 48 | captionShifted: MInputMethodQuick.contentType === Maliit.EmailContentType? ".": ( MInputMethodQuick.contentType === Maliit.UrlContentType? ".": ( xt9? ".": "。" ) ) 49 | symView: "," 50 | symView2: "," 51 | fixedWidth: true 52 | width: keyWidth * 1.5 53 | } 54 | 55 | SpacebarKey { 56 | width: keyWidth * 4.6 57 | fixedWidth: true 58 | } 59 | 60 | CharacterKey { 61 | caption: MInputMethodQuick.contentType === Maliit.EmailContentType? ".": ( MInputMethodQuick.contentType === Maliit.UrlContentType? ".": ( xt9? ".": "。" ) ) 62 | captionShifted: MInputMethodQuick.contentType === Maliit.EmailContentType? ".": ( MInputMethodQuick.contentType === Maliit.UrlContentType? ".": ( xt9? ".": "。" ) ) 63 | symView: "." 64 | symView2: "." 65 | fixedWidth: true 66 | width: keyWidth * 1.5 67 | } 68 | 69 | EnterKey { width: shiftKeyWidth } 70 | } 71 | -------------------------------------------------------------------------------- /dolphin/SymbolKey.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Jolla ltd. and/or its subsidiary(-ies). All rights reserved. 3 | * 4 | * Contact: Pekka Vuorela 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * Redistributions of source code must retain the above copyright notice, this list 10 | * of conditions and the following disclaimer. 11 | * Redistributions in binary form must reproduce the above copyright notice, this list 12 | * of conditions and the following disclaimer in the documentation and/or other materials 13 | * provided with the distribution. 14 | * Neither the name of Jolla ltd nor the names of its contributors may be 15 | * used to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 19 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 20 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 | * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | * 28 | */ 29 | 30 | import QtQuick 2.2 31 | import com.jolla.keyboard 1.0 32 | import Sailfish.Silica 1.0 33 | 34 | FunctionKey { 35 | id: symbolKey 36 | 37 | property int _charactersWhenPressed 38 | property bool _quickPicking 39 | property string symbolCaption: "A" 40 | 41 | clip: true 42 | caption: attributes.inSymView ? symbolCaption : "#" 43 | implicitWidth: shiftKeyWidth 44 | keyType: KeyType.SymbolKey 45 | 46 | onPressedChanged: { 47 | if (pressed && !keyboard.inSymView && keyboard.lastInitialKey === symbolKey) { 48 | keyboard.deadKeyAccent = "" 49 | keyboard.toggleSymbolMode() 50 | //Dolphin Keyboard: Prevent mouse event leak 51 | keyboard.cancelAllTouchPoints() 52 | _quickPicking = true 53 | } else { 54 | _quickPicking = false 55 | } 56 | 57 | _charactersWhenPressed = keyboard.characterKeyCounter 58 | } 59 | 60 | onClicked: { 61 | if (!_quickPicking || keyboard.characterKeyCounter > _charactersWhenPressed) { 62 | keyboard.toggleSymbolMode() 63 | } 64 | } 65 | 66 | Rectangle { 67 | color: parent.pressed ? Theme.highlightBackgroundColor : Theme.primaryColor 68 | opacity: parent.pressed ? 0.6 : 0.17 69 | radius: geometry.keyRadius 70 | anchors.fill: parent 71 | anchors.margins: Theme.paddingMedium 72 | 73 | } 74 | 75 | 76 | } 77 | -------------------------------------------------------------------------------- /dolphin/TabKey.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. 3 | * Copyright (C) 2012-2013 Jolla Ltd. 4 | * 5 | * Contact: Pekka Vuorela 6 | * 7 | * Redistribution and use in source and binary forms, with or without modification, 8 | * are permitted provided that the following conditions are met: 9 | * 10 | * Redistributions of source code must retain the above copyright notice, this list 11 | * of conditions and the following disclaimer. 12 | * Redistributions in binary form must reproduce the above copyright notice, this list 13 | * of conditions and the following disclaimer in the documentation and/or other materials 14 | * provided with the distribution. 15 | * Neither the name of Nokia Corporation nor the names of its contributors may be 16 | * used to endorse or promote products derived from this software without specific 17 | * prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 23 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | * 29 | */ 30 | 31 | import QtQuick 2.2 32 | import Sailfish.Silica 1.0 33 | import com.jolla.keyboard 1.0 34 | 35 | BackgroundItem { 36 | id: root 37 | 38 | property alias icon: image 39 | property string text: "" // text to be send 40 | property string caption: "" // text to be shown 41 | opacity: enabled ? (pressed ? 0.6 : 1.0) : 0.3 42 | 43 | 44 | Image { 45 | id: image 46 | anchors.centerIn: parent 47 | } 48 | 49 | Text { 50 | anchors.centerIn: parent 51 | horizontalAlignment: Text.AlignHCenter 52 | verticalAlignment: Text.AlignVCenter 53 | font.pixelSize: Theme.fontSizeTiny * settings.scale 54 | font.family: Theme.fontFamily 55 | color: root.pressed ? Theme.highlightColor : Theme.primaryColor 56 | text: root.caption 57 | } 58 | 59 | Rectangle { 60 | color: root.pressed ? Theme.highlightBackgroundColor : Theme.primaryColor 61 | opacity: root.pressed ? 0.6 : 0.16 62 | radius: geometry.keyRadius 63 | 64 | anchors.fill: parent 65 | anchors.margins: Theme.paddingMedium 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /dolphin/TabulatorKey.qml: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * 3 | * Created: 2016 by Eetu Kahelin / eekkelund 4 | * 5 | * Copyright 2016 Eetu Kahelin. All rights reserved. 6 | * 7 | * This file may be distributed under the terms of GNU Public License version 8 | * 3 (GPL v3) as defined by the Free Software Foundation (FSF). A copy of the 9 | * license should have been included with this file, or the project in which 10 | * this file belongs to. You may also find the details of GPL v3 at: 11 | * http://www.gnu.org/licenses/gpl-3.0.txt 12 | * 13 | * If you have any questions regarding the use of this file, feel free to 14 | * contact the author of this file, or the owner of the project in which 15 | * this file belongs to. 16 | *****************************************************************************/ 17 | 18 | import QtQuick 2.2 19 | import Sailfish.Silica 1.0 20 | 21 | FunctionKey { 22 | icon.source: "tab.svg" 23 | key: Qt.Key_Tab 24 | implicitWidth: shiftKeyWidth 25 | Rectangle { 26 | color: parent.pressed ? Theme.highlightBackgroundColor : Theme.primaryColor 27 | opacity: parent.pressed ? 0.6: MInputMethodQuick.actionKeyOverride.highlighted ? 0.4 : 0.17 28 | radius: geometry.keyRadius 29 | anchors.fill: parent 30 | anchors.margins: Theme.paddingMedium 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /dolphin/Toolbar.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.2 2 | import Sailfish.Silica 1.0 3 | import com.meego.maliitquick 1.0 4 | import com.jolla.keyboard 1.0 5 | 6 | Flow { 7 | id: root 8 | property int count 9 | 10 | //Paste 11 | PasteButton { 12 | visible: keyboard.portraitMode && Clipboard.hasText && !fetchMany 13 | height: Theme.itemSizeSmall 14 | onClicked: commit(Clipboard.text) 15 | } 16 | 17 | PasteButtonVertical { 18 | visible: !keyboard.portraitMode && Clipboard.hasText && !fetchMany 19 | height: visible ? Theme.itemSizeSmall : 0 20 | width: visible ? parent.width : 0 21 | popupParent: container 22 | popupAnchor: 2 // center 23 | 24 | onClicked: commit(Clipboard.text) 25 | } 26 | 27 | Component.onCompleted: { 28 | 29 | 30 | var toolbar 31 | toolbar = cursorBar.createObject(root, { }) 32 | //Toolbar 33 | switch(settings.toolbar) { 34 | case 1: 35 | toolbar = cursorBar.createObject(root, { }) 36 | break 37 | case 2: 38 | toolbar = numberBar.createObject(root, { }) 39 | break 40 | case 3: 41 | toolbar = functionBar.createObject(root, { }) 42 | } 43 | } 44 | 45 | //Cursor 46 | Component { 47 | id: cursorBar 48 | 49 | Repeater { 50 | model: ["left", "right", "up", "down"] 51 | 52 | delegate: Component { 53 | CursorKey { 54 | width: height 55 | height: Theme.itemSizeSmall 56 | visible: root.count === 0 ? true : false 57 | direction: modelData 58 | } 59 | } 60 | } 61 | 62 | } 63 | 64 | //Number 65 | Component { 66 | id: numberBar 67 | 68 | Repeater { 69 | model: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"] 70 | 71 | delegate: Component { 72 | CommitKey { 73 | width: height / 2 74 | height: Theme.itemSizeSmall 75 | visible: root.count === 0 ? true : false 76 | caption: modelData 77 | onClicked: MInputMethodQuick.sendCommit(caption) 78 | } 79 | } 80 | } 81 | } 82 | 83 | //Function 84 | 85 | Component { 86 | id: functionBar 87 | 88 | Repeater { 89 | 90 | CommitKey { 91 | width: height 92 | height: Theme.itemSizeSmall 93 | visible: root.count === 0 ? true : false 94 | caption: "HM" 95 | onClicked: MInputMethodQuick.sendKey(Qt.Key_Home, 0, "", Maliit.KeyClick) 96 | } 97 | 98 | CommitKey { 99 | width: height 100 | height: Theme.itemSizeSmall 101 | visible: root.count === 0 ? true : false 102 | caption: "ED" 103 | onClicked: MInputMethodQuick.sendKey(Qt.Key_End, 0, "", Maliit.KeyClick) 104 | } 105 | 106 | CommitKey { 107 | width: height 108 | height: Theme.itemSizeSmall 109 | visible: root.count === 0 ? true : false 110 | caption: "AL" 111 | onClicked: MInputMethodQuick.sendKey(Qt.Key_A, Qt.ControlModifier, 0, "", Maliit.KeyClick) 112 | } 113 | 114 | CommitKey { 115 | width: height 116 | height: Theme.itemSizeSmall 117 | visible: root.count === 0 ? true : false 118 | caption: "CP" 119 | onClicked: MInputMethodQuick.sendKey(Qt.Key_C, Qt.ControlModifier, 0, "", Maliit.KeyClick) 120 | } 121 | 122 | CommitKey { 123 | width: height 124 | height: Theme.itemSizeSmall 125 | visible: root.count === 0 ? true : false 126 | caption: "PS" 127 | onClicked: MInputMethodQuick.sendKey(Qt.Key_V, Qt.ControlModifier, 0, "", Maliit.KeyClick) 128 | } 129 | } 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /dolphin/TopItem.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Jolla ltd. and/or its subsidiary(-ies). All rights reserved. 3 | * 4 | * Contact: Antti Seppala 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * Redistributions of source code must retain the above copyright notice, this list 10 | * of conditions and the following disclaimer. 11 | * Redistributions in binary form must reproduce the above copyright notice, this list 12 | * of conditions and the following disclaimer in the documentation and/or other materials 13 | * provided with the distribution. 14 | * Neither the name of Jolla ltd nor the names of its contributors may be 15 | * used to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 19 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 20 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 | * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | * 28 | */ 29 | 30 | import QtQuick 2.2 31 | import com.jolla.keyboard 1.0 32 | import Sailfish.Silica 1.0 33 | import com.meego.maliitquick 1.0 34 | 35 | CloseGestureArea { 36 | height: Theme.itemSizeSmall 37 | threshold: Math.max(keyboard.height * 0.4, Theme.itemSizeSmall) 38 | onTriggered: MInputMethodQuick.userHide() 39 | } 40 | -------------------------------------------------------------------------------- /dolphin/dolphin.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = aux 2 | 3 | OTHER_FILES = *.qml \ 4 | *.png \ 5 | *.svg 6 | 7 | qml.files = $${OTHER_FILES} 8 | qml.path = /usr/share/maliit/plugins/com/jolla/tide/ 9 | 10 | INSTALLS += qml 11 | -------------------------------------------------------------------------------- /dolphin/graphic-keyboard-highlight-top.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eekkelund/harbour-tIDE/f0d465ce730befdd1d4d4d64dea39d4e08187de6/dolphin/graphic-keyboard-highlight-top.png -------------------------------------------------------------------------------- /dolphin/keyboard_letter.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eekkelund/harbour-tIDE/f0d465ce730befdd1d4d4d64dea39d4e08187de6/dolphin/keyboard_letter.wav -------------------------------------------------------------------------------- /dolphin/keyboard_option.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eekkelund/harbour-tIDE/f0d465ce730befdd1d4d4d64dea39d4e08187de6/dolphin/keyboard_option.wav -------------------------------------------------------------------------------- /dolphin/qmldir: -------------------------------------------------------------------------------- 1 | KeyboardGeometry 1.0 KeyboardGeometry.qml 2 | KeyboardBase 1.0 KeyboardBase.qml 3 | CharacterKey 1.0 CharacterKey.qml 4 | LanguageSelectionPopup 1.0 LanguageSelectionPopup.qml 5 | LanguageSelectionCell 1.0 LanguageSelectionCell.qml 6 | LayoutRow 1.0 LayoutRow.qml 7 | LayoutLoader 1.0 LayoutLoader.qml 8 | FunctionKey 1.0 FunctionKey.qml 9 | BackspaceKey 1.0 BackspaceKey.qml 10 | EnterKey 1.0 EnterKey.qml 11 | ShiftKey 1.0 ShiftKey.qml 12 | SymbolKey 1.0 SymbolKey.qml 13 | SpacebarKey 1.0 SpacebarKey.qml 14 | SpacebarRow 1.0 SpacebarRow.qml 15 | SpacebarRowDeadKey 1.0 SpacebarRowDeadKey.qml 16 | Popper 1.0 Popper.qml 17 | PopperCell 1.0 PopperCell.qml 18 | InputHandler 1.0 InputHandler.qml 19 | PreeditTestHandler 1.0 PreeditTestHandler.qml 20 | NumberLayoutPortrait 1.0 NumberLayoutPortrait.qml 21 | PhoneNumberLayoutPortrait 1.0 PhoneNumberLayoutPortrait.qml 22 | MultiTap 1.0 MultiTap.qml 23 | KeyboardRow 1.0 KeyboardRow.qml 24 | KeyboardLayout 1.0 KeyboardLayout.qml 25 | ClipboardHeader 1.0 ClipboardHeader.qml 26 | QuickPick 1.0 QuickPick.qml 27 | DeadKey 1.0 DeadKey.qml 28 | AccentedCharacterKey 1.0 AccentedCharacterKey.qml 29 | NumberKey 1.0 NumberKey.qml 30 | PasteButton 1.0 PasteButton.qml 31 | PasteInputHandler 1.0 PasteInputHandler.qml 32 | ContextAwareCommaKey 1.0 ContextAwareCommaKey.qml 33 | NumberLayoutLandscape 1.0 NumberLayoutLandscape.qml 34 | PhoneNumberLayoutLandscape 1.0 PhoneNumberLayoutLandscape.qml 35 | TopItem 1.0 TopItem.qml 36 | HwrLayout 1.0 HwrLayout.qml 37 | StrokeLayout 1.0 StrokeLayout.qml 38 | -------------------------------------------------------------------------------- /dolphin/tab.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /dolphin/touchpointarray.js: -------------------------------------------------------------------------------- 1 | var array = new Array 2 | 3 | function findById(id) { 4 | for (var i = 0; i < array.length; i++) { 5 | var point = array[i] 6 | if (point.pointId === id) { 7 | return point 8 | } 9 | } 10 | 11 | return null 12 | } 13 | 14 | function findByKeyId(keyId) { 15 | for (var i = 0; i < array.length; i++) { 16 | var point = array[i] 17 | if (point.pressedKey && point.pressedKey.key === keyId) { 18 | return point 19 | } 20 | } 21 | 22 | return null 23 | } 24 | 25 | function findByKeyType(keyType) { 26 | for (var i = 0; i < array.length; i++) { 27 | var point = array[i] 28 | if (point.pressedKey && point.pressedKey.keyType === keyType) { 29 | return point 30 | } 31 | } 32 | 33 | return null 34 | } 35 | 36 | function remove(point) { 37 | for (var i = 0; i < array.length; i++) { 38 | var item = array[i] 39 | if (item === point) { 40 | array.splice(i, 1) 41 | break 42 | } 43 | } 44 | } 45 | 46 | function addPoint(touchEvent) { 47 | var point = new Object 48 | point.pointId = touchEvent.pointId 49 | point.x = touchEvent.x 50 | point.y = touchEvent.y 51 | point.startX = touchEvent.startX 52 | point.startY = touchEvent.startY 53 | point.pressedKey = null 54 | point.initialKey = null 55 | 56 | array.push(point) 57 | return point 58 | } 59 | -------------------------------------------------------------------------------- /harbour-tide.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Type=Application 3 | X-Nemo-Application-Type=silica-qt5 4 | Icon=harbour-tide 5 | Exec=harbour-tide 6 | Name=tIDE 7 | -------------------------------------------------------------------------------- /harbour-tide.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = subdirs 2 | 3 | SUBDIRS += \ 4 | kbdsrc \ 5 | developkbd \ 6 | dolphin \ 7 | config \ 8 | tide \ 9 | roothelper 10 | 11 | OTHER_FILES += \ 12 | rpm/harbour-tide.spec \ 13 | rpm/harbour-tide.changes \ 14 | harbour-tide.desktop 15 | 16 | desktop.files = harbour-tide.desktop 17 | desktop.path = /usr/share/applications/ 18 | 19 | INSTALLS += desktop 20 | 21 | -------------------------------------------------------------------------------- /kbdsrc/database.cpp: -------------------------------------------------------------------------------- 1 | #include "database.h" 2 | 3 | QString path = "/var/lib/harbour-tide-keyboard/database/"; 4 | 5 | Database::~Database() 6 | { 7 | 8 | } 9 | 10 | Database::Database(QQuickItem *parent) 11 | : QQuickItem(parent) 12 | { 13 | FileWatcher *fs = new FileWatcher(); 14 | connect(fs, SIGNAL(changed(QString)), this, SLOT(changed(QString))); 15 | } 16 | 17 | 18 | void Database::initial(QString name) 19 | { 20 | //If should use properties 21 | if (name != "qml" && name != "js" && name != "py" && name != "sh") { 22 | name = "keywords"; 23 | } 24 | //Check if file exists 25 | if(QFile::exists(path + name + ".sqlite")) { 26 | if ( database.database(name).isValid() == false ) { 27 | database = QSqlDatabase::addDatabase("QSQLITE", name); 28 | } else { 29 | database = QSqlDatabase::database(name); 30 | } 31 | //open database 32 | database.setConnectOptions("QSQLITE_ENABLE_SHARED_CACHE = 1;"); 33 | database.setDatabaseName("/var/lib/harbour-tide-keyboard/database/" + name + ".sqlite"); 34 | database.open(); 35 | QSqlQuery query(database); 36 | query.exec("PRAGMA synchronous = OFF; PRAGMA journal_mode = OFF; PRAGMA default_cache_size =32768; PRAGMA foreign_keys = OFF; PRAGMA count_changes = OFF; PRAGMA temp_store = qvectorMEMORY"); 37 | } 38 | 39 | } 40 | 41 | 42 | QStringList Database::load(QString sql) 43 | { 44 | QList temp; 45 | 46 | QSqlQuery query(database); 47 | query.setForwardOnly(true); 48 | 49 | if( query.exec(sql)) { 50 | 51 | while (query.next()) { 52 | temp << query.value(0).toString(); 53 | } 54 | 55 | } 56 | 57 | return temp; 58 | 59 | } 60 | 61 | void Database::update(QString sql) 62 | { 63 | 64 | QSqlQuery query(database); 65 | query.setForwardOnly(true); 66 | query.exec(sql); 67 | 68 | } 69 | 70 | void Database::adjust(QString name, QString word) 71 | { 72 | QString sql; 73 | sql = "UPDATE " + name + " SET frequency = frequency + 1 WHERE word = \"" + word + "\""; 74 | 75 | QSqlQuery query(database); 76 | query.exec(sql); 77 | } 78 | 79 | void Database::close(QString name) 80 | { 81 | //Check database connection exist or not 82 | if ( database.database(name).isValid() == true ) { 83 | database = QSqlDatabase::database(name); 84 | database.close(); 85 | 86 | } 87 | } 88 | 89 | 90 | //Slot if fileType is changed in config.conf 91 | void Database::changed(QString type) 92 | { 93 | initial(type); 94 | } 95 | 96 | //prediction call 97 | QStringList Database::predict(QString word, QString size) 98 | { 99 | QString sql; 100 | int prefix = word.length() + 1; 101 | sql = "SELECT word FROM predict WHERE word GLOB \"" + word + "*\" AND LENGTH(word) - " + QString::number(prefix) + " >= 0 ORDER BY frequency DESC, sorting DESC LIMIT 0, " + size; 102 | return Database::load(sql); 103 | 104 | } 105 | 106 | -------------------------------------------------------------------------------- /kbdsrc/database.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * 3 | * Created: 2016 by Eetu Kahelin / eekkelund 4 | * 5 | * Copyright 2016 Eetu Kahelin. All rights reserved. 6 | * 7 | * This file may be distributed under the terms of GNU Public License version 8 | * 3 (GPL v3) as defined by the Free Software Foundation (FSF). A copy of the 9 | * license should have been included with this file, or the project in which 10 | * this file belongs to. You may also find the details of GPL v3 at: 11 | * http://www.gnu.org/licenses/gpl-3.0.txt 12 | * 13 | * If you have any questions regarding the use of this file, feel free to 14 | * contact the author of this file, or the owner of the project in which 15 | * this file belongs to. 16 | *****************************************************************************/ 17 | #ifndef DATABASE_H 18 | #define DATABASE_H 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include "filewatcher.h" 32 | 33 | class Database : public QQuickItem 34 | { 35 | 36 | Q_OBJECT 37 | 38 | public slots: 39 | void update(QString sql); 40 | void initial(QString name); 41 | void close(QString name); 42 | void adjust(QString name, QString word); 43 | void changed(QString type); 44 | 45 | public: 46 | ~Database(); 47 | Q_INVOKABLE QStringList load(QString sql); 48 | Q_INVOKABLE QStringList predict(QString sql, QString size); 49 | Database(QQuickItem *parent = 0); 50 | QSqlDatabase database; 51 | 52 | Q_INVOKABLE QStringList develop(QString keys, QString size); 53 | 54 | }; 55 | 56 | 57 | #endif // DATABASE_H 58 | -------------------------------------------------------------------------------- /kbdsrc/filewatcher.cpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * 3 | * Created: 2016 by Eetu Kahelin / eekkelund 4 | * 5 | * Copyright 2016 Eetu Kahelin. All rights reserved. 6 | * 7 | * This file may be distributed under the terms of GNU Public License version 8 | * 3 (GPL v3) as defined by the Free Software Foundation (FSF). A copy of the 9 | * license should have been included with this file, or the project in which 10 | * this file belongs to. You may also find the details of GPL v3 at: 11 | * http://www.gnu.org/licenses/gpl-3.0.txt 12 | * 13 | * If you have any questions regarding the use of this file, feel free to 14 | * contact the author of this file, or the owner of the project in which 15 | * this file belongs to. 16 | *****************************************************************************/ 17 | 18 | #include "filewatcher.h" 19 | 20 | FileWatcher::FileWatcher() 21 | { 22 | watcher=0; 23 | watcher = new QFileSystemWatcher(this); 24 | connect(watcher, SIGNAL(fileChanged(const QString &)), this, SLOT(fileChanged(const QString &))); 25 | connect(watcher, SIGNAL(directoryChanged(const QString &)), this, SLOT(directoryChanged(const QString &))); 26 | watcher->addPath("/var/lib/harbour-tide-keyboard/config/"); 27 | watcher->addPath("/var/lib/harbour-tide-keyboard/config/config.conf"); 28 | } 29 | 30 | void FileWatcher::directoryChanged(const QString & path) 31 | { 32 | } 33 | //checks if config file is changed=different filetype opened 34 | void FileWatcher::fileChanged(const QString & path) 35 | { 36 | QFileInfo checkFile(path); 37 | QSettings settings(QString(path), QSettings::IniFormat); 38 | QString type = settings.value("fileType/type", "qml").toString(); 39 | emit changed(type); 40 | while(!checkFile.exists()){} 41 | watcher->addPath(path); 42 | } 43 | -------------------------------------------------------------------------------- /kbdsrc/filewatcher.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * 3 | * Created: 2016 by Eetu Kahelin / eekkelund 4 | * 5 | * Copyright 2016 Eetu Kahelin. All rights reserved. 6 | * 7 | * This file may be distributed under the terms of GNU Public License version 8 | * 3 (GPL v3) as defined by the Free Software Foundation (FSF). A copy of the 9 | * license should have been included with this file, or the project in which 10 | * this file belongs to. You may also find the details of GPL v3 at: 11 | * http://www.gnu.org/licenses/gpl-3.0.txt 12 | * 13 | * If you have any questions regarding the use of this file, feel free to 14 | * contact the author of this file, or the owner of the project in which 15 | * this file belongs to. 16 | *****************************************************************************/ 17 | #ifndef FILEWATCHER_H 18 | #define FILEWATCHER_H 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | 27 | class FileWatcher : public QObject 28 | { 29 | Q_OBJECT 30 | public: 31 | explicit FileWatcher(); 32 | 33 | signals: 34 | void changed(QString type); 35 | 36 | public slots: 37 | 38 | private slots: 39 | 40 | void directoryChanged(const QString & path); 41 | void fileChanged(const QString & path); 42 | private: 43 | QFileSystemWatcher * watcher; 44 | }; 45 | 46 | #endif // FILEWATCHER_H 47 | -------------------------------------------------------------------------------- /kbdsrc/kbdsrc.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = lib 2 | TARGET = harbour-tide 3 | QT += qml quick sql 4 | CONFIG += qt plugin 5 | 6 | TARGET = $$qtLibraryTarget($$TARGET) 7 | uri = harbour.tide.keyboard 8 | 9 | # Input 10 | SOURCES += \ 11 | database.cpp \ 12 | src.cpp \ 13 | settings.cpp \ 14 | filewatcher.cpp 15 | 16 | 17 | HEADERS += \ 18 | database.h \ 19 | src.h \ 20 | settings.h \ 21 | filewatcher.h 22 | 23 | OTHER_FILES = qmldir 24 | 25 | ## Install 26 | installPath = $$[QT_INSTALL_QML]/$$replace(uri, \\., /) 27 | 28 | qmldir.files = qmldir 29 | qmldir.path = $$installPath 30 | target.path = $$installPath 31 | INSTALLS += target qmldir 32 | -------------------------------------------------------------------------------- /kbdsrc/qmldir: -------------------------------------------------------------------------------- 1 | module harbour.tide.keyboard 2 | plugin harbour-tide 3 | -------------------------------------------------------------------------------- /kbdsrc/settings.cpp: -------------------------------------------------------------------------------- 1 | #include "settings.h" 2 | 3 | Settings::Settings(QQuickItem *parent) 4 | : QQuickItem(parent) 5 | { 6 | 7 | } 8 | 9 | QVariant Settings::load(QString name) 10 | { 11 | QSettings settings("/var/lib/harbour-tide-keyboard/config/config.conf", QSettings::IniFormat); 12 | return settings.value(name); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /kbdsrc/settings.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * 3 | * Created: 2016 by Eetu Kahelin / eekkelund 4 | * 5 | * Copyright 2016 Eetu Kahelin. All rights reserved. 6 | * 7 | * This file may be distributed under the terms of GNU Public License version 8 | * 3 (GPL v3) as defined by the Free Software Foundation (FSF). A copy of the 9 | * license should have been included with this file, or the project in which 10 | * this file belongs to. You may also find the details of GPL v3 at: 11 | * http://www.gnu.org/licenses/gpl-3.0.txt 12 | * 13 | * If you have any questions regarding the use of this file, feel free to 14 | * contact the author of this file, or the owner of the project in which 15 | * this file belongs to. 16 | *****************************************************************************/ 17 | #ifndef SETTINGS_H 18 | #define SETTINGS_H 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | 26 | class Settings : public QQuickItem 27 | { 28 | 29 | Q_OBJECT 30 | 31 | public: 32 | Q_INVOKABLE QVariant load(QString name); 33 | Settings(QQuickItem *parent=0); 34 | }; 35 | 36 | 37 | #endif // SETTINGS_H 38 | -------------------------------------------------------------------------------- /kbdsrc/src.cpp: -------------------------------------------------------------------------------- 1 | #include "src.h" 2 | #include "database.h" 3 | #include "settings.h" 4 | #include 5 | 6 | void src::registerTypes(const char *uri) 7 | { 8 | // @uri harbour.tide.keyboard 9 | qmlRegisterType(uri, 1, 0, "Database"); 10 | qmlRegisterType(uri, 1, 0, "Settings"); 11 | 12 | } 13 | 14 | -------------------------------------------------------------------------------- /kbdsrc/src.h: -------------------------------------------------------------------------------- 1 | #ifndef SRC_H 2 | #define SRC_H 3 | 4 | #include 5 | 6 | class src : public QQmlExtensionPlugin 7 | { 8 | Q_OBJECT 9 | Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface") 10 | 11 | public: 12 | void registerTypes(const char *uri); 13 | }; 14 | 15 | #endif // SRC_H 16 | -------------------------------------------------------------------------------- /roothelper/harbour-tide-root.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Type=Application 3 | Icon=harbour-tide-root 4 | Exec=harbour-tide-root 5 | Name=root@tIDE 6 | -------------------------------------------------------------------------------- /roothelper/icons/108x108/harbour-tide-root.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eekkelund/harbour-tIDE/f0d465ce730befdd1d4d4d64dea39d4e08187de6/roothelper/icons/108x108/harbour-tide-root.png -------------------------------------------------------------------------------- /roothelper/icons/128x128/harbour-tide-root.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eekkelund/harbour-tIDE/f0d465ce730befdd1d4d4d64dea39d4e08187de6/roothelper/icons/128x128/harbour-tide-root.png -------------------------------------------------------------------------------- /roothelper/icons/256x256/harbour-tide-root.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eekkelund/harbour-tIDE/f0d465ce730befdd1d4d4d64dea39d4e08187de6/roothelper/icons/256x256/harbour-tide-root.png -------------------------------------------------------------------------------- /roothelper/icons/86x86/harbour-tide-root.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eekkelund/harbour-tIDE/f0d465ce730befdd1d4d4d64dea39d4e08187de6/roothelper/icons/86x86/harbour-tide-root.png -------------------------------------------------------------------------------- /roothelper/main.cpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * 3 | * Created: 2016-2017 by Eetu Kahelin / eekkelund 4 | * 5 | * Copyright 2016-2017 Eetu Kahelin. All rights reserved. 6 | * 7 | * This file may be distributed under the terms of GNU Public License version 8 | * 3 (GPL v3) as defined by the Free Software Foundation (FSF). A copy of the 9 | * license should have been included with this file, or the project in which 10 | * this file belongs to. You may also find the details of GPL v3 at: 11 | * http://www.gnu.org/licenses/gpl-3.0.txt 12 | * 13 | * If you have any questions regarding the use of this file, feel free to 14 | * contact the author of this file, or the owner of the project in which 15 | * this file belongs to. 16 | *****************************************************************************/ 17 | #include 18 | #include 19 | #include 20 | 21 | int main(int argc, char *argv[]) 22 | { 23 | if (setuid(0)) { 24 | perror("setuid"); 25 | return 1; 26 | } 27 | argv[0] = "/usr/bin/harbour-tide"; 28 | execv(argv[0], argv); 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /roothelper/roothelper.pro: -------------------------------------------------------------------------------- 1 | CONFIG += sailfishapp 2 | 3 | TARGET = harbour-tide-root 4 | 5 | SOURCES += main.cpp 6 | 7 | SAILFISHAPP_ICONS = 86x86 108x108 128x128 256x256 8 | 9 | DISTFILES += \ 10 | icons/86x86/harbour-tide-root.png \ 11 | icons/108x108/harbour-tide-root.png \ 12 | icons/128x128/harbour-tide-root.png \ 13 | icons/256x256/harbour-tide-root.png 14 | 15 | OTHER_FILES = harbour-tide-root.desktop 16 | 17 | 18 | -------------------------------------------------------------------------------- /rpm/harbour-tide.changes: -------------------------------------------------------------------------------- 1 | # Rename this file as harbour-tide.changes to include changelog 2 | # entries in your RPM file. 3 | # 4 | # Add new changelog entries following the format below. 5 | # Add newest entries to the top of the list. 6 | # Separate entries from eachother with a blank line. 7 | 8 | # * date Author's Name version-release 9 | # - Summary of changes 10 | 11 | * Thu Jun 08 2017 Eetu Kahelin 0.2.10-2 12 | -Improved Search 13 | -Possibility to Search/Replace 14 | 15 | * Thu May 25 2017 Eetu Kahelin 0.2.10-1 16 | - Visual changes, splitview and topbar 17 | -Add possibility set as default text editor. Add possibility to edit system files; Root support 18 | 19 | * Wed May 17 2017 Eetu Kahelin 0.2.9-1 20 | -Small cosmetic settings page fixes 21 | -Fix file opening in splitview with system file manager 22 | -Fix untitled saving 23 | 24 | * Tue May 16 2017 Eetu Kahelin 0.2.8-1 25 | -Improvements for system FileManager. Option to use System File Manager as quick file manager 26 | -Highlightning rewrite, faster, better, cleaner, newer, more functionality. Change QRegExp to QRegularExpression. Better multiline, quotation and search highlight 27 | -Settings page rewrite. Add settings shortcut to topbar 28 | -Add option to disable highlight, clean code; create functions 29 | -Break long .qml pages to smaller components 30 | -More fonts 31 | -Bash syntax highlighting 32 | 33 | * Thu May 5 2017 Eetu Kahelin 0.2.7-2 34 | -Minor improvements for highlight. 35 | 36 | * Tue Apr 26 2017 Eetu Kahelin 0.2.7-1 37 | -Harbour version! Released in Jolla store, just the editor part. 38 | -Improved search highlight and improved highlight in general 39 | -New cover 40 | -And small bug fixes, getting ready for Git support 41 | 42 | * Tue Apr 2 2017 Eetu Kahelin 0.2.6-1 43 | -Harbour version! Just the editor part though 44 | -Bugfix: App output working also on SFOS 2.1.x.x 45 | 46 | * Tue Feb 5 2017 Eetu Kahelin 0.2.5-4 47 | -Create ~/tIDE and ~/tIDE/Projects folders automaticly 48 | -Bugfix: if project name different than main.qml file then app not able to run. 49 | -Update swedish translation(eson57) 50 | -'Bugfix': fileowner issues (Issue #11) and multiline working again 51 | 52 | * Tue Jan 31 2017 Eetu Kahelin 0.2.5-1 53 | -Able to start from command line in rootmode. 54 | -Tabulator key settings, (Real tab - 8spaces) 55 | -Bugfix: Linecounting works now WOOoo:) 56 | -Swedish(eson57) and Dutch (d9h02f) translations 57 | -Bugfix: Respect system allowed orientations settings.(Issue#9) 58 | -Bugfix: Come back to right folder when returning from editor and indentation function improving 59 | -Slightly better highlighting time, which affects file opening time 60 | -Fix: Better tab setting, not final though 61 | -Settings page available from EditorPage! 62 | -Better higlighting time, not perfect yet. Multiline needs fix 63 | -Added enterkey icon for searchbar in editorpage(GoAlexander) 64 | 65 | * Wed Jan 18 2017 Eetu Kahelin 0.2-1 66 | - Added tabulator key, visible on Sym view 67 | - Added selecting and jumping words to cursor keys 68 | - Show notification on Python error 69 | - Possibility to navigate to SD Card-Root-usr/share 70 | - Adding files in FileManagerPage possible 71 | - Improved search function 72 | - Improved spec files 73 | - Fixed ShiftKey bug 74 | - Updated keyboard layoyt 75 | - Added support for hw keyboard. CTRL+F and CTRL+S 76 | - Fixed keyboard prediction suggestions bug 77 | - Split view for tablet, quick file change inside editor and scrollable topbar 78 | - Key shortcuts & predicting support for split view 79 | - Fixed bug if building not example project 80 | - Root mode support and renamed directories 81 | - If build has been successfull possibility to install app 82 | - Possibility to change splitter position in split view 83 | - Possibility to delete projects. In CreatorHome via the long-tap-menu in the ListItems, and the pull down menu in ProjectHome. RemorseItem and RemorsePopup in use.(wellef) 84 | - Add support for wrap mode setting for the editor. As a result the editors textarea is now able to flick in both directions when needed.(wellef) 85 | 86 | * Wed Dec 21 2016 Eetu Kahelin 0.1-1 87 | - Initial release 88 | -------------------------------------------------------------------------------- /rpm/harbour-tide.spec: -------------------------------------------------------------------------------- 1 | Name: harbour-tide 2 | 3 | # >> macros 4 | # << macros 5 | 6 | %{!?qtc_qmake:%define qtc_qmake %qmake} 7 | %{!?qtc_qmake5:%define qtc_qmake5 %qmake5} 8 | %{!?qtc_make:%define qtc_make make} 9 | %{?qtc_builddir:%define _builddir %qtc_builddir} 10 | Summary: transportable IDE 11 | Version: 0.2.10 12 | Release: 1 13 | Group: Qt/Qt 14 | License: GPLv3 15 | URL: https://github.com/eekkelund/harbour-tIDE 16 | Source0: %{name}-%{version}.tar.bz2 17 | Requires: sailfishsilica-qt5 >= 0.10.9, qtchooser, qt5-qtdeclarative-qmlscene, pyotherside-qml-plugin-python3-qt5 >= 1.3, rpm-build, meego-rpm-config 18 | # Requires: qt5-qmake, make, gcc-c++, qt5-qtgui-devel, qt5-qtcore-devel, libsailfishapp-devel 19 | BuildRequires: pkgconfig(sailfishapp) >= 1.0.2 20 | BuildRequires: pkgconfig(Qt5Core) 21 | BuildRequires: pkgconfig(Qt5Qml) 22 | BuildRequires: pkgconfig(Qt5Quick) 23 | BuildRequires: desktop-file-utils 24 | 25 | %description 26 | transportable IDE for SailfishOS devices 27 | 28 | %prep 29 | %setup -q -n %{name}-%{version} 30 | 31 | # >> setup 32 | # << setup 33 | 34 | %build 35 | # >> build pre 36 | # << build pre 37 | 38 | %qtc_qmake5 \ 39 | VERSION=%{version} \ 40 | NAME=%{name} 41 | 42 | %qtc_make %{?_smp_mflags} 43 | 44 | # >> build post 45 | # << build post 46 | 47 | %install 48 | rm -rf %{buildroot} 49 | # >> install pre 50 | # << install pre 51 | %qmake5_install 52 | 53 | # >> install post 54 | # << install post 55 | 56 | #So dirty.......... 57 | %post 58 | systemctl-user restart maliit-server.service 59 | install -g nemo -o nemo -d /home/nemo/tIDE/ 60 | install -g nemo -o nemo -d /home/nemo/tIDE/Projects/ 61 | mv /home/nemo/Projects/ /home/nemo/tIDE/ 62 | chown -R nemo:nemo /home/nemo/tIDE/ 63 | 64 | %files 65 | %defattr(4755,root,root,4755) 66 | %{_bindir}/harbour-tide-root 67 | %defattr(755,nemo,nemo,755) 68 | %{_localstatedir}/lib/harbour-tide-keyboard/config/ 69 | %{_localstatedir}/lib/harbour-tide-keyboard/database/ 70 | %defattr(-,root,root,-) 71 | %{_bindir}/%{name}/ 72 | %{_datadir}/%{name}/ 73 | %{_datadir}/applications/%{name}.desktop 74 | %{_datadir}/applications/harbour-tide-root.desktop 75 | %{_datadir}/icons/hicolor/*/apps/%{name}.png 76 | %{_datadir}/icons/hicolor/*/apps/%{name}-root.png 77 | %{_libdir} 78 | %{_datadir}/maliit/plugins/com/jolla/layouts/ 79 | %{_datadir}/maliit/plugins/com/jolla/tide/ 80 | # >> files 81 | # << files 82 | --------------------------------------------------------------------------------