Compare commits

...

163 Commits

Author SHA1 Message Date
Jules Aguillon
5d1a503210 Release 1.26.0 (38) 2024-02-04 23:24:34 +01:00
vedamanavi
d1aa59768d Create layout arabic-hamvaj-tly (#542) 2024-02-04 23:18:33 +01:00
Jules Aguillon
2c52e94e0b Workaround cursor slider bug in Acode
Moving the cursor with setSelection has no effect on Acode, for which
the fallback must be used.
2024-02-04 00:29:07 +01:00
vedamanavi
3adf95a4c9 Add language support for Talysh New Latin (#534) 2024-01-31 01:06:47 +01:00
vedamanavi
44f39059e4 Add layout QWERTY (Talysh New Latin) (#529) 2024-01-28 23:49:27 +01:00
Jules Aguillon
bbc6226839 Redefined the key margin options in percent
Define the key margin options relative to the baseline dimensions of
keys. This removes the doubling of the horizontal margin in landscape
mode.
2024-01-28 19:38:29 +01:00
Jules Aguillon
c5f2c0b727 Send down event for modifiers on time
This allows to use modifiers in combination with other inputs like a
mouse click, for example under termux-x11.

The key down event and notification about modifiers changing are sent
down to KeyEventHandler. A mutable state remember for which modifier
down events have been sent.

When pressing down a modifier with one finger and typing with the
other, it might appear that the modifier is released after the first
time an other key is pressed and then pressed and released for the
following keys.
This prevents unintentionally type two modified keys instead of one
when the second key is pressed while the other is not yet released.
2024-01-26 00:17:51 +01:00
Jules Aguillon
fb27f8d36f check_layout: Warn against whitespaces and "loc" 2024-01-22 20:55:36 +01:00
Jules Aguillon
5beacf32b7 Add Russian vowels combined with the acute accent 2024-01-21 19:47:03 +01:00
Jules Aguillon
ad7314a016 Move layout definitions into srcs/layouts
This separates the layout definitions from the special layouts
(bottom_row, greekmath) and other unrelated files (method, settings).

This is also a more intuitive location for layouts and make the resource
directory easier to navigate.

Under the hood, layouts are copied back into
build/generated-resources/xml.
2024-01-21 16:34:49 +01:00
marciozomb13
bef29da3de Update pt-br translation (#527)
Update translation pt-br
2024-01-21 16:10:26 +01:00
RetrogisusDEV
a55506e607 Light and dark themes for the launcher and settings 2024-01-20 22:37:51 +01:00
abb128
b3dcd61c28 Add <queries> element for detecting IMEs (#526)
To detect voice IMEs, Unexpected Keyboard calls InputMethodManager.getEnabledInputMethodList

Internally, this method eventually calls a method that returns a filtered list of packages that may not include the installed voice IME, and thus Unexpected Keyboard unexpectedly claims no voice input is installed because it can't see it.

The fix is to explicitly state in the manifest that we want to query for other IMEs, based on https://developer.android.com/training/package-visibility/declaring

This is not an issue with Google's voice input or other preinstalled voice inputs because they usually have android:forceQueryable=true, but this is an issue with third-party voice inputs such as FUTO Voice Input. Launching the voice input app after activating the keyboard also usually makes the package visible, so a consistent way to replicate this issue on modern Android is to reboot the device and try triggering voice input from the keyboard
2024-01-18 23:42:29 +01:00
Sergiy Stupar
9257bf7392 Add Ukrainian translation (#525) 2024-01-18 22:44:22 +01:00
Jules Aguillon
95bd9312a7 Allow hidding the keyboard switching key
The keyboard switching key is now selected by default in the Extra Keys
option and can be deselected.
2024-01-15 23:26:40 +01:00
Jules Aguillon
0a86f9ab01 Always show the keyboard switching key
Android's shouldOfferSwitchingToNextInputMethod() method might return
false when an other IME is installed, perhaps when the other IME doesn't
specify android:supportsSwitchingToNextInputMethod="true".
2024-01-15 23:15:16 +01:00
Jules Aguillon
70d777253c Use switchToNextInputMethod instead of switchToPreviousInputMethod
This is warranted by the API.
2024-01-15 22:10:11 +01:00
Jules Aguillon
d7fa5ffa9a Refactor: Clearer names for CHANGE_METHOD* events
The keys are not renamed to retain compatibility.
2024-01-15 22:09:15 +01:00
Jules Aguillon
b114c78bf1 Refactor: Keyboard2View: Take layout id attr
Removes EmojiBottomRow.
2024-01-13 23:22:26 +01:00
Jules Aguillon
eddf9c6c11 Refactor: New namespace for preference classes 2024-01-13 20:59:05 +01:00
Jules Aguillon
148f3dfc05 prefs: Show custom layout names if provided
Show the name of custom layouts in the list if it's provided using the
`name` attribute.
This should make managing several custom layouts easier.
2024-01-10 23:39:19 +01:00
Jules Aguillon
6725d3057b check_layout: Stronger bottom row key check 2024-01-10 23:00:40 +01:00
Jules Aguillon
cf9fd3a0db CI: Fix debug build due to missing release keystore 2024-01-10 00:34:19 +01:00
Jules Aguillon
329a35e7d3 Fix layouts containing empty keys
This results in a key being the empty string and do not trigger an
error:

    key1="\"

Layouts are fixed and check_layout now checks for this case.
2024-01-10 00:28:21 +01:00
Jules Aguillon
b319356a08 Fix crash on shift with empty keys
Tapping shift might call `Utils.capitalize_string` on some symbols
(notably custom keys), which crashes on empty string.

This also happens on builtin layouts with `key1="\"`.
2024-01-10 00:17:09 +01:00
Jules Aguillon
73267d68fb Revert "Remove the vibration settings"
This reverts commits ef03dfed5c and
ff01678ba6.

The "vibration duration" slider is bought back.
The "vibration enabled" option is replaced by "custom vibration", which switch between the system haptic feedback or the custom vibration.

The slider is greyed when "custom vibration" is unchecked and is
allowed to have a value of 0 to disable vibrations within the app.

The intermediate values "light", "medium" and "strong" are removed and
no migration of the setting is made.
2024-01-09 00:43:28 +01:00
Jules Aguillon
3f2f3177da gradle: Enforce release build is signed 2024-01-08 22:49:59 +01:00
Jules Aguillon
e26e1d112c gradle: Name outputs after the application ID 2024-01-08 22:47:21 +01:00
Diego Puma
0005eb2dd5 Update Spanish translations (#517) 2024-01-07 02:18:40 +01:00
Jules Aguillon
8b2c7d9337 Release 1.25.0 (37) 2024-01-03 01:07:22 +01:00
Jules Aguillon
409362ddb4 launcher: Remove intro video when not supported
Previously, this would trigger an error popup and make the activity
unresponsive.
2024-01-03 00:48:26 +01:00
Jules Aguillon
c524caa6f1 Remove unsupported API readAllBytes 2024-01-01 21:04:54 +01:00
Jules Aguillon
7caf60c93b README: Display the intro video 2023-12-31 20:19:58 +01:00
Jules Aguillon
49a6a30773 Add an introduction video in the launcher activity
A video is more intuitive than a written description and doesn't need
translations.
2023-12-31 13:18:15 +01:00
Jules Aguillon
4a5a125aea Bring the voice IME chooser with a long press 2023-12-30 01:24:21 +01:00
Jules Aguillon
51a41ec90a Voice IME chooser popup
Bring a popup for choosing the voice IME when the voice key is pressed
for the first time or the list of voice IMEs installed on the device
change.

A preference stores the last selected IME and the last seen list of
IMEs.
2023-12-30 00:56:55 +01:00
Jules Aguillon
7e7a5e4425 Separate arabic layouts with hindu or arabic numerals
This reverts the Tusinian layout (1af4e45) and instead introduce a new
arabic PC layout with arabic numbers.

Layouts are renamed:
- arab_pc => arab_pc_hindu
- arab_pc_tn => arab_pc
2023-12-26 17:16:29 +01:00
Jules Aguillon
9ff8179d49 Add layout attribute 'numpad_script'
This new attribute is now used instead of 'script' for modifying the
numpad according to the selected layout's script.
If not provided, it defaults to the value of 'script'.
2023-12-26 17:05:51 +01:00
Jules Aguillon
1af4e45117 Add Tunisian layout
It is a copy of the 'arab_pc' layout with arabic digits.
Also, fix the default layout for arabic.
2023-12-21 21:45:56 +01:00
Jules Aguillon
2db4ae3730 Fix the number row showing up on top of pinentry
This wasn't intended and was caused by the "current_layout_unmodified"
optimisation.
2023-12-21 20:59:30 +01:00
polyctena
2aecbca9ac Update strings.xml (#505) 2023-12-20 21:27:19 +01:00
Validbit
dce7e2b9d9 Update strings.xml (cz_CS) (#506) 2023-12-20 21:26:46 +01:00
1
7c12aa610c Update Turkish translations (#501)
Turkish translate update
2023-12-18 19:38:06 +01:00
Chasm Solacer
294ebee6f1 Update Polish translations (#502) 2023-12-18 19:35:56 +01:00
Edgars
bd1afd2c3c Update Latvian translations (#503) 2023-12-18 19:34:15 +01:00
Jules Aguillon
44f6908411 Update French translation 2023-12-17 20:25:43 +01:00
RetrogisusDEV
df04eae85f Launcher activity: Add "Select keyboard" button 2023-12-17 20:10:39 +01:00
Jules Aguillon
d7c230e173 prefs: Use QWERTY (US) as the default custom layout
This layout definition contains some documentation and is a better
default than no text.
2023-12-17 12:41:19 +01:00
Jules Aguillon
478d8082f4 Improve layout parsing errors
Add location information to all error and improve "expected tag" errors.
2023-12-17 12:12:23 +01:00
Jules Aguillon
7af6adcf11 prefs: Report errors while editing custom layouts
Errors are obtained by running the parser, validation is throttle to
when the user stops editing for a second.
2023-12-17 11:58:41 +01:00
Jules Aguillon
dd327cc812 prefs: Render line numbers in custom layout input box
Line numbers will help reporting errors. Also, disable line breaking to
improve readability.
2023-12-10 19:44:50 +01:00
Jules Aguillon
d073523125 shell.nix: Update dependencies and add Gradle
Update OpenJDK to version 17, Android build tools to 33.0.1 and platform to 33.
These are required to build with Gradle.

Add Gradle to the environment, which must be wrapped to fix a
permissions issue. Setting `GRADLE_OPTS` has no effect as it seems not
to be passed down to the daemon.
2023-11-25 20:13:24 +01:00
deftkHD
684d5c7b70 Use Gradle (#452) 2023-11-25 20:11:12 +01:00
deftk
851d22da6e Make check_layout.py independent from dir structure 2023-11-25 19:08:24 +01:00
Jules Aguillon
44adb55544 Separately persisted current layout in landscape mode
Remember the selected layout in portrait and landscape mode
independently.
This allows to define a layout specific to landscape without having to
switch manually.
2023-11-19 20:10:45 +01:00
Jules Aguillon
15de829138 Persist current selected layout 2023-11-19 19:07:54 +01:00
Jules Aguillon
c57d896d8d Update translations
Was missing from the previous commit.
2023-11-19 12:03:39 +01:00
RetrogisusDEV
80c6f97767 Add Desert and Jungle themes 2023-11-19 11:33:39 +01:00
Diego Puma
b0cf9a52b5 Update Spanish translations (#489) 2023-11-13 00:06:43 +01:00
Jules Aguillon
f696452c59 method.xml: Add Armenian 2023-11-13 00:04:31 +01:00
Jules Aguillon
70500ba6f8 Update check_layout.output 2023-11-13 00:03:45 +01:00
Rafael Grigorian
474c693427 Add Armenian layout (#490) 2023-11-13 00:00:25 +01:00
RetrogisusDEV
73060bfc00 Adaptive launcher icon
Existing icons are kept for API < 26.
2023-11-06 20:52:35 +01:00
Reza Hosseinzadeh
60134effdc Remove extra paranthesis in persian layout (#485) 2023-11-01 16:30:01 +01:00
1
838fbc8ef8 Update Turkish translation (#486) 2023-10-31 20:57:42 +01:00
Jules Aguillon
148bed769a Add left/right slider to the emoji pane
This entirely changes the implementation of the bottom row in the emoji
pane.
2023-10-28 20:14:32 +02:00
deftk
3d36ecb34d Make special font glyphs pass linting 2023-10-28 18:48:25 +02:00
Jules Aguillon
2d164ca64f Add '₽' to Russian layout and to the Fn layer
Other currencies are moved on the Fn layer for consistency with the
compose key.
2023-10-21 11:56:56 +02:00
matthiakl
d594242a53 Update the neo2 layout (#477) 2023-10-20 21:06:21 +02:00
Lyubomir Vasilev
bd886a24eb Add Bulgarian BDS layout (#479) 2023-10-20 14:21:14 +02:00
Luke Videckis
7b7202ec1b Add * and @ to Hindi layout (#480) 2023-10-20 12:59:19 +02:00
Jules Aguillon
33653a94cb Add page_up, page_down, home, end to extra keys
The new keys are placed on the corner of the arrow keys. Key
descriptions are added.

They are removed from the Fn layer to avoid showing up twice.
2023-10-20 12:20:25 +02:00
Ojas Bhagavath
5b4345088d Use standard Greek layout in greekmath.xml (#474) 2023-09-24 16:59:47 +02:00
Jules Aguillon
d5cbcb37e3 Preferred position for locale extra_keys
`method.xml` is now able to specify a preferred position for each extra
keys in term of an other key to which it should be placed nearby.

It's implemented for French as an example.
2023-09-24 16:35:24 +02:00
Jules Aguillon
66b1bdc9c9 Refactor: Preferred positions for extra keys
The new PreferredPos class represents where an extra key should be
placed
Currently used to place keys at the same positions they were placed
before.
2023-09-15 18:00:27 +02:00
Jules Aguillon
d771e9d2c7 Refactor: Compute key positions in layouts
`KeyboardData.getKeys()` now returns a map of the keys present on the
layout to their position. Positions are the row, column and swipe
direction.

The computed map is cached in the KeyboardData object as it might be
accessed later by `findKeyWithValue`, which now do less work.
2023-09-10 11:43:56 +02:00
Jules Aguillon
44e2e86f19 Capitalize the first letter of custom keys
This is more useful than turning the entire string full caps.
2023-09-09 14:32:03 +02:00
Jules Aguillon
92a8db5e93 Update auto-capitalisation state when input starts
The initial capitalisation state given by the editor
(`info.initialCapsMode`) is always 0 in many editors.

For some text input types, update the state when typing starts,
disregarding the value given by `info.initialCapsMode`.
2023-09-09 14:15:44 +02:00
Jules Aguillon
687d88f4f7 Per-script numpad
The numeric layout and the optional right hand side numpad are modified
to show the digits belonging to the script used in the current layout.

The numpads are still defined as it was before. The digits are changed
in `modify_numpad` if needed.
2023-09-03 23:38:55 +02:00
Jules Aguillon
b079e5cf43 Consistent layout for optional numpad
Modify the optional right hand numpad the same way as the numeric
layout.
2023-09-03 23:36:49 +02:00
Jules Aguillon
86038ef512 check_layout.py: Deterministic output order 2023-09-03 20:15:31 +02:00
Jules Aguillon
816269aed0 Remove unused editing keys from the settings
These keys don't seem to have a purpose, which is confusing.
2023-09-03 15:05:23 +02:00
Ben Slusky
234986817f Change Greek math koppa to lowercase (#457)
Uppercase koppa can still be entered as shift+koppa.
2023-08-30 09:33:36 +02:00
pharook
f4a995e2bd Add Czech QWERTY layout (#455) 2023-08-28 19:16:39 +02:00
Jules Aguillon
f07fbaff3b CONTRIBUTING: Fix typos 2023-08-27 17:44:13 +02:00
Jules Aguillon
3530263083 CONTRIBUTING: Improve translation guidelines 2023-08-27 17:39:04 +02:00
Jules Aguillon
9b917e79b1 Fix regression on Ctrl on space bar slider
This makes Ctrl+move_cursor the same as before 5123ce5.
2023-08-26 23:44:41 +02:00
Jules Aguillon
f4c11d99ed Disable automatically Shift when pressing Ctrl
Automatic capitalisation might interferes with keyboard shortcuts.
2023-08-26 23:37:22 +02:00
Jules Aguillon
cf76118548 Add missing combining accents
Implement the combinations that were previously not possible and were
commented out.

Also remove `apply_dead_char` and `apply_combining` and make all
dead-keys definitions uniform.
2023-08-20 01:03:14 +02:00
Jules Aguillon
40498e7b4c Refactor: Allow combining diacritics modifiers
Change the API of `KeyModifier.Map_char` to allow returning a string
instead of a single 16 bits char.

This allows to return combining diacritics.

This also gets rid of `apply_map_or_dead_char`, maps can have their own
fallback.
2023-08-20 00:44:22 +02:00
Jules Aguillon
cd5ca56226 Release 1.24.0 (36) 2023-08-18 12:29:17 +02:00
Shareef101
491e72f247 Add urdu phonetic layout (#413) 2023-08-18 12:20:41 +02:00
Dimethylebutane
c3a5dc63f2 Added french bépo layout (adapted) (#402) 2023-08-18 12:15:43 +02:00
Eluc
6cb6f2541b Add Bitcoin symbol to Fn+b (#434) 2023-08-18 12:14:20 +02:00
Jules Aguillon
5123ce5417 Fix slider movements changing input focus
The slider was repeatedly sending arrow keys, which change the focused
input when the end of a text box is hit.

A new key is added that implements cursor movements using the
`InputConnection` API.
The new keys are defined as `KeyValue.Editing`, which are no longer only
context menu actions.

The behavior when a selection has started is changed. The selection is
modified instead of cleared even when shift isn't pressed or the
selection would become empty.

Fallbacks to sending arrow keys for editors that do not support the API,
like Termux.
2023-08-17 12:47:44 +02:00
Jules Aguillon
2dc0ce066d Fix inconsistent initial spacing between keys
Settings defined with `get_dip_pref` had a wrong default value on first
launch.

The "right" default value was used after the shared preferences are
populated.
2023-08-16 18:25:20 +02:00
Eluc
ab05d8314b Create latn_qwertz_fr_CH.xml (#390)
Adapted from qwertz DE to match qwertz fr_CH layout.

Added all missing characters with accents needed in French while leaving the most common Swiss German characters as it is on the Swiss layout PC keyboard.
Re-organized some special characters to be in a similar position than the PC layout.

* Add locale fr-CH
2023-08-16 16:14:38 +02:00
Validbit
405e63d5c2 Move voice input key (#433)
Move the voice input key to the top-left corner of the return key to reduce accidentally entering voice input, which is disrupting.
2023-08-16 12:27:00 +02:00
Jules Aguillon
5822f98bbb Migrate layouts preferences
The new `layouts` preference replaces three previous preferences:

    layout
    second_layout
    custom_layout

Add a preference migration function, which first migration is to
migrate layouts into the new preference.

The migration must also be called from the SettingsActivity as it might
use a different preference store due to the boot-aware preference copy.
2023-08-16 12:21:40 +02:00
Jules Aguillon
613aa283bd LayoutsPreference: Remove cross button for custom layouts
Remove the cross button on the right of custom layouts to reduce
accidental removal.
A remove button is added in the dialog for modifying the layout.
2023-08-16 12:21:38 +02:00
Jules Aguillon
ddceb69d4e LayoutsPreference: Modify custom layout
Clicking on a custom layout opens a dialog for modifying the layout
description instead of the dialog for selecting a layout.
2023-08-16 12:21:25 +02:00
Jules Aguillon
4584e8289b Remove unused class LayoutListPreference
This class is not used since the introduction of [LayoutsPreference].
2023-08-16 12:21:25 +02:00
Jules Aguillon
febc23776f ListGroupPreference: Fix change items
[Preference.onClick] is apparently not called on [Item]s, though it is
on [AddButton].

Workaround this by listening on click events on the view.
2023-08-16 12:21:25 +02:00
Jules Aguillon
500f4e41d3 Allow multiple custom layouts
This merges the "Layouts" option with the "Custom layout" option.
A custom layout becomes an item in the "Layouts" list among the other
layouts. It's possible to add several custom layouts.

Selecting the "Custom layout" item in the list opens a second dialog for
entering the layout description.

Layouts are serialized as JSON object and are decoded solely in the
LayoutsPreference class.
2023-08-16 12:21:23 +02:00
Jules Aguillon
8611dbcfa0 CustomExtraKeysPreference: Reusable edit text layout
This layout is generically used by CustomExtraKeysPreference and
LayoutsPreference.
2023-08-16 12:20:40 +02:00
Jules Aguillon
03f2b8df70 ListGroupPreference.Serializer: Allow exceptions
(De)serializing might raise exceptions, which are handled by dropping
the failing item.
2023-08-16 12:20:40 +02:00
Jules Aguillon
0269cd65ea ListGroupPreference: Make items abstract
Allow items to be of any class instead of strings.

Item serialization and deserialization methods are in a separate class
because they are also used in a static context.
2023-08-16 12:20:40 +02:00
polyctena
20ab3915e8 Update German Strings (#430)
Co-authored-by: Benjamin <f.weiss@stud.uni-goettingen.de>
2023-08-15 20:18:35 +02:00
Edgars
39a751a497 Add missing Latvian translations (#425) 2023-08-08 16:38:34 +02:00
Chasm Solacer
1ad8f79b5c Updated pl (Polish) translation (#424) 2023-08-07 20:48:13 +02:00
Validbit
12de2733a8 Updated Czech translation (#421) 2023-08-07 20:16:45 +02:00
sdrapha
78f521250f Update pt-Br translations 2023-08-07 18:38:53 +02:00
sdrapha
29106bc69a Add Superscript and Subscript letters 2023-08-07 18:38:53 +02:00
Rapha
f522a678f9 Add superscript, subscript, ª and º to optional extrakeys
And add description strings.
2023-08-07 18:38:53 +02:00
Rapha
c17dfdfe13 Add ordinals to ptbr extrakeys 2023-08-07 18:38:53 +02:00
Jules Aguillon
21316b77d7 Don't elide label of non-string keys
Several non-string keys can have a large label that shouldn't be elided,
for example ctrl, meta, send.

Also, change the cutoff to 3 characters as labels are easily colliding.
2023-08-07 13:11:21 +02:00
Jules Aguillon
eeae964ae6 check_layout: Warn about duplicate keys 2023-08-06 20:09:53 +02:00
Jules Aguillon
8d7b3efeb1 LayoutsPreference: Show layout display names
The internal name of layouts was rendered.
2023-08-06 19:54:38 +02:00
Jules Aguillon
ddc4ff1378 Describe editing keys
The new strings are used in the "Add keys to the keyboard" option.
2023-08-06 19:35:06 +02:00
Jules Aguillon
1c59347cca Add glyphs for editing keys
All from Material Design Icons.
2023-08-06 19:17:05 +02:00
Jules Aguillon
eb56c80ffb Elide custom keys labels
Make the font smaller for custom keys with a length above 1.
Draw up to 4 characters on keys.
2023-08-06 18:22:15 +02:00
Jules Aguillon
4d10556d49 Don't replace user selected dead keys
Don't replace dead-keys selected in the "Add keys to the keyboard"
option by an alternative.
2023-08-06 17:15:36 +02:00
Jules Aguillon
1eea9e25d2 Remove the Accents option
This option makes less sense since per-script extra keys. It's also
getting in the way of an eventual "dead-key or accented-letters" option.
2023-08-06 17:15:35 +02:00
Jules Aguillon
45905f5f3b Replace dead-keys when there's one alternative
The dead-key is replaced by its alternative if there's only one
specified.
Extra keys from every subtypes must be merged together to be able to
make this check.
2023-08-06 17:14:23 +02:00
Jules Aguillon
c26343cd42 method.xml: Specify extra keys alternatives 2023-08-06 17:14:23 +02:00
Jules Aguillon
cd95c589de Extra keys alternatives
For each extra key, a list of alternative can be specified. An extra key
won't be added to the keyboard if all its alternatives are already
present on it.

This is useful to avoid having the dead key for an accent and the
accented letters at the same time.
2023-08-06 17:14:23 +02:00
Rapha
0924df8d13 Update translations pt-br (#420) 2023-08-06 12:19:51 +02:00
Chasm Solacer
0fea071352 Updated pl (Polish) translation (#419) 2023-08-06 00:13:37 +02:00
Jules Aguillon
c46e5ec450 Add esc and tab to the Persian layout 2023-08-05 19:44:00 +02:00
Jules Aguillon
6054c2eec8 Add Persian to method.xml 2023-08-05 19:40:13 +02:00
Jules Aguillon
dcbb4c484c Modify arabic and persian numbers info function keys
And add function keys placeholders in the layouts.
2023-08-05 19:40:13 +02:00
Jules Aguillon
76f01122c2 Tweak check_layout.py
- Warn about missing esc, tab, f11_placeholder and f12_placeholder.
- Don't check non-layout files and special layouts.
2023-08-05 19:40:13 +02:00
Stephen Karl Larroque
94bd9c6bc8 docs: mention Calculator++ (#418)
* docs: mention Calculator++

Signed-off-by: Stephen L. <LRQ3000@gmail.com>
2023-08-05 17:37:27 +02:00
Jules Aguillon
7ce0c6e37a sync_translations.py: Report number of missing strings 2023-08-05 17:27:56 +02:00
Jules Aguillon
9ea06594d1 Update French translations 2023-08-05 16:52:26 +02:00
Jules Aguillon
ae791ab292 Translatable key descriptions
Key descriptions are shown in the "extra keys" option and can now be
translated.
2023-08-05 16:45:57 +02:00
Jules Aguillon
8b95053566 LauncherActivity: Visible, clickable and untranslatable link
The link to Github was not clickable and couldn't easily be made so in
its current form.

Render the link in its own paragraph and do not hide the URL.
2023-08-04 17:31:06 +02:00
Jules Aguillon
e0dd145bb4 Correct Farsi strings 2023-08-04 17:11:00 +02:00
Jules Aguillon
4abea0e878 Settings: Increase vibration values 2023-08-02 21:02:07 +02:00
Jules Aguillon
be97364b34 font: Move glyphs into the PUA
Glyphs in the Private Use Area at uE000 will no longer conflict with
fallback fonts in the "extra keys" option.
2023-08-02 20:39:37 +02:00
Jules Aguillon
3c3955e583 Settings: Move "extra keys" higher on the page
And "Accents" lower.
2023-08-02 20:17:41 +02:00
Jules Aguillon
22458cd445 check_layout.py: Warn about editing and function keys 2023-08-02 12:09:15 +02:00
Jules Aguillon
3598e19894 Update check_layout.output 2023-07-31 00:10:49 +02:00
Jules Aguillon
9bd8b08544 ListGroupPreference: Allow to modify items 2023-07-30 23:34:48 +02:00
Jules Aguillon
dad5f57a03 Allow more than 2 layouts
The two layout selection options are replaced by a ListGroupPreference
that allow to enter an arbitrary amount of layouts.

The "switch_second" and "switch_second_back" keys are replaced by
"switch_forward" and "switch_backward", which allow to cycle through the
selected layouts in two directions.

Layouts are changed to place these two key on the space bar.
The backward key is not shown if there's only two layouts.
2023-07-30 21:44:14 +02:00
Jules Aguillon
818aa4c7d5 ListGroupPreference: Allow hide the "remove" button 2023-07-30 21:34:01 +02:00
Jules Aguillon
b4a1ac48bb ListGroupPreference: Overrideable "add" button 2023-07-30 21:34:01 +02:00
Jules Aguillon
0856fb4e31 Refactor: Split out ListGroupPreference
Split out the implementation of a string-list preference from
CustomExtraKeysPreference.

Allows to share the implementation with future preferences.
2023-07-29 18:42:36 +02:00
Ben Slusky
0a114bd2bc Add dagger, double dagger, section mark, and pilcrow as extra keys on QWERTY-like layouts (#410)
* Add section mark as an extra key in QWERTY-like layouts that don't have it already

* Add dagger (also double dagger) as an extra key in QWERTY-like layouts
2023-07-29 18:42:20 +02:00
Jules Aguillon
427ef6a97d Add '=' to pin entry layout
Might be useful in spreadsheets.
2023-07-29 17:40:21 +02:00
Jules Aguillon
fce8ff7ce2 Add option to disable pin entry layout
The pin entry layout might be inferior for some usecases and people
might be more used to the numeric layout.
2023-07-29 17:29:45 +02:00
KuRa KuRd
d1f0d5a7bf Correct Kurdish layout name (#407)
Correct layout name to Kurdish because Kurdish and Arabic are totally two different language.
2023-07-23 17:09:57 +02:00
adu
f60927edac Updated Spanish translation (#404) 2023-07-20 14:02:18 +02:00
Jules Aguillon
8b2c07c9cb Refactor: Centralize logging in a static class
This new class will help write more logs. The LogPrinter is no longer
created everytime the keyboard is opened.

An error log is added if failing to load the custom extra keys.
2023-07-19 23:30:58 +02:00
Jules Aguillon
458e17bf31 Add custom extra keys preference
This is a new section in the extra keys option that allows to enter
arbitrary strings which are then added to the keyboard.

A new string is needed for the title of the section, Android's icons and
strings are used as much as possible to avoid adding more strings.

Keys are stored in the preferences as a JSON array of strings.
2023-07-19 23:30:58 +02:00
Jules Aguillon
324aa26ba4 Refactor: Make KeyValue.makeStringKey public 2023-07-19 23:30:58 +02:00
Jules Aguillon
6747669c2d Refactor: Use a PreferenceCategory for extra keys
This removes the need for a layout definition and adds a title before
the prefs.
It's a prerequise for the custom keys preference.
2023-07-19 23:30:58 +02:00
Reza Hosseinzadeh
1097b297d3 Improve the Persian layout (#397)
Change some characters' position
2023-07-17 19:33:09 +02:00
Jules Aguillon
4669192a01 Refactor: Don't define extra keys in xml
The current approach is hard to maintain, for example the last key
"autofill" was not displayed.

This implements a PreferenceGroup that contains the check boxes for
every extra keys without involving listing the preferences in
settings.xml.

A custom layout is used to remove the 'title' text view.
The list of extra keys is moved into the new class.
'ExtraKeyCheckBoxPreference' becomes a nested class.
2023-07-09 18:14:43 +02:00
Jules Aguillon
a2957a43d6 Add symbol ₴ to Fn+h and to Ukrainian 2023-07-09 16:12:13 +02:00
Jules Aguillon
37d4a523bb Remove use of Arrays.copyOf
The function has been added in API 9.
2023-07-05 18:58:27 +02:00
Validbit
ef4477d50c Updated/Added Czech translation + 2 common Fn keys (#387) 2023-07-02 16:12:19 +02:00
Jules Aguillon
7f79bc358d Fix descriptions
Short description can't exceed 80 characters.
Removed trailing space.
2023-07-01 17:44:14 +02:00
189 changed files with 5202 additions and 2073 deletions

View File

@@ -12,36 +12,37 @@ jobs:
- uses: actions/setup-java@v3 - uses: actions/setup-java@v3
with: with:
distribution: 'zulu' # See 'Supported distributions' for available options distribution: 'zulu' # See 'Supported distributions' for available options
java-version: '11' java-version: '17'
- name: Checkout repo - name: Checkout repo
uses: actions/checkout@v3 uses: actions/checkout@v3
- name: Cache debug certificate - name: Restore debug keystore from GitHub Secrets
uses: actions/cache@v3
with:
path: _build/debug.keystore
key: debug-keystore
- name: Restore debug keystore from github Secrets
run: | run: |
mkdir -p _build
cd "_build"
# Check if exist and use the secret named DEBUG_KEYSTORE # Check if exist and use the secret named DEBUG_KEYSTORE
# The contents of the secret can be obtained - # The contents of the secret can be obtained -
# from the debug.keystore.asc from you local _build folder # from the debug.keystore.asc from you local folder (refer to CONTRIBUTING.md#Using the local debug.keystore on the Github CI actions)
if [[ ! "${{ secrets.DEBUG_KEYSTORE }}" = "" ]]; then if [[ ! "${{ secrets.DEBUG_KEYSTORE }}" = "" ]]; then
echo "${{ secrets.DEBUG_KEYSTORE }}" > "debug.keystore.asc" echo "${{ secrets.DEBUG_KEYSTORE }}" > "debug.keystore.asc"
if [[ -s "debug.keystore.asc" ]]; then if [[ -s "debug.keystore.asc" ]]; then
echo "Restoring debug keystore from GitHub secrets"
gpg -d --passphrase "debug0" --batch "debug.keystore.asc" > "debug.keystore" gpg -d --passphrase "debug0" --batch "debug.keystore.asc" > "debug.keystore"
fi fi
fi fi
- name: Build - name: Build debug APK
run: make uses: gradle/gradle-build-action@v2
env:
DEBUG_KEYSTORE: "debug.keystore"
DEBUG_KEYSTORE_PASSWORD: debug0
DEBUG_KEY_ALIAS: debug
DEBUG_KEY_PASSWORD: debug0
with:
arguments: assembleDebug
- name: Artifact naming - name: Artifact naming
run: | run: |
artifact="${{github.repository_owner}} ${{github.ref_name}}" artifact="${{github.repository_owner}} ${{github.ref_name}}"
artifact="${artifact//\//-}" # replace slashes artifact="${artifact//\//-}" # replace slashes
echo "artifact=${artifact}" >> $GITHUB_ENV echo "artifact=${artifact}" >> $GITHUB_ENV
- name: Save debug apk - name: Upload debug APK
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v3
with: with:
name: "${{env.artifact}} debug_apk" name: "${{env.artifact}} debug_apk"
path: _build/*.apk path: build/outputs/apk/debug/*.apk

10
.gitignore vendored
View File

@@ -1,4 +1,12 @@
*.keystore *.keystore
*.keystore.asc *.keystore.asc
_build
/*-keystore.conf /*-keystore.conf
*.iml
.gradle
/local.properties
/.idea
.DS_Store
/captures
/build
# Directory _build is not used anymore
/_build

View File

@@ -1,19 +1,18 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="juloo.keyboard2" android:versionCode="35" android:versionName="1.23.0" android:hardwareAccelerated="false"> <manifest xmlns:android="http://schemas.android.com/apk/res/android" android:hardwareAccelerated="false">
<uses-sdk android:minSdkVersion="4" android:targetSdkVersion="33"/> <application android:label="@string/app_name" android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:hardwareAccelerated="false">
<application android:label="@string/app_name" android:allowBackup="true" android:icon="@drawable/ic_launcher" android:hardwareAccelerated="false">
<service android:name="juloo.keyboard2.Keyboard2" android:label="@string/app_name" android:permission="android.permission.BIND_INPUT_METHOD" android:exported="true" android:directBootAware="true"> <service android:name="juloo.keyboard2.Keyboard2" android:label="@string/app_name" android:permission="android.permission.BIND_INPUT_METHOD" android:exported="true" android:directBootAware="true">
<intent-filter> <intent-filter>
<action android:name="android.view.InputMethod"/> <action android:name="android.view.InputMethod"/>
</intent-filter> </intent-filter>
<meta-data android:name="android.view.im" android:resource="@xml/method"/> <meta-data android:name="android.view.im" android:resource="@xml/method"/>
</service> </service>
<activity android:name="juloo.keyboard2.SettingsActivity" android:icon="@drawable/ic_launcher" android:label="@string/settings_activity_label" android:theme="@style/android:Theme.DeviceDefault" android:exported="true" android:directBootAware="true"> <activity android:name="juloo.keyboard2.SettingsActivity" android:icon="@mipmap/ic_launcher" android:label="@string/settings_activity_label" android:theme="@style/appTheme" android:exported="true" android:directBootAware="true">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN"/> <action android:name="android.intent.action.MAIN"/>
</intent-filter> </intent-filter>
</activity> </activity>
<activity android:name="juloo.keyboard2.LauncherActivity" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/android:Theme.DeviceDefault" android:exported="true" android:directBootAware="true"> <activity android:name="juloo.keyboard2.LauncherActivity" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme="@style/appTheme" android:exported="true" android:directBootAware="true">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN"/> <action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/> <category android:name="android.intent.category.LAUNCHER"/>
@@ -22,4 +21,11 @@
</application> </application>
<uses-permission android:name="android.permission.VIBRATE"/> <uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<!-- To query enabled input methods for voice IME detection -->
<queries>
<intent>
<action android:name="android.view.InputMethod" />
</intent>
</queries>
</manifest> </manifest>

View File

@@ -4,52 +4,46 @@ Thanks for contributing :)
## Building the app ## Building the app
The application doesn't use Gradle and it might be hard to use some features of The application uses Gradle and can be used with Android Studio, but using
Android Studio. Android Studio is not required. The build dependencies are:
- OpenJDK 17
Fortunately, there's not many dependencies:
- OpenJDK 8
- Android SDK: build tools (minimum `28.0.1`), platform `30` - Android SDK: build tools (minimum `28.0.1`), platform `30`
- Make sure to have the `$ANDROID_HOME` environment variable set.
Python 3 is required to update generated files but not to build the app.
For Android Studio users, no more setup is needed.
For Nix users, the right environment can be obtained with `nix-shell ./shell.nix`. For Nix users, the right environment can be obtained with `nix-shell ./shell.nix`.
Instructions to install Nix are [here](https://nixos.wiki/wiki/Nix_Installation_Guide). Instructions to install Nix are [here](https://nixos.wiki/wiki/Nix_Installation_Guide).
If you don't use Android Studio or Nix, you have to inform Gradle about the
location of your Android SDK by either:
- Setting the `ANDROID_HOME` environment variable to point to the android sdk or
- Creating the file `local.properties` and writing
`sdk.dir=<location_of_android_home>` into it.
Building the debug apk: Building the debug apk:
```sh ```sh
make ./gradlew assembleDebug
``` ```
If the build succeed, the debug apk is located in `_build/juloo.keyboard2.debug.apk`. Nix users can call gradle directly: `gradle assembleDebug`.
## Using the local debug.keystore on the Github CI actions If the build succeeds, the debug apk is located in `build/outputs/apk/debug/app-debug.apk`.
It's possible to save the local debug.keystore into a github secret, so the same keystore is utilized to build the debug apk in the CI github actions.
Doing this, they wil have the same signature, thus the debug apk can be updated without having to uninstall it first.
After you sucessfully run `make`, (thus a debug.keystore exists) you can use this second command to generate a base64 stringified version of it
```sh
cd _build
gpg -c --armor --pinentry-mode loopback --passphrase debug0 --yes "debug.keystore"
```
A file will be generated inside the local `_build/` folder, called `debug.keystore.asc`
You can copy the content of this file, and with that, paste it into a new github secret in your repo settings.
The secret must be named `DEBUG_KEYSTORE`
## Debugging on your phone ## Debugging on your phone
First [Enable adb debugging on your device](https://developer.android.com/studio/command-line/adb#Enabling). First [Enable adb debugging on your device](https://developer.android.com/studio/command-line/adb#Enabling).
Then connect your phone to your computer using an USB cable or wireless Then connect your phone to your computer using an USB cable or via wireless
debugging. debugging.
If you use Android Studio, this process will be automatic and you don't have to
follow this guide anymore.
And finally, install the application with: And finally, install the application with:
```sh ```sh
make installd ./gradlew installDebug
``` ```
The released version of the application won't be removed, both versions will The released version of the application won't be removed, both versions will
@@ -57,11 +51,13 @@ be installed at the same time.
## Debugging the application: INSTALL_FAILED_UPDATE_INCOMPATIBLE ## Debugging the application: INSTALL_FAILED_UPDATE_INCOMPATIBLE
`make installd` can fail with the following error message: `./gradlew installDebug` can fail with the following error message:
``` ```
adb: failed to install _build/juloo.keyboard2.debug.apk: Failure [INSTALL_FAILED_UPDATE_INCOMPATIBLE: Package juloo.keyboard2.debug signatures do not match previously installed version; ignoring!] FAILURE: Build failed with an exception.
make: *** [Makefile:20: installd] Error 1 * What went wrong:
Execution failed for task ':installDebug'.
> java.util.concurrent.ExecutionException: com.android.builder.testing.api.DeviceException: com.android.ddmlib.InstallException: INSTALL_FAILED_UPDATE_INCOMPATIBLE: Existing package juloo.keyboard2.debug signatures do not match newer version; ignoring!
``` ```
The application can't be "updated" because the temporary certificate has been The application can't be "updated" because the temporary certificate has been
@@ -70,36 +66,53 @@ The application must be enabled again in the settings.
```sh ```sh
adb uninstall juloo.keyboard2.debug adb uninstall juloo.keyboard2.debug
make installd ./gradlew installDebug
``` ```
## Specifying a debug signing certificate on Github Actions
It's possible to specify the signing certificate that the automated build
should use.
After you successfully run `./gradlew asssembleDebug`, (thus a debug.keystore
exists) you can use this second command to generate a base64 stringified
version of it:
```sh
gpg -c --armor --pinentry-mode loopback --passphrase debug0 --yes "debug.keystore"
```
This will create the file `debug.keystore.asc`, paste its content into a new
Github secret named `DEBUG_KEYSTORE`.
## Guidelines ## Guidelines
### Adding a layout ### Adding a layout
Layouts are defined in XML, see `res/xml/latn_qwerty_us.xml`. Layouts are defined in XML, see `srcs/layouts/latn_qwerty_us.xml`.
An online tool for editing layout files written by @Lixquid is available An online tool for editing layout files written by @Lixquid is available
[here](https://unexpected-keyboard-layout-editor.lixquid.com/). [here](https://unexpected-keyboard-layout-editor.lixquid.com/).
Makes sure to specify the `name` attribute like in `latn_qwerty_us.xml`, Makes sure to specify the `name` attribute like in `latn_qwerty_us.xml`,
otherwise the layout won't be added to the app. otherwise the layout won't be added to the app.
The layout file must be placed in the `res/xml/` directory and named according to: The layout file must be placed in the `srcs/layouts` directory and named
according to:
- script (`latn` for latin, etc..) - script (`latn` for latin, etc..)
- layout name (eg. the name of a standard) - layout name (eg. the name of a standard)
- country code (or language code if more adequate) - country code (or language code if more adequate)
Then, run `make gen_layouts` to add the layout to the app. Then, run `./gradlew genLayoutsList` to add the layout to the app.
The last step will update the file `res/values/layouts.xml`, that you should The last step will update the file `res/values/layouts.xml`, that you should
not edit directly. not edit directly.
Run `make check_layouts` to check some properties about your layout. This will Run `./gradlew checkKeyboardLayouts` to check some properties about your
change the file `check_layout.output`, which you should commit. layout. This will change the file `check_layout.output`, which you should
commit.
#### Adding a programming layout #### Adding a programming layout
A programming layout must contains every ASCII characters. A programming layout must contain all ASCII characters.
The current programming layouts are: QWERTY, Dvorak and Colemak. The current programming layouts are: QWERTY, Dvorak and Colemak.
See for example, Dvorak, added in https://github.com/Julow/Unexpected-Keyboard/pull/16 See for example, Dvorak, added in https://github.com/Julow/Unexpected-Keyboard/pull/16
@@ -133,25 +146,42 @@ and other extra keys to show.
The list of language tags (generally two letters) The list of language tags (generally two letters)
and locales (generally of the form `xx_XX`) and locales (generally of the form `xx_XX`)
can be found in this stackoverflow answer: https://stackoverflow.com/a/7989085 can be found in this [stackoverflow answer](https://stackoverflow.com/a/7989085)
### Translations ### Updating translations
Translations are always welcome ! The text used in the app is written in `res/values-<language_tag>/strings.xml`.
See for example: 1723288 (Latvian), baf867a (French). The list of language tags can be found in this
The app can be translated by writing `res/values-<language code>/strings.xml` [stackoverflow answer](https://stackoverflow.com/a/7989085)
(for example `values-fr`, `values-lv`), based on the default:
`res/values/strings.xml` (English). The first part before the `_` is used, for example,
`res/values-fr/strings.xml` for French,
`res/values-lv/strings.xml` for Latvian.
Commented-out lines indicate missing translations:
```xml
<!-- <string name="pref_layouts_add">Add an alternate layout</string> -->
```
Remove the `<!--` and `-->` parts and change the text.
### Adding a translation
The `res/values-<language_tag>/strings.xml` file must be created by copying the
default translation in `res/values/strings.xml`, which contain the structure of
the file and the English strings.
To check that `strings.xml` is formatted correctly, run To check that `strings.xml` is formatted correctly, run
`python sync_translations.py`. This will modify your files. `./gradlew syncTranslations`. This will modify your files.
The store description is found in `metadata/android/<locale>/`, The store description is found in `metadata/android/<locale>/`,
`short_description.txt` and `full_description.txt`. `short_description.txt` and `full_description.txt`.
The short description must not exceed 80 characters.
Translating changelogs is not useful. Translating changelogs is not useful.
The app name might be partially translated, the "unexpected" word should remain The app name might be partially translated, the "Unexpected" word should remain
untranslated. untranslated.
As translations need to be updated regularly, you can subscribe to this issue As translations need to be updated regularly, you can subscribe to this issue

139
Makefile
View File

@@ -1,139 +0,0 @@
# Configuration
PACKAGE_NAME = juloo.keyboard2
ANDROID_PLATFORM_VERSION = android-30
JAVA_VERSION = 1.7
SRC_DIR = srcs
RES_DIR = res
EXTRA_JARS =
# /
debug: _build/$(PACKAGE_NAME).debug.apk
release: _build/$(PACKAGE_NAME).apk
installd: _build/$(PACKAGE_NAME).debug.apk
adb install -r "$<"
clean:
rm -rf _build/*.dex _build/class _build/gen _build/*.apk _build/*.unsigned-apk \
_build/*.idsig _build/assets
rebuild_special_font: _build/special_font.ttf
cp "$<" srcs/special_font/result.ttf
sync_translations:
python sync_translations.py
check_layouts:
python check_layout.py $(wildcard res/xml/*.xml) > check_layout.output
gen_layouts:
python gen_layouts.py
# Will modify the source tree.
runtest: rebuild_special_font sync_translations check_layouts gen_layouts
.PHONY: release debug installd clean rebuild_special_font check_layouts \
sync_translations runtest gen_layouts
$(shell mkdir -p _build)
ifndef ANDROID_HOME
$(error ANDROID_HOME not set)
endif
ANDROID_BUILD_TOOLS = $(lastword $(sort $(wildcard $(ANDROID_HOME)/build-tools/*)))
ANDROID_PLATFORM = $(ANDROID_HOME)/platforms/$(ANDROID_PLATFORM_VERSION)
ifeq ($(shell [ -d "$(ANDROID_PLATFORM)" ] && echo ok),)
$(error Android platform not found. Want $(ANDROID_PLATFORM_VERSION), \
found $(notdir $(wildcard $(ANDROID_HOME)/platforms/*)))
endif
JAVAC_FLAGS = -source $(JAVA_VERSION) -target $(JAVA_VERSION) -encoding utf8
# Source files
MANIFEST_FILE = AndroidManifest.xml
JAVA_FILES = $(shell find $(SRC_DIR) -name '*.java')
RES_FILES = $(shell find $(RES_DIR) -type f)
# Debug signing
DEBUG_KEYSTORE = _build/debug.keystore
DEBUG_PASSWD = debug0
$(DEBUG_KEYSTORE):
echo y | keytool -genkeypair -dname "cn=d, ou=e, o=b, c=ug" \
-alias debug -keypass $(DEBUG_PASSWD) -keystore "$@" \
-keyalg rsa -storepass $(DEBUG_PASSWD) -validity 10000
_build/%.debug.apk: _build/%.debug.unsigned-apk $(DEBUG_KEYSTORE)
$(ANDROID_BUILD_TOOLS)/apksigner sign --in "$<" --out "$@" \
--ks $(DEBUG_KEYSTORE) --ks-key-alias debug --ks-pass "pass:$(DEBUG_PASSWD)"
# Debug apk
_build/$(PACKAGE_NAME).debug.unsigned-apk: AAPT_PACKAGE_FLAGS+=--rename-manifest-package $(PACKAGE_NAME).debug --product debug
# Release signing
# %-keystore.conf should declare KEYSTORE, KEYNAME and KEYSTOREPASS
# it is interpreted as a shell script
_build/%.apk: _build/%.unsigned-apk %-keystore.conf
eval `cat $(word 2,$^)` && \
$(ANDROID_BUILD_TOOLS)/apksigner sign --in "$<" --out "$@" \
--ks "$$KEYSTORE" --ks-key-alias "$$KEYNAME" --ks-pass "pass:$$KEYSTOREPASS"
# Package
_build/%.unsigned-apk: _build/%.unaligned-apk
$(ANDROID_BUILD_TOOLS)/zipalign -fp 4 "$<" "$@"
APK_EXTRA_FILES = classes.dex assets/special_font.ttf
_build/%.unaligned-apk: $(addprefix _build/,$(APK_EXTRA_FILES)) $(MANIFEST_FILE)
$(ANDROID_BUILD_TOOLS)/aapt package -f -M $(MANIFEST_FILE) -S $(RES_DIR) \
-I $(ANDROID_PLATFORM)/android.jar -F "$@" $(AAPT_PACKAGE_FLAGS)
cd $(@D) && $(ANDROID_BUILD_TOOLS)/aapt add $(@F) $(APK_EXTRA_FILES)
# Copy the special font file into _build because aapt requires relative paths
_build/assets/special_font.ttf: srcs/special_font/result.ttf
mkdir -p $(@D)
cp "$<" "$@"
# R.java
GEN_DIR = _build/gen
R_FILE = $(GEN_DIR)/$(subst .,/,$(PACKAGE_NAME))/R.java
$(R_FILE): $(RES_FILES) $(MANIFEST_FILE)
mkdir -p "$(@D)"
$(ANDROID_BUILD_TOOLS)/aapt package -f -m -S $(RES_DIR) -J $(GEN_DIR) \
-M $(MANIFEST_FILE) -I $(ANDROID_PLATFORM)/android.jar
# Compile java classes and build classes.dex
OBJ_DIR = _build/class
# A$B.class files are ignored
# CLASS_FILES = $(JAVA_FILES:$(SRC_DIR)/%.java=$(OBJ_DIR)/%.class) \
# $(R_FILE:$(GEN_DIR)/%.java=$(OBJ_DIR)/%.class)
_build/classes.dex: $(JAVA_FILES) $(R_FILE)
mkdir -p $(OBJ_DIR)
javac -d $(OBJ_DIR) $(JAVAC_FLAGS) \
-classpath $(ANDROID_PLATFORM)/android.jar:$(EXTRA_JARS) \
-sourcepath $(SRC_DIR):$(GEN_DIR) \
$^
$(ANDROID_BUILD_TOOLS)/d8 --output $(@D) $(OBJ_DIR)/*/*/* $(subst :, ,$(EXTRA_JARS))
# Font file
FONT_GLYPHS = $(wildcard srcs/special_font/*.svg)
_build/special_font.ttf: srcs/special_font/build.pe $(FONT_GLYPHS)
fontforge -lang=ff -script $< "$@" $(FONT_GLYPHS)

View File

@@ -9,9 +9,7 @@
Lightweight and privacy-conscious virtual keyboard for Android. Lightweight and privacy-conscious virtual keyboard for Android.
| <img src="/metadata/android/en-US/images/phoneScreenshots/1.png" alt="Screenshot-1" /> | <img src="/metadata/android/en-US/images/phoneScreenshots/2.png" alt="Screenshot-2"/> | <img src="/metadata/android/en-US/images/phoneScreenshots/3.png" alt="Screenshot-3"/> | https://github.com/Julow/Unexpected-Keyboard/assets/2310568/28f8f6fe-ac13-46f3-8c5e-d62443e16d0d
| --- | --- | --- |
| <img src="/metadata/android/en-US/images/phoneScreenshots/4.png" alt="Screenshot-4" /> | <img src="/metadata/android/en-US/images/phoneScreenshots/5.png" alt="Screenshot-5" /> | <img src="/metadata/android/en-US/images/phoneScreenshots/6.png" alt="Screenshot-6" /> |
The main feature is that you can type more characters by swiping the keys towards the corners. The main feature is that you can type more characters by swiping the keys towards the corners.
@@ -20,6 +18,13 @@ Now perfect for everyday use.
This application contains no ads, doesn't make any network requests and is Open Source. This application contains no ads, doesn't make any network requests and is Open Source.
| <img src="/metadata/android/en-US/images/phoneScreenshots/1.png" alt="Screenshot-1" /> | <img src="/metadata/android/en-US/images/phoneScreenshots/2.png" alt="Screenshot-2"/> | <img src="/metadata/android/en-US/images/phoneScreenshots/3.png" alt="Screenshot-3"/> |
| --- | --- | --- |
| <img src="/metadata/android/en-US/images/phoneScreenshots/4.png" alt="Screenshot-4" /> | <img src="/metadata/android/en-US/images/phoneScreenshots/5.png" alt="Screenshot-5" /> | <img src="/metadata/android/en-US/images/phoneScreenshots/6.png" alt="Screenshot-6" /> |
## Similar apps
* [Calculator++](https://github.com/Bubu/android-calculatorpp) - Calculator with a similar UX, swipe to corners for advanced math symbols and operators. Works up to Android 13 but maybe unmaintained.
## Contributing ## Contributing
For instructions on building the application, see For instructions on building the application, see

167
build.gradle Normal file
View File

@@ -0,0 +1,167 @@
plugins {
id 'com.android.application' version '8.1.1'
}
android {
namespace 'juloo.keyboard2'
compileSdk 33
defaultConfig {
applicationId "juloo.keyboard2"
minSdk 4
targetSdkVersion 33
versionCode 38
versionName "1.26.0"
}
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['srcs']
res.srcDirs = ['res', 'build/generated-resources']
assets.srcDirs = ['assets']
}
}
signingConfigs {
// Debug builds will always be signed. If no environment variables are set, a default
// keystore will be initialized by the task initDebugKeystore and used. This keystore
// can be uploaded to GitHub secrets by following instructions in CONTRIBUTING.md
// in order to always receive correctly signed debug APKs from the CI.
debug {
storeFile(System.env.DEBUG_KEYSTORE ? file(System.env.DEBUG_KEYSTORE) : file("debug.keystore"))
storePassword(System.env.DEBUG_KEYSTORE_PASSWORD ? "$System.env.DEBUG_KEYSTORE_PASSWORD" : "debug0")
keyAlias(System.env.DEBUG_KEY_ALIAS ? "$System.env.DEBUG_KEY_ALIAS" : "debug")
keyPassword(System.env.DEBUG_KEY_PASSWORD ? "$System.env.DEBUG_KEY_PASSWORD" : "debug0")
}
release {
if (System.env.RELEASE_KEYSTORE) {
storeFile file(System.env.RELEASE_KEYSTORE)
storePassword "$System.env.RELEASE_KEYSTORE_PASSWORD"
keyAlias "$System.env.RELEASE_KEY_ALIAS"
keyPassword "$System.env.RELEASE_KEY_PASSWORD"
}
}
}
buildTypes {
release {
minifyEnabled true
shrinkResources true
debuggable false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt')
resValue "string", "app_name", "@string/app_name_release"
signingConfig signingConfigs.release
}
debug {
minifyEnabled false
shrinkResources false
debuggable true
applicationIdSuffix ".debug"
resValue "string", "app_name", "@string/app_name_debug"
resValue "bool", "debug_logs", "true"
signingConfig signingConfigs.debug
}
}
// Name outputs after the application ID.
android.applicationVariants.all { variant ->
variant.outputs.all {
outputFileName = "${applicationId}.apk"
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
}
dependencies {
}
tasks.register('buildKeyboardFont') {
println "\nBuilding assets/special_font.ttf"
mkdir "$buildDir"
exec {
workingDir "$projectDir/srcs/special_font"
def svgFiles = workingDir.listFiles().findAll {
it.isFile() && it.name.endsWith(".svg")
}
commandLine("fontforge", "-lang=ff", "-script", "build.pe", "$buildDir/special_font.ttf", *svgFiles)
}
copy {
from "$buildDir/special_font.ttf"
into "assets"
}
}
tasks.withType(Test).configureEach {
dependsOn 'genLayoutsList'
dependsOn 'checkKeyboardLayouts'
dependsOn 'syncTranslations'
}
tasks.register('genLayoutsList') {
println "\nGenerating res/values/layouts.xml"
exec {
workingDir = projectDir
commandLine "python", "gen_layouts.py"
}
}
tasks.register('checkKeyboardLayouts') {
println "\nChecking layouts"
exec {
def layouts = new File(projectDir, "srcs/layouts").listFiles().findAll {
it.name.endsWith(".xml")
}
workingDir = projectDir
commandLine("python", "check_layout.py", *layouts)
standardOutput = new FileOutputStream("${projectDir}/check_layout.output")
}
}
tasks.register('syncTranslations') {
println "\nUpdating translations"
exec {
workingDir = projectDir
commandLine "python", "sync_translations.py"
}
}
tasks.named("preBuild") {
dependsOn += "initDebugKeystore"
dependsOn += "copyRawQwertyUS"
dependsOn += "copyLayoutDefinitions"
}
tasks.register('initDebugKeystore') {
if (!file("debug.keystore").exists()) {
println "Initializing default debug keystore"
exec {
// A shell script might be needed if this line requires input from the user
commandLine "keytool", "-genkeypair", "-dname", "cn=d, ou=e, o=b, c=ug", "-alias", "debug", "-keypass", "debug0", "-keystore", "debug.keystore", "-keyalg", "rsa", "-storepass", "debug0", "-validity", "10000"
}
}
}
// latn_qwerty_us is used as a raw resource by the custom layout option.
tasks.register('copyRawQwertyUS')
{
copy {
from "srcs/layouts/latn_qwerty_us.xml"
into "build/generated-resources/raw"
}
}
tasks.register('copyLayoutDefinitions')
{
copy {
from "srcs/layouts"
into "build/generated-resources/xml"
}
}

View File

@@ -1,116 +1,133 @@
# res/xml/arab_alt.xml # arab_alt
Layout includes some ASCII punctuation but not all, missing: !, ", ', +, -, /, :, ;, <, =, >, ?, [, \, ], _, |, ~ Layout includes some ASCII punctuation but not all, missing: !, ", ', +, -, /, :, ;, <, =, >, ?, [, \, ], _, |, ~
1 warnings Layout doesn't define some important keys, missing: f11_placeholder, f12_placeholder
# res/xml/arab_pc_ckb.xml 2 warnings
Layout includes some ASCII punctuation but not all, missing: ", %, ', +, ,, ., :, ;, <, =, >, ?, `, |, ~ # arab_hamvaj_tly
1 warnings Layout includes some ASCII punctuation but not all, missing: ", %, ', ,, /, ;, <, =, >, ?, [, \, ], _, `, {, |, }
# res/xml/arab_pc_ir.xml Layout doesn't define some important keys, missing: esc, f11_placeholder, f12_placeholder
Layout includes some ASCII punctuation but not all, missing: ", $, %, ', *, ,, /, ;, <, =, >, ?, [, \, ], ^, _, `, {, |, }, ~ 2 warnings
1 warnings # arab_pc
# res/xml/arab_pc.xml
Layout includes some ASCII punctuation but not all, missing: !, ', +, ;, ?, \, | Layout includes some ASCII punctuation but not all, missing: !, ', +, ;, ?, \, |
1 warnings 1 warnings
# res/xml/beng_national.xml # arab_pc_ckb
Layout includes some ASCII punctuation but not all, missing: ", %, ', +, ,, ., :, ;, <, =, >, ?, `, |, ~
1 warnings
# arab_pc_hindu
Layout includes some ASCII punctuation but not all, missing: !, ', +, ;, ?, \, |
1 warnings
# arab_pc_ir
Layout includes some ASCII punctuation but not all, missing: ", %, ', ,, /, ;, <, =, >, ?, [, \, ], `, {, |, }
1 warnings
# armenian_ph_am
Layout doesn't define some important keys, missing: f11_placeholder, f12_placeholder
1 warnings
# beng_national
Layout includes some ASCII punctuation but not all, missing: $ Layout includes some ASCII punctuation but not all, missing: $
Layout doesn't specify a script. Layout doesn't define some important keys, missing: f11_placeholder, f12_placeholder
2 warnings 2 warnings
# res/xml/beng_provat.xml # beng_provat
Layout includes some ASCII punctuation but not all, missing: $, &, *, ., /, <, >, [, \, ], `, {, |, } Layout includes some ASCII punctuation but not all, missing: $, &, *, ., /, <, >, [, \, ], `, {, |, }
Layout doesn't specify a script. Layout doesn't define some important keys, missing: f11_placeholder, f12_placeholder
2 warnings 2 warnings
Not a layout file: res/xml/bottom_row.xml # cyrl_jcuken_ru
# res/xml/cyrl_jcuken_ru.xml
0 warnings 0 warnings
# res/xml/cyrl_jcuken_uk.xml # cyrl_jcuken_uk
0 warnings 0 warnings
# res/xml/cyrl_yaverti.xml # cyrl_ueishsht
0 warnings
# cyrl_yaverti
Layout includes some ASCII punctuation but not all, missing: ~ Layout includes some ASCII punctuation but not all, missing: ~
1 warnings 1 warnings
# res/xml/deva_alt.xml # deva_alt
Layout includes some ASCII punctuation but not all, missing: #, $, %, &, ', (, ), *, +, ., /, :, <, =, >, @, [, \, ], ^, _, `, {, |, }, ~ Layout includes some ASCII punctuation but not all, missing: #, $, %, &, ', (, ), +, ., /, :, <, =, >, [, \, ], ^, _, `, {, |, }, ~
1 warnings Layout doesn't define some important keys, missing: esc, f11_placeholder, f12_placeholder, tab
# res/xml/deva_inscript.xml 2 warnings
# deva_inscript
Duplicate keys: ।
Layout includes some ASCII punctuation but not all, missing: ", $, ', ^, _, `, | Layout includes some ASCII punctuation but not all, missing: ", $, ', ^, _, `, |
1 warnings Layout doesn't define some important keys, missing: f11_placeholder, f12_placeholder
# res/xml/greekmath.xml
Layout includes some ASCII punctuation but not all, missing: !, ", #, $, %, &, ', (, ), *, +, ,, -, /, :, ;, <, >, ?, @, [, \, ], _, `, {, |, }, ~
Layout redefines the bottom row but some important keys are missing, missing: change_method, config, ctrl, switch_emoji, switch_second
Layout doesn't specify a script.
3 warnings 3 warnings
# res/xml/grek_qwerty.xml # grek_qwerty
Duplicate keys: ;
1 warnings
# hang_dubeolsik_kr
0 warnings 0 warnings
# res/xml/hang_dubeolsik_kr.xml # hebr_1_il
0 warnings
# res/xml/hebr_1_il.xml
Layout includes some ASCII punctuation but not all, missing: (, ), <, >, [, ], {, } Layout includes some ASCII punctuation but not all, missing: (, ), <, >, [, ], {, }
1 warnings 1 warnings
# res/xml/hebr_2_il.xml # hebr_2_il
Layout includes some ASCII punctuation but not all, missing: (, ), <, >, [, ], {, } Layout includes some ASCII punctuation but not all, missing: (, ), <, >, [, ], {, }
1 warnings 1 warnings
# res/xml/latn_azerty_fr.xml # latn_azerty_fr
0 warnings 0 warnings
# res/xml/latn_bone.xml # latn_bepo_fr
Layout doesn't define some important keys, missing: f11_placeholder, f12_placeholder
1 warnings
# latn_bone
Layout includes some ASCII punctuation but not all, missing: $ Layout includes some ASCII punctuation but not all, missing: $
Layout redefines the bottom row but some important keys are missing, missing: cursor_left, cursor_right, loc end, loc home, loc page_down, loc page_up, loc switch_greekmath, loc voice_typing, switch_backward
2 warnings
# latn_colemak
Some keys contain whitespaces, unexpected: ́
1 warnings 1 warnings
# res/xml/latn_colemak.xml # latn_dvorak
0 warnings 0 warnings
# res/xml/latn_dvorak.xml # latn_neo2
0 warnings Layout redefines the bottom row but some important keys are missing, missing: loc end, loc home, loc page_down, loc page_up
# res/xml/latn_neo2.xml
0 warnings
# res/xml/latn_qwerty_br.xml
0 warnings
# res/xml/latn_qwerty_es.xml
0 warnings
# res/xml/latn_qwerty_hu.xml
0 warnings
# res/xml/latn_qwerty_lv.xml
0 warnings
# res/xml/latn_qwerty_no.xml
0 warnings
# res/xml/latn_qwerty_pl.xml
0 warnings
# res/xml/latn_qwerty_ro.xml
0 warnings
# res/xml/latn_qwerty_se.xml
0 warnings
# res/xml/latn_qwerty_tr.xml
0 warnings
# res/xml/latn_qwerty_us.xml
0 warnings
# res/xml/latn_qwerty_vi.xml
Layout includes some ASCII punctuation but not all, missing: \
1 warnings 1 warnings
# res/xml/latn_qwertz_cz_multifunctional.xml # latn_qwerty_br
0 warnings
# latn_qwerty_cz
Layout doesn't define some important keys, missing: f11_placeholder, f12_placeholder
1 warnings
# latn_qwerty_es
0 warnings
# latn_qwerty_hu
0 warnings
# latn_qwerty_lv
0 warnings
# latn_qwerty_no
0 warnings
# latn_qwerty_pl
0 warnings
# latn_qwerty_ro
0 warnings
# latn_qwerty_se
Duplicate keys: !, ', ,, -, ., ?
1 warnings
# latn_qwerty_tly
Duplicate keys: a, c, g, j, q
Layout doesn't define some important keys, missing: esc, f11_placeholder, f12_placeholder, tab
2 warnings
# latn_qwerty_tr
Layout doesn't define some important keys, missing: f11_placeholder, f12_placeholder
1 warnings
# latn_qwerty_us
0 warnings
# latn_qwerty_vi
0 warnings
# latn_qwertz
0 warnings
# latn_qwertz_cz
Layout doesn't define some important keys, missing: f11_placeholder, f12_placeholder
1 warnings
# latn_qwertz_cz_multifunctional
Layout includes some ASCII punctuation but not all, missing: ` Layout includes some ASCII punctuation but not all, missing: `
1 warnings Layout doesn't define some important keys, missing: f11_placeholder, f12_placeholder
# res/xml/latn_qwertz_cz.xml 2 warnings
# latn_qwertz_de
0 warnings 0 warnings
# res/xml/latn_qwertz_de.xml # latn_qwertz_fr_ch
0 warnings 0 warnings
# res/xml/latn_qwertz_hu.xml # latn_qwertz_hu
0 warnings 0 warnings
# res/xml/latn_qwertz_sk.xml # latn_qwertz_sk
Layout includes some ASCII punctuation but not all, missing: \, ` Layout includes some ASCII punctuation but not all, missing: `
1 warnings Layout doesn't define some important keys, missing: f11_placeholder, f12_placeholder
# res/xml/latn_qwertz.xml 2 warnings
0 warnings # urdu_phonetic_ur
Not a layout file: res/xml/method.xml Duplicate keys:
Not a layout file: res/xml/number_row.xml Layout includes some ASCII punctuation but not all, missing: <, >, ?, `, |, ~
# res/xml/numeric.xml Layout doesn't define some important keys, missing: f11_placeholder, f12_placeholder
Layout includes some ASCII punctuation but not all, missing: &, ?, @, ` Some keys contain whitespaces, unexpected:
Layout redefines the bottom row but some important keys are missing, missing: change_method, config, switch_emoji, switch_numeric, switch_second
Layout doesn't specify a script.
3 warnings
# res/xml/numpad.xml
Layout includes some ASCII punctuation but not all, missing: !, ", #, $, %, &, ', (, ), ,, :, ;, <, >, ?, @, [, \, ], ^, _, `, {, |, }, ~
Layout doesn't define some important keys, missing: backspace, delete
Layout redefines the bottom row but some important keys are missing, missing: action, change_method, config, ctrl, down, enter, fn, left, right, space, switch_emoji, switch_numeric, switch_second, up
Layout doesn't specify a script.
4 warnings 4 warnings
# res/xml/pin.xml
Layout includes some ASCII punctuation but not all, missing: !, ", $, %, &, ', ;, <, =, >, ?, @, [, \, ], ^, _, `, {, |, }, ~
Layout redefines the bottom row but some important keys are missing, missing: change_method, config, ctrl, fn, switch_emoji, switch_second
Layout doesn't specify a script.
3 warnings
Not a layout file: res/xml/settings.xml

View File

@@ -1,8 +1,13 @@
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
import sys import sys, os
warning_count = 0 warning_count = 0
KNOWN_NOT_LAYOUT = set([
"number_row", "numpad", "pin",
"bottom_row", "settings", "method",
"greekmath", "numeric", "emoji_bottom_row" ])
def warn(msg): def warn(msg):
global warning_count global warning_count
print(msg) print(msg)
@@ -29,30 +34,56 @@ def unexpected_keys(keys, symbols, msg):
if len(unexpected) > 0: if len(unexpected) > 0:
warn("%s, unexpected: %s" % (msg, key_list_str(unexpected))) warn("%s, unexpected: %s" % (msg, key_list_str(unexpected)))
# Write to [keys] and [dup].
def parse_row_from_et(row, keys, dup):
for key in row:
for attr in key.keys():
if attr.startswith("key"):
k = key.get(attr).removeprefix("\\")
if k in keys: dup.add(k)
keys.add(k)
def parse_layout(fname): def parse_layout(fname):
keys = set() keys = set()
dup = set()
root = ET.parse(fname).getroot() root = ET.parse(fname).getroot()
if root.tag != "keyboard": if root.tag != "keyboard":
return None return None
for row in root: for row in root:
for key in row: parse_row_from_et(row, keys, dup)
for attr in key.keys(): return root, keys, dup
keys.add(key.get(attr).removeprefix("\\"))
return root, keys def parse_row(fname):
keys = set()
dup = set()
root = ET.parse(fname).getroot()
if root.tag != "row":
return None
parse_row_from_et(root, keys, dup)
return root, keys, dup
def check_layout(layout): def check_layout(layout):
root, keys = layout root, keys, dup = layout
if len(dup) > 0: warn("Duplicate keys: " + key_list_str(dup))
missing_some_of(keys, "~!@#$%^&*(){}`[]=\\-_;:/.,?<>'\"+|", "ASCII punctuation") missing_some_of(keys, "~!@#$%^&*(){}`[]=\\-_;:/.,?<>'\"+|", "ASCII punctuation")
missing_some_of(keys, "0123456789", "digits") missing_some_of(keys, "0123456789", "digits")
missing_some_of(keys, ["f11_placeholder", "f12_placeholder"]) missing_required(keys,
missing_some_of(keys, ["esc", "tab"]) ["esc", "tab", "backspace", "delete",
missing_required(keys, ["backspace", "delete"], "Layout doesn't define some important keys") "f11_placeholder", "f12_placeholder"],
"Layout doesn't define some important keys")
unexpected_keys(keys,
["copy", "paste", "cut", "selectAll", "shareText",
"pasteAsPlainText", "undo", "redo" ],
"Layout contains editing keys")
unexpected_keys(keys,
[ "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9",
"f10", "f11", "f12" ],
"Layout contains function keys")
unexpected_keys(keys, [""], "Layout contains empty strings")
unexpected_keys(keys, ["loc"], "Special keyword cannot be a symbol")
unexpected_keys(keys, filter(lambda k: k.strip()!=k, keys), "Some keys contain whitespaces")
bottom_row_keys = [ _, bottom_row_keys, _ = parse_row("res/xml/bottom_row.xml")
"ctrl", "fn", "switch_numeric", "change_method", "switch_emoji",
"config", "switch_second", "enter", "action", "left", "up", "right",
"down", "space"
]
if root.get("bottom_row") == "false": if root.get("bottom_row") == "false":
missing_required(keys, bottom_row_keys, missing_required(keys, bottom_row_keys,
@@ -64,12 +95,15 @@ def check_layout(layout):
if root.get("script") == None: if root.get("script") == None:
warn("Layout doesn't specify a script.") warn("Layout doesn't specify a script.")
for fname in sys.argv[1:]: for fname in sorted(sys.argv[1:]):
layout_id, _ = os.path.splitext(os.path.basename(fname))
if layout_id in KNOWN_NOT_LAYOUT:
continue
layout = parse_layout(fname) layout = parse_layout(fname)
if layout == None: if layout == None:
print("Not a layout file: %s" % fname) print("Not a layout file: %s" % layout_id)
else: else:
print("# %s" % fname) print("# %s" % layout_id)
warning_count = 0 warning_count = 0
check_layout(layout) check_layout(layout)
print("%d warnings" % warning_count) print("%d warnings" % warning_count)

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# Generates the list of layouts in res/values/layouts.xml from the layout files # Generates the list of layouts in res/values/layouts.xml from the layout files
# in res/xml. Every layouts must have a 'name' attribute to be listed. # in srcs/layouts. Every layouts must have a 'name' attribute to be listed.
import itertools as it import itertools as it
import sys, os, glob import sys, os, glob
@@ -11,11 +11,6 @@ import xml.etree.ElementTree as XML
# are sorted alphabetically. # are sorted alphabetically.
FIRST_LAYOUTS = [ "latn_qwerty_us", "latn_colemak", "latn_dvorak" ] FIRST_LAYOUTS = [ "latn_qwerty_us", "latn_colemak", "latn_dvorak" ]
# File names that are known not to be layouts. Avoid warning about them.
KNOWN_NOT_LAYOUT = set([
"number_row", "numpad", "pin", "bottom_row", "settings", "method",
"greekmath", "numeric" ])
# Read a layout from a file. Returns [None] if [fname] is not a layout. # Read a layout from a file. Returns [None] if [fname] is not a layout.
def read_layout(fname): def read_layout(fname):
root = XML.parse(fname).getroot() root = XML.parse(fname).getroot()
@@ -28,9 +23,7 @@ def read_layouts(files):
for layout_file in files: for layout_file in files:
layout_id, _ = os.path.splitext(os.path.basename(layout_file)) layout_id, _ = os.path.splitext(os.path.basename(layout_file))
layout = read_layout(layout_file) layout = read_layout(layout_file)
if layout_id in KNOWN_NOT_LAYOUT: if layout == None:
continue
elif layout == None:
print("Not a layout file: %s" % layout_file) print("Not a layout file: %s" % layout_file)
elif layout["name"] == None: elif layout["name"] == None:
print("Layout doesn't have a name: %s" % layout_id) print("Layout doesn't have a name: %s" % layout_id)
@@ -54,10 +47,10 @@ def generate_arrays(out, layouts):
item.text = s item.text = s
elem.append(item) elem.append(item)
return elem return elem
none_item = [ ("none", "None") ] system_item = [ ("system", "@string/pref_layout_e_system") ]
custom_item = [ ("custom", "@string/pref_layout_e_custom") ] custom_item = [ ("custom", "@string/pref_layout_e_custom") ]
values_items, entries_items = zip(*(none_item + layouts + custom_item)) # unzip values_items, entries_items = zip(*(system_item + layouts + custom_item)) # unzip
ids_items = map(lambda s: "@xml/%s" % s if s not in ["none", "custom"] else "-1", values_items) ids_items = map(lambda s: "@xml/%s" % s if s not in ["system", "custom"] else "-1", values_items)
root = XML.Element("resources") root = XML.Element("resources")
root.append(XML.Comment(text="DO NOT EDIT. This file is generated, see gen_layouts.py.")) root.append(XML.Comment(text="DO NOT EDIT. This file is generated, see gen_layouts.py."))
root.append(mk_array("string-array", "pref_layout_values", values_items)) root.append(mk_array("string-array", "pref_layout_values", values_items))
@@ -66,6 +59,6 @@ def generate_arrays(out, layouts):
XML.indent(root) XML.indent(root)
XML.ElementTree(element=root).write(out, encoding="unicode", xml_declaration=True) XML.ElementTree(element=root).write(out, encoding="unicode", xml_declaration=True)
layouts = sort_layouts(read_layouts(glob.glob("res/xml/*.xml"))) layouts = sort_layouts(read_layouts(glob.glob("srcs/layouts/*.xml")))
with open("res/values/layouts.xml", "w") as out: with open("res/values/layouts.xml", "w") as out:
generate_arrays(out, layouts) generate_arrays(out, layouts)

3
gradle.properties Normal file
View File

@@ -0,0 +1,3 @@
org.gradle.jvmargs=-Dfile.encoding=UTF-8
android.useAndroidX=false
android.nonTransitiveRClass=true

BIN
gradle/wrapper/gradle-wrapper.jar vendored Normal file

Binary file not shown.

View File

@@ -0,0 +1,6 @@
#Mon Aug 21 18:13:41 CEST 2023
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

185
gradlew vendored Executable file
View File

@@ -0,0 +1,185 @@
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=`expr $i + 1`
done
case $i in
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=`save "$@"`
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
exec "$JAVACMD" "$@"

89
gradlew.bat vendored Normal file
View File

@@ -0,0 +1,89 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

View File

@@ -0,0 +1,9 @@
Allow selecting any number of standard and custom layouts.
Allow adding custom keys to the keyboard.
Changed behavior of auto-added keys (often dead-keys).
New layouts.
Improved layouts and language support.
Improved the space bar slider, and many more.
Updated translations.
Thanks to the contributors: @ChasmSolacer, @ElucGeek, @GoRaN909, @RZHSSNZDH, @Shareef101, @Validbit, @eandersons, @nitsvga, @polyctena, @sdrapha, @syskill

View File

@@ -0,0 +1,8 @@
Improved custom layout option.
Allow selecting voice typing app with a long press.
The numpad can work with other numeral systems.
New and updated layouts.
New themes.
Many small improvements.
Thanks to the contributors: @pharook, @syskill, @ojas-bhagavath, @lrvideckis, @lyubomirv, @matthiakl, @deftkHD, @V6lhost, @RZHSSNZDH, @RetrogisusDEV, @rafasaurus, @krtsgnr7230, @eandersons, @ChasmSolacer, @Validbit, @polyctena

View File

@@ -0,0 +1,7 @@
The custom vibration setting is back.
Allow to hide the keyboard switching key.
Fixed modifier keys in some development apps.
Updated translations.
Bug fixes and general improvements.
Many thanks to the contributors: @abb128, @marciozomb13, @RetrogisusDEV, @Sestowner, @vedamanavi, @krtsgnr7230

View File

@@ -0,0 +1 @@
https://www.youtube.com/watch?v=rwGvWesPFX8

View File

@@ -0,0 +1,6 @@
La característica principal es que hay acceso a más caractéres deslizando hacia las esquinas de las teclas.
Esta aplicación fue originalmente diseñada para programadores que usaran Termux.
Ahora es perfecta para uso cotidiano.
La misma no contiene ningún anuncio/publicidad, no realiza peticiones de red y es de Fuente Abierta.

View File

@@ -1 +1 @@
Un teclado virtual ligero para desarrolladores. Un teclado virtual ligero para Android consciente de su privacidad.

View File

@@ -1 +1 @@
Легкая виртуальная клавиатура для пользователей, заботящихся о своей конфиденциальности. Легкая клавиатура для пользователей, заботящихся о конфиденциальности.

View File

@@ -0,0 +1,6 @@
Bu uygulama özünde tuşların kenarlarından kaydırarak daha fazla karakter yazabilmek amacıyla geliştirildi.
Bu uygulama aslında Termux kullanıcıları için geliştirildi.
Artık gündelik kullanım için de uygun.
Bu uygulama açık kaynaklıdır. Reklam içermez ve internete bağlanmaz.

View File

@@ -0,0 +1 @@
Android için hafif ve güvenlik odaklı bir sanal klavye uygulaması.

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#ff101010"/>
</shape>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="1100.0dip" android:width="1100.0dip" android:viewportWidth="1100.0" android:viewportHeight="1100.0">
<path android:fillColor="#fc2a2a2a" android:pathData="M549.19,211.58L838.49,211.58A66.72 66.72 0 0 1 905.21,278.30L905.21,731.23A66.72 66.72 0 0 1 838.49,797.95L549.19,797.95A66.72 66.72 0 0 1 482.47,731.23L482.47,278.30A66.72 66.72 0 0 1 549.19,211.58zM38.60,272.97L38.60,725.90A66.72 66.72 0 0 0 105.32,792.62L394.62,792.62A66.72 66.72 0 0 0 461.34,725.90L461.34,272.97A66.72 66.72 0 0 0 394.62,206.25L105.32,206.25A66.72 66.72 0 0 0 38.60,272.97z" android:strokeLineCap="round" android:strokeLineJoin="round" android:fillType="nonZero"/>
<path android:fillColor="#ffffffff" android:pathData="M662.14,510.10L662.14,648.69" android:strokeColor="#ffffffff" android:strokeWidth="20.380417" android:strokeLineCap="square" android:strokeLineJoin="miter" android:fillType="nonZero"/>
<path android:fillColor="#00ffffff" android:pathData="M662.14,531.42C778.39,456.79,778.39,659.35,662.14,595.39" android:strokeColor="#ffffffff" android:strokeWidth="20.380417" android:strokeLineCap="round" android:strokeLineJoin="miter" android:fillType="nonZero"/>
<path android:fillColor="#00ffffff" android:pathData="M852.37,264.89C869.88,264.89,884.07,286.37,884.07,312.86C884.07,339.36,869.88,360.84,852.37,360.84C834.86,360.84,820.66,339.36,820.66,312.86C820.66,286.37,834.86,264.89,852.37,264.89z" android:strokeColor="#ffffffff" android:strokeWidth="20.380417" android:strokeLineCap="round" android:strokeLineJoin="miter" android:fillType="nonZero"/>
<path android:fillColor="#00ffffff" android:pathData="M514.18,659.35Q545.88,712.66,514.18,776.63" android:strokeColor="#ffffffff" android:strokeWidth="20.380417" android:strokeLineCap="round" android:strokeLineJoin="miter" android:fillType="nonZero"/>
<path android:fillColor="#00ffffff" android:pathData="M254.75,520.69C281.29,520.69,302.81,542.19,302.81,568.70C302.81,595.21,281.29,616.71,254.75,616.71C228.21,616.71,206.69,595.21,206.69,568.70C206.69,542.19,228.21,520.69,254.75,520.69z" android:strokeColor="#fffdfdfd" android:strokeWidth="20.380417" android:strokeLineCap="round" android:strokeLineJoin="miter" android:fillType="nonZero"/>
<path android:fillColor="#00ffffff" android:pathData="M403.36,265.80C417.87,265.80,429.63,277.53,429.63,292.00C429.63,306.46,417.87,318.19,403.36,318.19C388.86,318.19,377.09,306.46,377.09,292.00C377.09,277.53,388.86,265.80,403.36,265.80z" android:strokeColor="#ffffffff" android:strokeWidth="20.380417" android:strokeLineCap="round" android:strokeLineJoin="miter" android:fillType="nonZero"/>
<path android:fillColor="#fc2a2a2a" android:pathData="M337.82,845.92L627.12,845.92A66.72 66.72 0 0 1 693.84,912.64L693.84,1365.58A66.72 66.72 0 0 1 627.12,1432.29L337.82,1432.29A66.72 66.72 0 0 1 271.11,1365.58L271.11,912.64A66.72 66.72 0 0 1 337.82,845.92zM-183.33,901.98L-183.33,1354.91A66.72 66.72 0 0 0 -116.62,1421.63L172.69,1421.63A66.72 66.72 0 0 0 239.40,1354.91L239.40,901.98A66.72 66.72 0 0 0 172.69,835.26L-116.62,835.26A66.72 66.72 0 0 0 -183.33,901.98zM-183.33,901.98L-183.33,1354.91A66.72 66.72 0 0 0 -116.62,1421.63L172.69,1421.63A66.72 66.72 0 0 0 239.40,1354.91L239.40,901.98A66.72 66.72 0 0 0 172.69,835.26L-116.62,835.26A66.72 66.72 0 0 0 -183.33,901.98z" android:strokeLineCap="round" android:strokeLineJoin="round" android:fillType="nonZero"/>
<path android:fillColor="#00ffffff" android:pathData="M397.93,360.84L429.63,296.87" android:strokeColor="#ffffffff" android:strokeWidth="20.380417" android:strokeLineCap="round" android:strokeLineJoin="round" android:fillType="nonZero"/>
<path android:fillColor="#00ffffff" android:pathData="M651.57,883.24L651.57,968.53" android:strokeColor="#ffffffff" android:strokeWidth="20.380417" android:strokeLineCap="round" android:strokeLineJoin="round" android:fillType="nonZero"/>
<path android:fillColor="#00ffffff" android:pathData="M197.13,883.24Q207.70,883.24,207.70,893.90L207.70,936.54Q218.26,947.21,207.70,957.87L207.70,968.53" android:strokeColor="#ffffffff" android:strokeWidth="20.380417" android:strokeLineCap="round" android:strokeLineJoin="round" android:fillType="nonZero"/>
</vector>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content">
<EditText android:id="@+id/text" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_margin="10dp"/>
</LinearLayout>

View File

@@ -3,9 +3,6 @@
<juloo.keyboard2.EmojiGroupButtonsBar android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content"/> <juloo.keyboard2.EmojiGroupButtonsBar android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content"/>
<juloo.keyboard2.EmojiGridView android:id="@+id/emoji_grid" android:layout_width="fill_parent" android:layout_height="@dimen/emoji_grid_height" android:orientation="vertical" android:numColumns="auto_fit" android:columnWidth="45sp" android:background="?attr/colorKeyboard"/> <juloo.keyboard2.EmojiGridView android:id="@+id/emoji_grid" android:layout_width="fill_parent" android:layout_height="@dimen/emoji_grid_height" android:orientation="vertical" android:numColumns="auto_fit" android:columnWidth="45sp" android:background="?attr/colorKeyboard"/>
<LinearLayout android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content"> <LinearLayout android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content">
<juloo.keyboard2.EmojiKeyButton style="@style/emojiKeyButton" key="switch_back_emoji"/> <juloo.keyboard2.Keyboard2View layout="@xml/emoji_bottom_row" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="?attr/emoji_key_bg"/>
<juloo.keyboard2.EmojiKeyButton style="@style/emojiKeyButton" android:layout_weight="4" key="space"/>
<juloo.keyboard2.EmojiKeyButton style="@style/emojiKeyButton" key="backspace"/>
<juloo.keyboard2.EmojiKeyButton style="@style/emojiKeyButton" key="enter"/>
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>

View File

@@ -1,8 +1,13 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:fillViewport="true">
<LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical">
<TextView style="@style/paragraph" android:text="@string/launcher_description"/> <TextView style="@style/paragraph" android:text="@string/launcher_description"/>
<Button style="@style/paragraph" android:text="@string/launcher_button_imesettings" android:onClick="launch_imesettings" android:layout_width="wrap_content"/> <Button style="@style/paragraph" android:text="@string/launcher_button_imesettings" android:onClick="launch_imesettings" android:layout_width="wrap_content"/>
<TextView style="@style/paragraph" android:text="@string/launcher_sourcecode" android:autoLink="web"/> <Button style="@style/paragraph" android:text="@string/launcher_button_imepicker" android:onClick="launch_imepicker" android:layout_width="wrap_content"/>
<VideoView android:id="@+id/launcher_intro_video" android:layout_width="240dp" android:layout_height="wrap_content" android:layout_gravity="center"/>
<TextView android:id="@+id/launcher_tryhere_text" style="@style/paragraph" android:text="@string/launcher_tryhere"/> <TextView android:id="@+id/launcher_tryhere_text" style="@style/paragraph" android:text="@string/launcher_tryhere"/>
<EditText android:id="@+id/launcher_tryhere_area" style="@style/paragraph" android:inputType="text"/> <EditText android:id="@+id/launcher_tryhere_area" style="@style/paragraph" android:inputType="text"/>
<TextView style="@style/paragraph" android:text="@string/launcher_sourcecode"/>
<TextView style="@style/paragraph" android:text="https://github.com/Julow/Unexpected-Keyboard" android:autoLink="web" android:linksClickable="true"/>
</LinearLayout> </LinearLayout>
</ScrollView>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center" android:minHeight="?android:attr/listPreferredItemHeightSmall">
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/pref_layouts_add" android:textAppearance="?android:attr/textAppearanceListItemSmall"/>
</LinearLayout>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center">
<View android:layout_width="@dimen/pref_button_size" android:layout_height="@dimen/pref_button_size" android:background="@android:drawable/ic_menu_add"/>
</LinearLayout>

View File

@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center">
</LinearLayout>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal">
<Button android:id="@+id/pref_listgroup_remove_btn" android:layout_width="@dimen/pref_button_size" android:layout_height="@dimen/pref_button_size" android:layout_gravity="center" android:background="@android:drawable/ic_menu_close_clear_cancel"/>
</LinearLayout>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon>

View File

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 7.7 KiB

BIN
res/raw/intro_video.mp4 Normal file

Binary file not shown.

View File

@@ -1,48 +1,51 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="app_name" product="debug">Klávesnice Unexpected (pro ladění)</string> <string name="app_name_release">Klávesnice Unexpected</string>
<string name="app_name" product="default">Klávesnice Unexpected</string> <string name="app_name_debug">Klávesnice Unexpected (pro ladění)</string>
<string name="settings_activity_label">Nastavení Klávesnice Unexpected</string> <string name="settings_activity_label">Nastavení Klávesnice Unexpected</string>
<!-- <string name="pref_portrait">In portrait mode</string> --> <string name="pref_portrait">V režimu na výšku</string>
<!-- <string name="pref_landscape">In landscape mode</string> --> <string name="pref_landscape">V režimu na šířku</string>
<string name="pref_category_layout">Rozvržení</string> <string name="pref_category_layout">Rozvržení</string>
<!-- <string name="pref_label_brightness">Adjust label brightness</string> --> <string name="pref_label_brightness">Upravit jas nápisu</string>
<!-- <string name="pref_keyboard_opacity">Adjust keyboard background opacity</string> --> <string name="pref_keyboard_opacity">Upravit průhlednost pozadí klávesnice</string>
<!-- <string name="pref_key_opacity">Adjust key opacity</string> --> <string name="pref_key_opacity">Upravit průhlednost kláves</string>
<!-- <string name="pref_key_activated_opacity">Adjust pressed key opacity</string> --> <string name="pref_key_activated_opacity">Upravit průhlednost stisknutých kláves</string>
<string name="pref_layout_title">Změnit rozvržení klávesnice</string> <string name="pref_layout_e_system">Dle nastavení systému</string>
<string name="pref_layout_e_system">V nastavení systému</string> <string name="pref_layout_e_custom">Vlastní rozvržení</string>
<!-- <string name="pref_layout_e_custom">Custom layout</string> --> <string name="pref_layouts_add">Přidat alternativní rozložení</string>
<string name="pref_accents_title">(Univerzální) Diakritická znaménka</string> <string name="pref_layouts_item">Rozložení %1$d: %2$s</string>
<string name="pref_accents_e_all_installed">Zobrazovat znaménka pro všechny instalované systémové jazyky</string> <string name="pref_layouts_remove_custom">Odebrat rozložení</string>
<string name="pref_accents_e_selected">Zobrazovat znaménka pouze pro současně zvolený jazyk</string> <string name="pref_custom_layout_title">Vlastní rozložení</string>
<string name="pref_accents_e_none">Skrýt (univerzální) diakritická znaménka</string> <string name="pref_show_numpad_title">Zobrazit NumPad</string>
<!-- <string name="pref_show_numpad_title">Show NumPad</string> --> <string name="pref_show_numpad_never">Nikdy</string>
<!-- <string name="pref_show_numpad_never">Never</string> --> <string name="pref_show_numpad_landscape">Pouze v režimu na šířku</string>
<!-- <string name="pref_show_numpad_landscape">Only in landscape mode</string> --> <string name="pref_show_numpad_always">Vždy</string>
<!-- <string name="pref_show_numpad_always">Always</string> --> <string name="pref_number_row_title">Zobrazit řádek s čísly</string>
<!-- <string name="pref_number_row_title">Show number row</string> --> <string name="pref_number_row_summary">Přidá řádek s čísly nad klávesnici, pokud je NumPad skrytý</string>
<!-- <string name="pref_number_row_summary">Add a number row at the top of the keyboard when the numpad is hidden</string> --> <string name="pref_numpad_layout">Rozložení NumPadu</string>
<!-- <string name="pref_numpad_layout">NumPad layout</string> --> <string name="pref_numpad_layout_e_high_first">Vyšší číslice jako první (horní řádek 789)</string>
<!-- <string name="pref_numpad_layout_e_high_first">High digits first</string> --> <string name="pref_numpad_layout_e_low_first">Nižší číslice jako první (horní řádek 123)</string>
<!-- <string name="pref_numpad_layout_e_low_first">Low digits first</string> --> <string name="pref_extra_keys_title">Přidat klávesy do klávesnice</string>
<!-- <string name="pref_extra_keys_title">Add keys to the keyboard</string> --> <string name="pref_extra_keys_custom">Přidat vlastní klávesy</string>
<!-- <string name="pref_second_layout_title">Secondary layout</string> --> <string name="pref_extra_keys_internal">Výbrané klávesy k přidaní do klávesnice</string>
<string name="pref_second_layout_title">Vedlejší rozvržení</string>
<string name="pref_second_layout_none">Žádné</string> <string name="pref_second_layout_none">Žádné</string>
<string name="pref_category_typing">Psaní</string> <string name="pref_category_typing">Psaní</string>
<string name="pref_swipe_dist_title">Vzdálenost posunutí prstem</string> <string name="pref_swipe_dist_title">Vzdálenost posunutí prstem</string>
<string name="pref_swipe_dist_summary">Jak daleko je třeba posunout prst pro napsaní znaku/diakritiky v rozích klávey (%s)</string> <string name="pref_swipe_dist_summary">Jak daleko je třeba posunout prst pro zadání znaku/znaménka v rohu klávey (%s)</string>
<string name="pref_long_timeout_title">Časová prodleva opakování znaků</string> <string name="pref_long_timeout_title">Časová prodleva opakování znaků</string>
<string name="pref_long_interval_title">Interval opakování znaků</string> <string name="pref_long_interval_title">Interval opakování znaků</string>
<string name="pref_lock_double_tap_title">Dvojklik pro aktivaci caps lock(u)</string> <string name="pref_lock_double_tap_title">Dvojklik pro aktivaci Capslock(u)</string>
<string name="pref_lock_double_tap_summary">Dvojklik namísto držení modifikačních kláves po nějakou dobu</string> <string name="pref_lock_double_tap_summary">Umožňuje zamknout Shift dvojklikem, namísto podržení</string>
<!-- <string name="pref_category_behavior">Behavior</string> --> <string name="pref_category_behavior">Chování</string>
<string name="pref_autocapitalisation_title">Automatická kapitalizace</string> <string name="pref_autocapitalisation_title">Automatická kapitalizace</string>
<string name="pref_autocapitalisation_summary">Stiskne Shift na začátku věty</string> <string name="pref_autocapitalisation_summary">Stiskne Shift na začátku věty</string>
<!-- <string name="pref_switch_input_immediate_title">Switch to the last used keyboard</string> --> <string name="pref_switch_input_immediate_title">Přepnout na posledně užívanou klávesnici</string>
<!-- <string name="pref_switch_input_immediate_summary">Behavior of the keyboard-switching key</string> --> <string name="pref_switch_input_immediate_summary">Jak bude klávesa pro přepnutí klávesnice reagovat</string>
<string name="pref_vibrate_title">Vibrace</string> <!-- <string name="pref_vibrate_custom">Custom vibration</string> -->
<string name="pref_vibrate_summary">Zapnout/Vypnout vibrace při stisku klávesy</string> <!-- <string name="pref_vibrate_duration_title">Vibration intensity</string> -->
<string name="pref_pin_entry_enabled_title">Rozvržení zadávání PIN kódu</string>
<string name="pref_pin_entry_enabled_summary">Automaticky při psaní čísel, datumů a telefonních čísel</string>
<string name="pref_category_style">Styl</string> <string name="pref_category_style">Styl</string>
<string name="pref_margin_bottom_title">Spodní odsazení</string> <string name="pref_margin_bottom_title">Spodní odsazení</string>
<string name="pref_keyboard_height_title">Výška klávesnice</string> <string name="pref_keyboard_height_title">Výška klávesnice</string>
@@ -54,9 +57,11 @@
<string name="pref_theme_e_dark">Tmavý</string> <string name="pref_theme_e_dark">Tmavý</string>
<string name="pref_theme_e_light">Světlý</string> <string name="pref_theme_e_light">Světlý</string>
<string name="pref_theme_e_black">Černý</string> <string name="pref_theme_e_black">Černý</string>
<!-- <string name="pref_theme_e_altblack">Alternative Black</string> --> <string name="pref_theme_e_altblack">Černý (alternativní)</string>
<!-- <string name="pref_theme_e_white">White</string> --> <string name="pref_theme_e_white">Bílý</string>
<!-- <string name="pref_theme_e_epaper">ePaper</string> --> <string name="pref_theme_e_epaper">ePapír</string>
<string name="pref_theme_e_desert">Poušťě</string>
<string name="pref_theme_e_jungle">Džungle</string>
<string name="pref_swipe_dist_e_very_short">Velmi krátká</string> <string name="pref_swipe_dist_e_very_short">Velmi krátká</string>
<string name="pref_swipe_dist_e_short">Krátká</string> <string name="pref_swipe_dist_e_short">Krátká</string>
<string name="pref_swipe_dist_e_default">Běžná</string> <string name="pref_swipe_dist_e_default">Běžná</string>
@@ -64,22 +69,36 @@
<string name="pref_swipe_dist_e_very_far">Velmi dlouhá</string> <string name="pref_swipe_dist_e_very_far">Velmi dlouhá</string>
<string name="pref_key_horizontal_space">Horizontální mezery mezi klávesami</string> <string name="pref_key_horizontal_space">Horizontální mezery mezi klávesami</string>
<string name="pref_key_vertical_space">Vertikální mezery mezi klávesami</string> <string name="pref_key_vertical_space">Vertikální mezery mezi klávesami</string>
<!-- <string name="pref_category_advanced">Advanced</string> -->
<!-- <string name="pref_custom_layout_title">Custom layout</string> -->
<!-- <string name="pref_custom_layout_summary">See the source code. This option is not meant to be used.</string> -->
<!-- <string name="pref_vibration_e_disabled">Disabled</string> -->
<!-- <string name="pref_vibration_e_system">System</string> -->
<!-- <string name="pref_vibration_e_strong">Strong</string> -->
<!-- <string name="pref_vibration_e_medium">Medium</string> -->
<!-- <string name="pref_vibration_e_light">Light</string> -->
<string name="key_action_next">Další</string> <string name="key_action_next">Další</string>
<string name="key_action_done">Dokončit</string> <string name="key_action_done">Dokončit</string>
<string name="key_action_go">Spustit</string> <string name="key_action_go">Spustit</string>
<string name="key_action_prev">Předchozí</string> <string name="key_action_prev">Předchozí</string>
<string name="key_action_search">Hledat</string> <string name="key_action_search">Hledat</string>
<string name="key_action_send">Odeslat</string> <string name="key_action_send">Odeslat</string>
<!-- <string name="launcher_button_imesettings">Enable keyboard</string> --> <string name="launcher_button_imesettings">Aktivovat klávesnici</string>
<!-- <string name="launcher_description">This application is a virtual keyboard. Go to the system settings by clicking on the button below and enable Unexpected-Keyboard.</string> --> <string name="launcher_button_imepicker">Vybrat klávesnici</string>
<!-- <string name="launcher_sourcecode">This is an free and open source application. You can find the source code or report bugs on <a href="https://github.com/Julow/Unexpected-Keyboard/">Github</a>.</string> --> <string name="launcher_description">Tato aplikace je pouhou virtuální klávesnicí. Přejděte do systémového nastavení, kliknutím na tlačítko níže a aktivujte ji.</string>
<!-- <string name="launcher_tryhere">After enabling, you can try the keyboard here:</string> --> <string name="launcher_sourcecode">Toto je volná, open-source aplikace. Její zdrojový kód, či hlášení chyb, naleznete na Githubu.</string>
<string name="launcher_tryhere">Po aktivaci můžete klávesnici rovnou vyzkoušet zde:</string>
<string name="key_descr_capslock">Caps lock</string>
<string name="key_descr_switch_greekmath">Řecké a matematické symboly</string>
<!-- <string name="key_descr_change_method">Switch keyboard</string> -->
<string name="key_descr_voice_typing">Hlasové zadávání</string>
<string name="key_descr_copy">Kopírovat</string>
<string name="key_descr_paste">Vložit</string>
<string name="key_descr_cut">Vyjmout</string>
<string name="key_descr_selectAll">Označit vše</string>
<string name="key_descr_shareText">Sdílet text</string>
<string name="key_descr_pasteAsPlainText">Vložit jako prostý text</string>
<string name="key_descr_undo">Zpět</string>
<string name="key_descr_redo">Znovu</string>
<string name="key_descr_ª">Indikátor řadové číslovky</string>
<string name="key_descr_º">Indikátor řadové číslovky</string>
<string name="key_descr_superscript">Horní index</string>
<string name="key_descr_subscript">Dolní index</string>
<string name="key_descr_page_up">Page Up</string>
<string name="key_descr_page_down">Page Down</string>
<string name="key_descr_home">Home</string>
<string name="key_descr_end">End</string>
<string name="pref_category_advanced">Pokročilé</string>
</resources> </resources>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="app_name" product="debug">Unexpected Keyboard (Debug)</string> <string name="app_name_release">Unexpected Keyboard</string>
<string name="app_name" product="default">Unexpected Keyboard</string> <string name="app_name_debug">Unexpected Keyboard (Debug)</string>
<string name="settings_activity_label">Unexpected Keyboard - Einstellungen</string> <string name="settings_activity_label">Unexpected Keyboard - Einstellungen</string>
<string name="pref_portrait">Im Hochformatmodus</string> <string name="pref_portrait">Im Hochformatmodus</string>
<string name="pref_landscape">Im Querformatmodus</string> <string name="pref_landscape">Im Querformatmodus</string>
@@ -10,13 +10,12 @@
<string name="pref_keyboard_opacity">Deckkraft des Tastaturhintergrunds anpassen</string> <string name="pref_keyboard_opacity">Deckkraft des Tastaturhintergrunds anpassen</string>
<string name="pref_key_opacity">Deckkraft der Tasten anpassen</string> <string name="pref_key_opacity">Deckkraft der Tasten anpassen</string>
<string name="pref_key_activated_opacity">Deckkraft gedrückter Tasten anpassen</string> <string name="pref_key_activated_opacity">Deckkraft gedrückter Tasten anpassen</string>
<string name="pref_layout_title">Tastaturlayout ändern</string>
<string name="pref_layout_e_system">Systemeinstellung</string> <string name="pref_layout_e_system">Systemeinstellung</string>
<string name="pref_layout_e_custom">Eigenes Layout</string> <string name="pref_layout_e_custom">Eigenes Layout</string>
<string name="pref_accents_title">Akzente</string> <string name="pref_layouts_add">Alternatives Layout hinzufügen</string>
<string name="pref_accents_e_all_installed">Akzente für alle installierten Sprachen anzeigen</string> <string name="pref_layouts_item">Layout %1$d: %2$s</string>
<string name="pref_accents_e_selected">Akzente nur für die gewählte Sprache anzeigen</string> <string name="pref_layouts_remove_custom">Layout entfernen</string>
<string name="pref_accents_e_none">Akzente verbergen</string> <string name="pref_custom_layout_title">Eigenes Layout</string>
<string name="pref_show_numpad_title">Ziffernblock anzeigen</string> <string name="pref_show_numpad_title">Ziffernblock anzeigen</string>
<string name="pref_show_numpad_never">Nie</string> <string name="pref_show_numpad_never">Nie</string>
<string name="pref_show_numpad_landscape">Nur im Querformat</string> <string name="pref_show_numpad_landscape">Nur im Querformat</string>
@@ -27,6 +26,8 @@
<string name="pref_numpad_layout_e_high_first">Hohe Ziffern zuerst</string> <string name="pref_numpad_layout_e_high_first">Hohe Ziffern zuerst</string>
<string name="pref_numpad_layout_e_low_first">Niedrige Ziffern zuerst</string> <string name="pref_numpad_layout_e_low_first">Niedrige Ziffern zuerst</string>
<string name="pref_extra_keys_title">Zusätzliche Zeichen zur Tastatur hinzufügen</string> <string name="pref_extra_keys_title">Zusätzliche Zeichen zur Tastatur hinzufügen</string>
<string name="pref_extra_keys_custom">Benutzerdefinierte Tasten hinzufügen</string>
<string name="pref_extra_keys_internal">Tasten auswählen, die der Tastatur hinzugefügt werden sollen</string>
<string name="pref_second_layout_title">Zweites Layout</string> <string name="pref_second_layout_title">Zweites Layout</string>
<string name="pref_second_layout_none">Keines</string> <string name="pref_second_layout_none">Keines</string>
<string name="pref_category_typing">Tippen</string> <string name="pref_category_typing">Tippen</string>
@@ -41,8 +42,10 @@
<string name="pref_autocapitalisation_summary">Umschalttaste am Satzanfang aktivieren</string> <string name="pref_autocapitalisation_summary">Umschalttaste am Satzanfang aktivieren</string>
<string name="pref_switch_input_immediate_title">Sofort zur nächsten Tastatur wechseln</string> <string name="pref_switch_input_immediate_title">Sofort zur nächsten Tastatur wechseln</string>
<string name="pref_switch_input_immediate_summary">Verhalten der Tastaturumschalttaste</string> <string name="pref_switch_input_immediate_summary">Verhalten der Tastaturumschalttaste</string>
<string name="pref_vibrate_title">Vibration</string> <!-- <string name="pref_vibrate_custom">Custom vibration</string> -->
<string name="pref_vibrate_summary">Vibration bei Tastendruck ein-/ausschalten</string> <!-- <string name="pref_vibrate_duration_title">Vibration intensity</string> -->
<string name="pref_pin_entry_enabled_title">PIN-Eingabe-Layout</string>
<string name="pref_pin_entry_enabled_summary">Für die Nummern-, Datums- und Telefonnummern-Eingabe</string>
<string name="pref_category_style">Design</string> <string name="pref_category_style">Design</string>
<string name="pref_margin_bottom_title">Unterer Abstand</string> <string name="pref_margin_bottom_title">Unterer Abstand</string>
<string name="pref_keyboard_height_title">Höhe der Tastatur</string> <string name="pref_keyboard_height_title">Höhe der Tastatur</string>
@@ -57,6 +60,8 @@
<string name="pref_theme_e_altblack">Alternatives Schwarz</string> <string name="pref_theme_e_altblack">Alternatives Schwarz</string>
<string name="pref_theme_e_white">Weiß</string> <string name="pref_theme_e_white">Weiß</string>
<string name="pref_theme_e_epaper">ePaper</string> <string name="pref_theme_e_epaper">ePaper</string>
<string name="pref_theme_e_desert">Wüste</string>
<string name="pref_theme_e_jungle">Dschungel</string>
<string name="pref_swipe_dist_e_very_short">Sehr kurz</string> <string name="pref_swipe_dist_e_very_short">Sehr kurz</string>
<string name="pref_swipe_dist_e_short">Kurz</string> <string name="pref_swipe_dist_e_short">Kurz</string>
<string name="pref_swipe_dist_e_default">Normal</string> <string name="pref_swipe_dist_e_default">Normal</string>
@@ -64,14 +69,6 @@
<string name="pref_swipe_dist_e_very_far">Sehr weit</string> <string name="pref_swipe_dist_e_very_far">Sehr weit</string>
<string name="pref_key_horizontal_space">Horizontaler Abstand zwischen den Tasten</string> <string name="pref_key_horizontal_space">Horizontaler Abstand zwischen den Tasten</string>
<string name="pref_key_vertical_space">Vertikaler Abstand zwischen den Tasten</string> <string name="pref_key_vertical_space">Vertikaler Abstand zwischen den Tasten</string>
<string name="pref_category_advanced">Erweitert</string>
<string name="pref_custom_layout_title">Eigenes Layout</string>
<string name="pref_custom_layout_summary">Bitte Sourcecode ansehen. Diese Option ist nicht zur Verwendung vorgesehen.</string>
<!-- <string name="pref_vibration_e_disabled">Disabled</string> -->
<!-- <string name="pref_vibration_e_system">System</string> -->
<!-- <string name="pref_vibration_e_strong">Strong</string> -->
<!-- <string name="pref_vibration_e_medium">Medium</string> -->
<!-- <string name="pref_vibration_e_light">Light</string> -->
<string name="key_action_next">Nächstes</string> <string name="key_action_next">Nächstes</string>
<string name="key_action_done">Fertig</string> <string name="key_action_done">Fertig</string>
<string name="key_action_go">Los</string> <string name="key_action_go">Los</string>
@@ -79,7 +76,29 @@
<string name="key_action_search">Suchen</string> <string name="key_action_search">Suchen</string>
<string name="key_action_send">Senden</string> <string name="key_action_send">Senden</string>
<string name="launcher_button_imesettings">Tastatur aktivieren</string> <string name="launcher_button_imesettings">Tastatur aktivieren</string>
<string name="launcher_button_imepicker">Tastatur auswählen</string>
<string name="launcher_description">Diese App ist eine virtuelle Tastatur. Tippe auf den Button unten und aktivere Unexpected Keyboard in den Systemeinstellungen.</string> <string name="launcher_description">Diese App ist eine virtuelle Tastatur. Tippe auf den Button unten und aktivere Unexpected Keyboard in den Systemeinstellungen.</string>
<string name="launcher_sourcecode">Dies ist eine freie und quelloffene App. Du findest den Quellcode auf <a href="https://github.com/Julow/Unexpected-Keyboard/">Github</a>. Dort können auch Bugs gemeldet werden.</string> <string name="launcher_sourcecode">Dies ist eine freie und quelloffene App. Du findest den Quellcode auf Github. Dort können auch Bugs gemeldet werden.</string>
<string name="launcher_tryhere">Nach Aktivierung kannst du die Tastatur hier ausprobieren:</string> <string name="launcher_tryhere">Nach Aktivierung kannst du die Tastatur hier ausprobieren:</string>
<string name="key_descr_capslock">Feststelltaste</string>
<string name="key_descr_switch_greekmath">Griechische &amp; mathematische Symbole</string>
<!-- <string name="key_descr_change_method">Switch keyboard</string> -->
<string name="key_descr_voice_typing">Spracheingabe</string>
<string name="key_descr_copy">Kopieren</string>
<string name="key_descr_paste">Einfügen</string>
<string name="key_descr_cut">Ausschneiden</string>
<string name="key_descr_selectAll">Alles auswählen</string>
<string name="key_descr_shareText">Text teilen</string>
<string name="key_descr_pasteAsPlainText">Unformatiert einfügen</string>
<string name="key_descr_undo">Rückgängig</string>
<string name="key_descr_redo">Wiederholen</string>
<string name="key_descr_ª">Ordinalzeichen</string>
<string name="key_descr_º">Ordinalzeichen</string>
<string name="key_descr_superscript">Hochgestellt</string>
<string name="key_descr_subscript">Tiefgestellt</string>
<string name="key_descr_page_up">Bild auf</string>
<string name="key_descr_page_down">Bild ab</string>
<string name="key_descr_home">Pos1</string>
<string name="key_descr_end">Ende</string>
<string name="pref_category_advanced">Erweitert</string>
</resources> </resources>

View File

@@ -1,85 +1,104 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<!-- <string name="app_name" product="debug">Unexpected Keyboard (debug)</string> --> <string name="app_name_release">Unexpected Keyboard</string>
<!-- <string name="app_name" product="default">Unexpected Keyboard</string> --> <string name="app_name_debug">Unexpected Keyboard (debug)</string>
<string name="settings_activity_label">Ajustes de Unexpected Keyboard</string> <string name="settings_activity_label">Ajustes de Unexpected Keyboard</string>
<!-- <string name="pref_portrait">In portrait mode</string> --> <string name="pref_portrait">En modo vertical</string>
<!-- <string name="pref_landscape">In landscape mode</string> --> <string name="pref_landscape">En modo horizontal</string>
<string name="pref_category_layout">Formato</string> <string name="pref_category_layout">Distribución</string>
<!-- <string name="pref_label_brightness">Adjust label brightness</string> --> <string name="pref_label_brightness">Ajustar brillo de etiqueta</string>
<!-- <string name="pref_keyboard_opacity">Adjust keyboard background opacity</string> --> <string name="pref_keyboard_opacity">Ajustar opacidad del fondo del teclado</string>
<!-- <string name="pref_key_opacity">Adjust key opacity</string> --> <string name="pref_key_opacity">Ajustar opacidad de teclas</string>
<!-- <string name="pref_key_activated_opacity">Adjust pressed key opacity</string> --> <string name="pref_key_activated_opacity">Ajustar opacidad de teclas presionadas</string>
<string name="pref_layout_title">Cambiar formato de teclado</string> <string name="pref_layout_e_system">Igual al sistema</string>
<string name="pref_layout_e_system">Ajustes del sistema</string> <string name="pref_layout_e_custom">Diseño personalizado</string>
<!-- <string name="pref_layout_e_custom">Custom layout</string> --> <string name="pref_layouts_add">Añadir distribución alterna</string>
<string name="pref_accents_title">Acentos</string> <string name="pref_layouts_item">Diseño %1$d: %2$s</string>
<string name="pref_accents_e_all_installed">Mostrar acentos para todos los lenguajes instalados</string> <string name="pref_layouts_remove_custom">Quitar diseño</string>
<string name="pref_accents_e_selected">Solo mostrar acentos para el lenguaje seleccionado</string> <string name="pref_custom_layout_title">Diseño personalizado</string>
<string name="pref_accents_e_none">Ocultar acentos</string> <string name="pref_show_numpad_title">Mostrar teclado numérico</string>
<!-- <string name="pref_show_numpad_title">Show NumPad</string> --> <string name="pref_show_numpad_never">Nunca</string>
<!-- <string name="pref_show_numpad_never">Never</string> --> <string name="pref_show_numpad_landscape">Solo en modo horizontal</string>
<!-- <string name="pref_show_numpad_landscape">Only in landscape mode</string> --> <string name="pref_show_numpad_always">Siempre</string>
<!-- <string name="pref_show_numpad_always">Always</string> --> <string name="pref_number_row_title">Mostrar fila de números</string>
<!-- <string name="pref_number_row_title">Show number row</string> --> <string name="pref_number_row_summary">Agrega la fila numérica a la parte superior del teclado si el teclado numérico está oculto</string>
<!-- <string name="pref_number_row_summary">Add a number row at the top of the keyboard when the numpad is hidden</string> --> <string name="pref_numpad_layout">Diseño del teclado numérico</string>
<!-- <string name="pref_numpad_layout">NumPad layout</string> --> <string name="pref_numpad_layout_e_high_first">Dígitos descendientes</string>
<!-- <string name="pref_numpad_layout_e_high_first">High digits first</string> --> <string name="pref_numpad_layout_e_low_first">gitos ascendientes</string>
<!-- <string name="pref_numpad_layout_e_low_first">Low digits first</string> --> <string name="pref_extra_keys_title">Agregar teclas</string>
<!-- <string name="pref_extra_keys_title">Add keys to the keyboard</string> --> <string name="pref_extra_keys_custom">Agregar teclas personalizadas</string>
<!-- <string name="pref_second_layout_title">Secondary layout</string> --> <string name="pref_extra_keys_internal">Selecciona teclas para agregar al teclado</string>
<!-- <string name="pref_second_layout_none">None</string> --> <string name="pref_second_layout_title">Formato secundario</string>
<string name="pref_category_typing">Escribiendo</string> <string name="pref_second_layout_none">Ninguno</string>
<string name="pref_swipe_dist_title">Distancia para deslizar</string> <string name="pref_category_typing">Escritura</string>
<string name="pref_swipe_dist_summary">Distancia de caracteres en las esquinas de las letras (%s)</string> <string name="pref_swipe_dist_title">Distancia de deslizamiento</string>
<string name="pref_long_timeout_title">Tiempo de espera de repetición de tecla</string> <string name="pref_swipe_dist_summary">Distancia de caracteres en las esquinas de las teclas (%s)</string>
<string name="pref_long_timeout_title">Tiempo de espera para repetir tecla</string>
<string name="pref_long_interval_title">Intervalo de repetición de tecla</string> <string name="pref_long_interval_title">Intervalo de repetición de tecla</string>
<!-- <string name="pref_lock_double_tap_title">Double tap on shift for caps lock</string> --> <string name="pref_lock_double_tap_title">Doble toque en Mayús para bloquear las mayúsculas</string>
<!-- <string name="pref_lock_double_tap_summary">You can lock any modifier by holding it</string> --> <string name="pref_lock_double_tap_summary">Se puede bloquear cualquier modificador manteniéndolo presionado</string>
<!-- <string name="pref_category_behavior">Behavior</string> --> <string name="pref_category_behavior">Comportamiento</string>
<!-- <string name="pref_autocapitalisation_title">Automatic capitalisation</string> --> <string name="pref_autocapitalisation_title">Mayúsculas automáticas</string>
<!-- <string name="pref_autocapitalisation_summary">Press Shift at the beginning of a sentence</string> --> <string name="pref_autocapitalisation_summary">Presionar Mayús al principio de una oración</string>
<!-- <string name="pref_switch_input_immediate_title">Switch to the last used keyboard</string> --> <string name="pref_switch_input_immediate_title">Cambiar al último teclado usado</string>
<!-- <string name="pref_switch_input_immediate_summary">Behavior of the keyboard-switching key</string> --> <string name="pref_switch_input_immediate_summary">Comportamiento de la tecla para cambiar diseño</string>
<string name="pref_vibrate_title">Vibración</string> <!-- <string name="pref_vibrate_custom">Custom vibration</string> -->
<string name="pref_vibrate_summary">Habilitar/deshabilitar vibración al presionar una tecla</string> <!-- <string name="pref_vibrate_duration_title">Vibration intensity</string> -->
<string name="pref_pin_entry_enabled_title">Diseño de introducción de PIN</string>
<string name="pref_pin_entry_enabled_summary">Para escribir cifras, fechas y números telefónicos</string>
<string name="pref_category_style">Estilo</string> <string name="pref_category_style">Estilo</string>
<string name="pref_margin_bottom_title">Margen del pie</string> <string name="pref_margin_bottom_title">Margen inferior</string>
<string name="pref_keyboard_height_title">Altura del teclado</string> <string name="pref_keyboard_height_title">Altura del teclado</string>
<string name="pref_horizontal_margin_title">Margen horizontal</string> <string name="pref_horizontal_margin_title">Margen horizontal</string>
<string name="pref_character_size_title">Tamaño de etiqueta</string> <string name="pref_character_size_title">Tamaño de etiqueta</string>
<string name="pref_character_size_summary">Tamaño de caracteres mostrados en el teclado (%.2fx)</string> <string name="pref_character_size_summary">Tamaño de caracteres mostrados en el teclado (%.2fx)</string>
<string name="pref_theme">Tema</string> <string name="pref_theme">Tema</string>
<string name="pref_theme_e_system">Ajustes de sistema</string> <string name="pref_theme_e_system">Igual al sistema</string>
<string name="pref_theme_e_dark">Oscuro</string> <string name="pref_theme_e_dark">Oscuro</string>
<string name="pref_theme_e_light">Claro</string> <string name="pref_theme_e_light">Claro</string>
<string name="pref_theme_e_black">Negro</string> <string name="pref_theme_e_black">Negro</string>
<!-- <string name="pref_theme_e_altblack">Alternative Black</string> --> <string name="pref_theme_e_altblack">Negro alternativo</string>
<!-- <string name="pref_theme_e_white">White</string> --> <string name="pref_theme_e_white">Blanco</string>
<!-- <string name="pref_theme_e_epaper">ePaper</string> --> <string name="pref_theme_e_epaper">ePaper</string>
<string name="pref_swipe_dist_e_very_short">Muy corto</string> <string name="pref_theme_e_desert">Desierto</string>
<string name="pref_swipe_dist_e_short">Corto</string> <string name="pref_theme_e_jungle">Selva</string>
<string name="pref_swipe_dist_e_very_short">Muy corta</string>
<string name="pref_swipe_dist_e_short">Corta</string>
<string name="pref_swipe_dist_e_default">Normal</string> <string name="pref_swipe_dist_e_default">Normal</string>
<string name="pref_swipe_dist_e_far">Lejano</string> <string name="pref_swipe_dist_e_far">Larga</string>
<string name="pref_swipe_dist_e_very_far">Muy lejano</string> <string name="pref_swipe_dist_e_very_far">Muy larga</string>
<string name="pref_key_horizontal_space">Espaciado horizontal entre las teclas</string> <string name="pref_key_horizontal_space">Espaciado horizontal entre las teclas</string>
<string name="pref_key_vertical_space">Espaciado vertical entre las teclas</string> <string name="pref_key_vertical_space">Espaciado vertical entre las teclas</string>
<!-- <string name="pref_category_advanced">Advanced</string> -->
<!-- <string name="pref_custom_layout_title">Custom layout</string> -->
<!-- <string name="pref_custom_layout_summary">See the source code. This option is not meant to be used.</string> -->
<!-- <string name="pref_vibration_e_disabled">Disabled</string> -->
<!-- <string name="pref_vibration_e_system">System</string> -->
<!-- <string name="pref_vibration_e_strong">Strong</string> -->
<!-- <string name="pref_vibration_e_medium">Medium</string> -->
<!-- <string name="pref_vibration_e_light">Light</string> -->
<string name="key_action_next">Siguiente</string> <string name="key_action_next">Siguiente</string>
<string name="key_action_done">Hecho</string> <string name="key_action_done">Hecho</string>
<string name="key_action_go">Ir</string> <string name="key_action_go">Ir</string>
<string name="key_action_prev">Anterior</string> <string name="key_action_prev">Anterior</string>
<string name="key_action_search">Buscar</string> <string name="key_action_search">Buscar</string>
<string name="key_action_send">Enviar</string> <string name="key_action_send">Enviar</string>
<!-- <string name="launcher_button_imesettings">Enable keyboard</string> --> <string name="launcher_button_imesettings">Habilitar teclado</string>
<!-- <string name="launcher_description">This application is a virtual keyboard. Go to the system settings by clicking on the button below and enable Unexpected-Keyboard.</string> --> <string name="launcher_button_imepicker">Seleccionar método de entrada</string>
<!-- <string name="launcher_sourcecode">This is an free and open source application. You can find the source code or report bugs on <a href="https://github.com/Julow/Unexpected-Keyboard/">Github</a>.</string> --> <string name="launcher_description">Esta aplicación es un teclado virtual. Presiona el botón de abajo para ir a Ajustes y habilitar Unexpected Keyboard.</string>
<!-- <string name="launcher_tryhere">After enabling, you can try the keyboard here:</string> --> <string name="launcher_sourcecode">Esta es una aplicación gratuita, libre y de código abierto. Puedes encontrar el código fuente o reportar errores en GitHub.</string>
<string name="launcher_tryhere">Tras habilitarlo, puedes probar el teclado en este campo:</string>
<string name="key_descr_capslock">Bloq Mayús</string>
<string name="key_descr_switch_greekmath">Símb. griegos y matemáticos</string>
<!-- <string name="key_descr_change_method">Switch keyboard</string> -->
<string name="key_descr_voice_typing">Dictado por voz</string>
<string name="key_descr_copy">Copiar</string>
<string name="key_descr_paste">Pegar</string>
<string name="key_descr_cut">Cortar</string>
<string name="key_descr_selectAll">Seleccionar todo</string>
<string name="key_descr_shareText">Compartir texto</string>
<string name="key_descr_pasteAsPlainText">Pegar como texto sin formato</string>
<string name="key_descr_undo">Deshacer</string>
<string name="key_descr_redo">Rehacer</string>
<string name="key_descr_ª">Indicador de ordinal</string>
<string name="key_descr_º">Indicador de ordinal</string>
<string name="key_descr_superscript">Superíndice</string>
<string name="key_descr_subscript">Subíndice</string>
<string name="key_descr_page_up">Av Pág</string>
<string name="key_descr_page_down">Re Pág</string>
<string name="key_descr_home">Inicio</string>
<string name="key_descr_end">Fin</string>
<string name="pref_category_advanced">Avanzado</string>
</resources> </resources>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="app_name" product="debug">صفحه کلید غیرمنتظره</string> <string name="app_name_release">صفحه کلید غیرمنتظره</string>
<string name="app_name" product="default">صفحه کلید غیرمنتظره</string> <string name="app_name_debug">صفحه کلید غیرمنتظره</string>
<string name="settings_activity_label">تنظیمات صفحه کلید غیرمنتظره</string> <string name="settings_activity_label">تنظیمات صفحه کلید غیرمنتظره</string>
<string name="pref_portrait">در حالت عمودی</string> <string name="pref_portrait">در حالت عمودی</string>
<string name="pref_landscape">در حالت افقی</string> <string name="pref_landscape">در حالت افقی</string>
@@ -10,13 +10,12 @@
<string name="pref_keyboard_opacity">تنظیم کدر بودن پس‌زمینه صفحه کلید</string> <string name="pref_keyboard_opacity">تنظیم کدر بودن پس‌زمینه صفحه کلید</string>
<string name="pref_key_opacity">تنظیم کدر بودن کلید</string> <string name="pref_key_opacity">تنظیم کدر بودن کلید</string>
<string name="pref_key_activated_opacity">تنظیم کدر بودن کلید فشرده شده</string> <string name="pref_key_activated_opacity">تنظیم کدر بودن کلید فشرده شده</string>
<string name="pref_layout_title">تغییر طرح صفحه کلید</string>
<string name="pref_layout_e_system">تنظیمات سامانه</string> <string name="pref_layout_e_system">تنظیمات سامانه</string>
<string name="pref_layout_e_custom">طرح صفارشی</string> <string name="pref_layout_e_custom">طرح صفارشی</string>
<string name="pref_accents_title">لهجه‌ها</string> <!-- <string name="pref_layouts_add">Add an alternate layout</string> -->
<string name="pref_accents_e_all_installed">نمایش لهجه‌ها برای تمام زبان‌هی نصب شده</string> <!-- <string name="pref_layouts_item">Layout %1$d: %2$s</string> -->
<string name="pref_accents_e_selected">فقط نمایش لهجه‌ها برای زبان‌های انتخاب شده</string> <!-- <string name="pref_layouts_remove_custom">Remove layout</string> -->
<string name="pref_accents_e_none">پنهان کردن لهجه‌ها</string> <string name="pref_custom_layout_title">طرح شخصی</string>
<string name="pref_show_numpad_title">نمایش پد شماره‌ها</string> <string name="pref_show_numpad_title">نمایش پد شماره‌ها</string>
<string name="pref_show_numpad_never">هرگز</string> <string name="pref_show_numpad_never">هرگز</string>
<string name="pref_show_numpad_landscape">فقط در حالت افقی</string> <string name="pref_show_numpad_landscape">فقط در حالت افقی</string>
@@ -27,6 +26,8 @@
<string name="pref_numpad_layout_e_high_first">ابتدا اعداد بزرگ</string> <string name="pref_numpad_layout_e_high_first">ابتدا اعداد بزرگ</string>
<string name="pref_numpad_layout_e_low_first">ابتدا اعداد کوچک</string> <string name="pref_numpad_layout_e_low_first">ابتدا اعداد کوچک</string>
<string name="pref_extra_keys_title">افزودن کلیدها به صفحه کلید</string> <string name="pref_extra_keys_title">افزودن کلیدها به صفحه کلید</string>
<!-- <string name="pref_extra_keys_custom">Add custom keys</string> -->
<!-- <string name="pref_extra_keys_internal">Select keys to add to the keyboard</string> -->
<string name="pref_second_layout_title">طرح دوم</string> <string name="pref_second_layout_title">طرح دوم</string>
<string name="pref_second_layout_none">هیچ</string> <string name="pref_second_layout_none">هیچ</string>
<string name="pref_category_typing">درحال نوشتن</string> <string name="pref_category_typing">درحال نوشتن</string>
@@ -41,8 +42,10 @@
<string name="pref_autocapitalisation_summary">در شروع جملات دگرساز را فشار دهید</string> <string name="pref_autocapitalisation_summary">در شروع جملات دگرساز را فشار دهید</string>
<string name="pref_switch_input_immediate_title">انتقال به آخرین صفحه کلید استفاده شده</string> <string name="pref_switch_input_immediate_title">انتقال به آخرین صفحه کلید استفاده شده</string>
<string name="pref_switch_input_immediate_summary">رفتار کلید تغییردهنده صفحه کلید</string> <string name="pref_switch_input_immediate_summary">رفتار کلید تغییردهنده صفحه کلید</string>
<string name="pref_vibrate_title">لرزش</string> <!-- <string name="pref_vibrate_custom">Custom vibration</string> -->
<string name="pref_vibrate_summary">فعال/غیرفعال کردن لرزش در زمان فشار دادن کلیدها</string> <!-- <string name="pref_vibrate_duration_title">Vibration intensity</string> -->
<!-- <string name="pref_pin_entry_enabled_title">Pin entry layout</string> -->
<!-- <string name="pref_pin_entry_enabled_summary">When typing numbers, dates and phone numbers</string> -->
<string name="pref_category_style">سبک</string> <string name="pref_category_style">سبک</string>
<string name="pref_margin_bottom_title">حاشیه پایین</string> <string name="pref_margin_bottom_title">حاشیه پایین</string>
<string name="pref_keyboard_height_title">ارتفاع صفحه کلید</string> <string name="pref_keyboard_height_title">ارتفاع صفحه کلید</string>
@@ -57,6 +60,8 @@
<string name="pref_theme_e_altblack">سیاه مشابه</string> <string name="pref_theme_e_altblack">سیاه مشابه</string>
<string name="pref_theme_e_white">سفید</string> <string name="pref_theme_e_white">سفید</string>
<string name="pref_theme_e_epaper">ای-پیپر</string> <string name="pref_theme_e_epaper">ای-پیپر</string>
<!-- <string name="pref_theme_e_desert">Desert</string> -->
<!-- <string name="pref_theme_e_jungle">Jungle</string> -->
<string name="pref_swipe_dist_e_very_short">بسیار کوتاه</string> <string name="pref_swipe_dist_e_very_short">بسیار کوتاه</string>
<string name="pref_swipe_dist_e_short">کوتاه</string> <string name="pref_swipe_dist_e_short">کوتاه</string>
<string name="pref_swipe_dist_e_default">عادی</string> <string name="pref_swipe_dist_e_default">عادی</string>
@@ -64,14 +69,6 @@
<string name="pref_swipe_dist_e_very_far">بسیار دور</string> <string name="pref_swipe_dist_e_very_far">بسیار دور</string>
<string name="pref_key_horizontal_space">فاصله افقی بین کلیدها</string> <string name="pref_key_horizontal_space">فاصله افقی بین کلیدها</string>
<string name="pref_key_vertical_space">فاصله عمودی بین کلیدها</string> <string name="pref_key_vertical_space">فاصله عمودی بین کلیدها</string>
<string name="pref_category_advanced">پیشرفته</string>
<string name="pref_custom_layout_title">طرح شخصی</string>
<string name="pref_custom_layout_summary">کد منبع را ببینید. این گزینه قرار نیست استفاده شود.</string>
<!-- <string name="pref_vibration_e_disabled">Disabled</string> -->
<!-- <string name="pref_vibration_e_system">System</string> -->
<!-- <string name="pref_vibration_e_strong">Strong</string> -->
<!-- <string name="pref_vibration_e_medium">Medium</string> -->
<!-- <string name="pref_vibration_e_light">Light</string> -->
<string name="key_action_next">بعدی</string> <string name="key_action_next">بعدی</string>
<string name="key_action_done">اتمام</string> <string name="key_action_done">اتمام</string>
<string name="key_action_go">برو</string> <string name="key_action_go">برو</string>
@@ -79,7 +76,29 @@
<string name="key_action_search">جستجو</string> <string name="key_action_search">جستجو</string>
<string name="key_action_send">ارسال</string> <string name="key_action_send">ارسال</string>
<string name="launcher_button_imesettings">فعال کردن صفحه کلید</string> <string name="launcher_button_imesettings">فعال کردن صفحه کلید</string>
<!-- <string name="launcher_button_imepicker">Select keyboard</string> -->
<string name="launcher_description">این برنامه یک صفحه کلید مجازی است. با کلیک روی گزینه زیر به تنظیمات سامانه بروید و صفحه کلید غیرمنتظره را فعال کنید.</string> <string name="launcher_description">این برنامه یک صفحه کلید مجازی است. با کلیک روی گزینه زیر به تنظیمات سامانه بروید و صفحه کلید غیرمنتظره را فعال کنید.</string>
<string name="launcher_sourcecode">این یک برنامه آزاد و منبع‌باز است. شما میتوانید پیدا کنید کد منبع را و گزارش کنید باگ‌ها را در <a href="https://github.com/Julow/Unexpected-Keyboard/">گیت‌هاب</a>.</string> <string name="launcher_sourcecode">این یک برنامه متن باز و آزاد است. شما میتوانید کد منبع را در گیتهاب پیدا کرده و نیز باگ‌ها را گزارش کنید.</string>
<string name="launcher_tryhere">بعد از فعالسازی، صفحه کلید را اینجا امتحان کنید:</string> <string name="launcher_tryhere">بعد از فعالسازی، صفحه کلید را اینجا امتحان کنید:</string>
<!-- <string name="key_descr_capslock">Caps lock</string> -->
<!-- <string name="key_descr_switch_greekmath">Greek &amp; math symbols</string> -->
<!-- <string name="key_descr_change_method">Switch keyboard</string> -->
<!-- <string name="key_descr_voice_typing">Voice typing</string> -->
<!-- <string name="key_descr_copy">Copy</string> -->
<!-- <string name="key_descr_paste">Paste</string> -->
<!-- <string name="key_descr_cut">Cut</string> -->
<!-- <string name="key_descr_selectAll">Select all</string> -->
<!-- <string name="key_descr_shareText">Share text</string> -->
<!-- <string name="key_descr_pasteAsPlainText">Paste as plain text</string> -->
<!-- <string name="key_descr_undo">Undo</string> -->
<!-- <string name="key_descr_redo">Redo</string> -->
<!-- <string name="key_descr_ª">Ordinal Indicator</string> -->
<!-- <string name="key_descr_º">Ordinal Indicator</string> -->
<!-- <string name="key_descr_superscript">Superscript</string> -->
<!-- <string name="key_descr_subscript">Subscript</string> -->
<!-- <string name="key_descr_page_up">Page Up</string> -->
<!-- <string name="key_descr_page_down">Page Down</string> -->
<!-- <string name="key_descr_home">Home</string> -->
<!-- <string name="key_descr_end">End</string> -->
<string name="pref_category_advanced">پیشرفته</string>
</resources> </resources>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="app_name" product="debug">Unexpected Keyboard (debug)</string> <string name="app_name_release">Unexpected Keyboard</string>
<string name="app_name" product="default">Unexpected Keyboard</string> <string name="app_name_debug">Unexpected Keyboard (debug)</string>
<string name="settings_activity_label">Unexpected Keyboard Paramètres</string> <string name="settings_activity_label">Unexpected Keyboard Paramètres</string>
<string name="pref_portrait">En mode portrait</string> <string name="pref_portrait">En mode portrait</string>
<string name="pref_landscape">En mode landscape</string> <string name="pref_landscape">En mode landscape</string>
@@ -10,13 +10,12 @@
<string name="pref_keyboard_opacity">Transparence du clavier</string> <string name="pref_keyboard_opacity">Transparence du clavier</string>
<string name="pref_key_opacity">Transparence des touches</string> <string name="pref_key_opacity">Transparence des touches</string>
<string name="pref_key_activated_opacity">Transparence des touches pressées</string> <string name="pref_key_activated_opacity">Transparence des touches pressées</string>
<string name="pref_layout_title">Disposition des touches</string>
<string name="pref_layout_e_system">Paramètre système</string> <string name="pref_layout_e_system">Paramètre système</string>
<string name="pref_layout_e_custom">Disposition personnalisée</string> <string name="pref_layout_e_custom">Disposition personnalisée</string>
<string name="pref_accents_title">Accents</string> <string name="pref_layouts_add">Ajouter un clavier alternatif</string>
<string name="pref_accents_e_all_installed">Afficher les accents pour les langues installées</string> <string name="pref_layouts_item">Disposition %1$d: %2$s</string>
<string name="pref_accents_e_selected">Afficher les accents pour la langue sélectionnée</string> <string name="pref_layouts_remove_custom">Supprimer</string>
<string name="pref_accents_e_none">Cacher les accents</string> <string name="pref_custom_layout_title">Disposition personnalisée</string>
<string name="pref_show_numpad_title">Afficher le pavé numérique</string> <string name="pref_show_numpad_title">Afficher le pavé numérique</string>
<string name="pref_show_numpad_never">Jamais</string> <string name="pref_show_numpad_never">Jamais</string>
<string name="pref_show_numpad_landscape">Seulement en mode paysage</string> <string name="pref_show_numpad_landscape">Seulement en mode paysage</string>
@@ -27,6 +26,8 @@
<string name="pref_numpad_layout_e_high_first">Du plus haut au plus bas</string> <string name="pref_numpad_layout_e_high_first">Du plus haut au plus bas</string>
<string name="pref_numpad_layout_e_low_first">Du plus bas au plus haut</string> <string name="pref_numpad_layout_e_low_first">Du plus bas au plus haut</string>
<string name="pref_extra_keys_title">Ajouter des touches au clavier</string> <string name="pref_extra_keys_title">Ajouter des touches au clavier</string>
<string name="pref_extra_keys_custom">Ajouter des touches personnalisées</string>
<string name="pref_extra_keys_internal">Sélectionner les touches à ajouter au clavier</string>
<string name="pref_second_layout_title">Disposition secondaire</string> <string name="pref_second_layout_title">Disposition secondaire</string>
<string name="pref_second_layout_none">Aucune</string> <string name="pref_second_layout_none">Aucune</string>
<string name="pref_category_typing">Saisie</string> <string name="pref_category_typing">Saisie</string>
@@ -41,8 +42,10 @@
<string name="pref_autocapitalisation_summary">Activer Shift au début des phrases</string> <string name="pref_autocapitalisation_summary">Activer Shift au début des phrases</string>
<string name="pref_switch_input_immediate_title">Changer vers le clavier utilisé en dernier</string> <string name="pref_switch_input_immediate_title">Changer vers le clavier utilisé en dernier</string>
<string name="pref_switch_input_immediate_summary">Comportement de la touche de changement de clavier</string> <string name="pref_switch_input_immediate_summary">Comportement de la touche de changement de clavier</string>
<string name="pref_vibrate_title">Vibreur</string> <!-- <string name="pref_vibrate_custom">Custom vibration</string> -->
<string name="pref_vibrate_summary">Vibration a chaque touche</string> <!-- <string name="pref_vibrate_duration_title">Vibration intensity</string> -->
<string name="pref_pin_entry_enabled_title">Clavier PIN</string>
<string name="pref_pin_entry_enabled_summary">Lors de la saisie de nombres, de dates et de numéros de téléphone</string>
<string name="pref_category_style">Style</string> <string name="pref_category_style">Style</string>
<string name="pref_margin_bottom_title">Marge du bas</string> <string name="pref_margin_bottom_title">Marge du bas</string>
<string name="pref_keyboard_height_title">Hauteur du clavier</string> <string name="pref_keyboard_height_title">Hauteur du clavier</string>
@@ -57,6 +60,8 @@
<string name="pref_theme_e_altblack">Noir 2</string> <string name="pref_theme_e_altblack">Noir 2</string>
<string name="pref_theme_e_white">Blanc</string> <string name="pref_theme_e_white">Blanc</string>
<string name="pref_theme_e_epaper">ePaper</string> <string name="pref_theme_e_epaper">ePaper</string>
<string name="pref_theme_e_desert">Desert</string>
<string name="pref_theme_e_jungle">Jungle</string>
<string name="pref_swipe_dist_e_very_short">Très courte</string> <string name="pref_swipe_dist_e_very_short">Très courte</string>
<string name="pref_swipe_dist_e_short">Courte</string> <string name="pref_swipe_dist_e_short">Courte</string>
<string name="pref_swipe_dist_e_default">Normale</string> <string name="pref_swipe_dist_e_default">Normale</string>
@@ -64,14 +69,6 @@
<string name="pref_swipe_dist_e_very_far">Très longue</string> <string name="pref_swipe_dist_e_very_far">Très longue</string>
<string name="pref_key_horizontal_space">Espacement horizontal entre les touches</string> <string name="pref_key_horizontal_space">Espacement horizontal entre les touches</string>
<string name="pref_key_vertical_space">Espacement vertical entre les touches</string> <string name="pref_key_vertical_space">Espacement vertical entre les touches</string>
<string name="pref_category_advanced">Avancé</string>
<string name="pref_custom_layout_title">Disposition personnalisée</string>
<string name="pref_custom_layout_summary">Cette option n\'est pas faite pour être utilisée.</string>
<string name="pref_vibration_e_disabled">Désactivé</string>
<string name="pref_vibration_e_system">Système</string>
<string name="pref_vibration_e_strong">Fort</string>
<string name="pref_vibration_e_medium">Moyen</string>
<string name="pref_vibration_e_light">Léger</string>
<string name="key_action_next">Suiv.</string> <string name="key_action_next">Suiv.</string>
<string name="key_action_done">Fin</string> <string name="key_action_done">Fin</string>
<string name="key_action_go">Aller</string> <string name="key_action_go">Aller</string>
@@ -79,7 +76,29 @@
<string name="key_action_search">Chercher</string> <string name="key_action_search">Chercher</string>
<string name="key_action_send">Envoyer</string> <string name="key_action_send">Envoyer</string>
<string name="launcher_button_imesettings">Activer le clavier</string> <string name="launcher_button_imesettings">Activer le clavier</string>
<string name="launcher_button_imepicker">Selectionner le keyboard</string>
<string name="launcher_description">Cette application est un clavier virtuel. Activez-le dans les paramètres système en cliquant sur le bouton ci-dessous.</string> <string name="launcher_description">Cette application est un clavier virtuel. Activez-le dans les paramètres système en cliquant sur le bouton ci-dessous.</string>
<string name="launcher_sourcecode">Cette application est libre et open-source. Lisez le source code et reportez des problèmes sur <a href="https://github.com/Julow/Unexpected-Keyboard/">Github</a>.</string> <string name="launcher_sourcecode">Cette application est libre et open-source. Lisez le source code et reportez des problèmes sur Github.</string>
<string name="launcher_tryhere">Après l\'avoir activé, vous pouvez l\'essayer ici:</string> <string name="launcher_tryhere">Après l\'avoir activé, vous pouvez l\'essayer ici:</string>
<string name="key_descr_capslock">Verrouillage majuscules</string>
<string name="key_descr_switch_greekmath">Symboles mathématiques</string>
<!-- <string name="key_descr_change_method">Switch keyboard</string> -->
<string name="key_descr_voice_typing">Saisie vocale</string>
<string name="key_descr_copy">Copier</string>
<string name="key_descr_paste">Coller</string>
<string name="key_descr_cut">Couper</string>
<string name="key_descr_selectAll">Sel. tout</string>
<string name="key_descr_shareText">Partager</string>
<string name="key_descr_pasteAsPlainText">Copier en texte brut</string>
<string name="key_descr_undo">Undo</string>
<string name="key_descr_redo">Redo</string>
<string name="key_descr_ª">Ordinal</string>
<string name="key_descr_º">Ordinal</string>
<string name="key_descr_superscript">Exposant</string>
<string name="key_descr_subscript">Souscrit</string>
<string name="key_descr_page_up">Page précédente</string>
<string name="key_descr_page_down">Page suivante</string>
<string name="key_descr_home">Début</string>
<string name="key_descr_end">Fin</string>
<string name="pref_category_advanced">Avancé</string>
</resources> </resources>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="app_name" product="debug">Unexpected Keyboard (debug)</string> <string name="app_name_release">Unexpected Keyboard</string>
<string name="app_name" product="default">Unexpected Keyboard</string> <string name="app_name_debug">Unexpected Keyboard (debug)</string>
<string name="settings_activity_label">Impostazioni di Unexpected Keyboard</string> <string name="settings_activity_label">Impostazioni di Unexpected Keyboard</string>
<!-- <string name="pref_portrait">In portrait mode</string> --> <!-- <string name="pref_portrait">In portrait mode</string> -->
<!-- <string name="pref_landscape">In landscape mode</string> --> <!-- <string name="pref_landscape">In landscape mode</string> -->
@@ -10,13 +10,12 @@
<!-- <string name="pref_keyboard_opacity">Adjust keyboard background opacity</string> --> <!-- <string name="pref_keyboard_opacity">Adjust keyboard background opacity</string> -->
<!-- <string name="pref_key_opacity">Adjust key opacity</string> --> <!-- <string name="pref_key_opacity">Adjust key opacity</string> -->
<!-- <string name="pref_key_activated_opacity">Adjust pressed key opacity</string> --> <!-- <string name="pref_key_activated_opacity">Adjust pressed key opacity</string> -->
<string name="pref_layout_title">Cambia layout tastiera</string>
<string name="pref_layout_e_system">Impostazioni di sistema</string> <string name="pref_layout_e_system">Impostazioni di sistema</string>
<!-- <string name="pref_layout_e_custom">Custom layout</string> --> <!-- <string name="pref_layout_e_custom">Custom layout</string> -->
<string name="pref_accents_title">Accenti</string> <!-- <string name="pref_layouts_add">Add an alternate layout</string> -->
<string name="pref_accents_e_all_installed">Mostra accenti per tutte le lingue installate</string> <!-- <string name="pref_layouts_item">Layout %1$d: %2$s</string> -->
<string name="pref_accents_e_selected">Mostra accenti solo per le lingue selezionate</string> <!-- <string name="pref_layouts_remove_custom">Remove layout</string> -->
<string name="pref_accents_e_none">Nascondi accenti</string> <!-- <string name="pref_custom_layout_title">Custom layout</string> -->
<!-- <string name="pref_show_numpad_title">Show NumPad</string> --> <!-- <string name="pref_show_numpad_title">Show NumPad</string> -->
<!-- <string name="pref_show_numpad_never">Never</string> --> <!-- <string name="pref_show_numpad_never">Never</string> -->
<!-- <string name="pref_show_numpad_landscape">Only in landscape mode</string> --> <!-- <string name="pref_show_numpad_landscape">Only in landscape mode</string> -->
@@ -27,6 +26,8 @@
<!-- <string name="pref_numpad_layout_e_high_first">High digits first</string> --> <!-- <string name="pref_numpad_layout_e_high_first">High digits first</string> -->
<!-- <string name="pref_numpad_layout_e_low_first">Low digits first</string> --> <!-- <string name="pref_numpad_layout_e_low_first">Low digits first</string> -->
<!-- <string name="pref_extra_keys_title">Add keys to the keyboard</string> --> <!-- <string name="pref_extra_keys_title">Add keys to the keyboard</string> -->
<!-- <string name="pref_extra_keys_custom">Add custom keys</string> -->
<!-- <string name="pref_extra_keys_internal">Select keys to add to the keyboard</string> -->
<!-- <string name="pref_second_layout_title">Secondary layout</string> --> <!-- <string name="pref_second_layout_title">Secondary layout</string> -->
<string name="pref_second_layout_none">Nessuno</string> <string name="pref_second_layout_none">Nessuno</string>
<string name="pref_category_typing">Digitando</string> <string name="pref_category_typing">Digitando</string>
@@ -41,8 +42,10 @@
<string name="pref_autocapitalisation_summary">Premi Shift all\'inizio di una frase</string> <string name="pref_autocapitalisation_summary">Premi Shift all\'inizio di una frase</string>
<!-- <string name="pref_switch_input_immediate_title">Switch to the last used keyboard</string> --> <!-- <string name="pref_switch_input_immediate_title">Switch to the last used keyboard</string> -->
<!-- <string name="pref_switch_input_immediate_summary">Behavior of the keyboard-switching key</string> --> <!-- <string name="pref_switch_input_immediate_summary">Behavior of the keyboard-switching key</string> -->
<string name="pref_vibrate_title">Vibrazione</string> <!-- <string name="pref_vibrate_custom">Custom vibration</string> -->
<string name="pref_vibrate_summary">Abilita/Disabilita Vibrazione alla pressione dei tasti</string> <!-- <string name="pref_vibrate_duration_title">Vibration intensity</string> -->
<!-- <string name="pref_pin_entry_enabled_title">Pin entry layout</string> -->
<!-- <string name="pref_pin_entry_enabled_summary">When typing numbers, dates and phone numbers</string> -->
<string name="pref_category_style">Stile</string> <string name="pref_category_style">Stile</string>
<string name="pref_margin_bottom_title">Margine inferiore</string> <string name="pref_margin_bottom_title">Margine inferiore</string>
<string name="pref_keyboard_height_title">Altezza tastiera</string> <string name="pref_keyboard_height_title">Altezza tastiera</string>
@@ -57,6 +60,8 @@
<!-- <string name="pref_theme_e_altblack">Alternative Black</string> --> <!-- <string name="pref_theme_e_altblack">Alternative Black</string> -->
<!-- <string name="pref_theme_e_white">White</string> --> <!-- <string name="pref_theme_e_white">White</string> -->
<!-- <string name="pref_theme_e_epaper">ePaper</string> --> <!-- <string name="pref_theme_e_epaper">ePaper</string> -->
<!-- <string name="pref_theme_e_desert">Desert</string> -->
<!-- <string name="pref_theme_e_jungle">Jungle</string> -->
<string name="pref_swipe_dist_e_very_short">Veramente breve</string> <string name="pref_swipe_dist_e_very_short">Veramente breve</string>
<string name="pref_swipe_dist_e_short">Breve</string> <string name="pref_swipe_dist_e_short">Breve</string>
<string name="pref_swipe_dist_e_default">Normale</string> <string name="pref_swipe_dist_e_default">Normale</string>
@@ -64,14 +69,6 @@
<string name="pref_swipe_dist_e_very_far">Molto distante</string> <string name="pref_swipe_dist_e_very_far">Molto distante</string>
<string name="pref_key_horizontal_space">Spazio orizzontale tra i tasti</string> <string name="pref_key_horizontal_space">Spazio orizzontale tra i tasti</string>
<string name="pref_key_vertical_space">Spazio verticale tra i tasti</string> <string name="pref_key_vertical_space">Spazio verticale tra i tasti</string>
<!-- <string name="pref_category_advanced">Advanced</string> -->
<!-- <string name="pref_custom_layout_title">Custom layout</string> -->
<!-- <string name="pref_custom_layout_summary">See the source code. This option is not meant to be used.</string> -->
<!-- <string name="pref_vibration_e_disabled">Disabled</string> -->
<!-- <string name="pref_vibration_e_system">System</string> -->
<!-- <string name="pref_vibration_e_strong">Strong</string> -->
<!-- <string name="pref_vibration_e_medium">Medium</string> -->
<!-- <string name="pref_vibration_e_light">Light</string> -->
<string name="key_action_next">Prossimo</string> <string name="key_action_next">Prossimo</string>
<string name="key_action_done">Fatto</string> <string name="key_action_done">Fatto</string>
<string name="key_action_go">Vai</string> <string name="key_action_go">Vai</string>
@@ -79,7 +76,29 @@
<string name="key_action_search">Cerca</string> <string name="key_action_search">Cerca</string>
<string name="key_action_send">Invia</string> <string name="key_action_send">Invia</string>
<!-- <string name="launcher_button_imesettings">Enable keyboard</string> --> <!-- <string name="launcher_button_imesettings">Enable keyboard</string> -->
<!-- <string name="launcher_button_imepicker">Select keyboard</string> -->
<!-- <string name="launcher_description">This application is a virtual keyboard. Go to the system settings by clicking on the button below and enable Unexpected-Keyboard.</string> --> <!-- <string name="launcher_description">This application is a virtual keyboard. Go to the system settings by clicking on the button below and enable Unexpected-Keyboard.</string> -->
<!-- <string name="launcher_sourcecode">This is an free and open source application. You can find the source code or report bugs on <a href="https://github.com/Julow/Unexpected-Keyboard/">Github</a>.</string> --> <!-- <string name="launcher_sourcecode">This is an free and open source application. You can find the source code or report bugs on Github.</string> -->
<!-- <string name="launcher_tryhere">After enabling, you can try the keyboard here:</string> --> <!-- <string name="launcher_tryhere">After enabling, you can try the keyboard here:</string> -->
<!-- <string name="key_descr_capslock">Caps lock</string> -->
<!-- <string name="key_descr_switch_greekmath">Greek &amp; math symbols</string> -->
<!-- <string name="key_descr_change_method">Switch keyboard</string> -->
<!-- <string name="key_descr_voice_typing">Voice typing</string> -->
<!-- <string name="key_descr_copy">Copy</string> -->
<!-- <string name="key_descr_paste">Paste</string> -->
<!-- <string name="key_descr_cut">Cut</string> -->
<!-- <string name="key_descr_selectAll">Select all</string> -->
<!-- <string name="key_descr_shareText">Share text</string> -->
<!-- <string name="key_descr_pasteAsPlainText">Paste as plain text</string> -->
<!-- <string name="key_descr_undo">Undo</string> -->
<!-- <string name="key_descr_redo">Redo</string> -->
<!-- <string name="key_descr_ª">Ordinal Indicator</string> -->
<!-- <string name="key_descr_º">Ordinal Indicator</string> -->
<!-- <string name="key_descr_superscript">Superscript</string> -->
<!-- <string name="key_descr_subscript">Subscript</string> -->
<!-- <string name="key_descr_page_up">Page Up</string> -->
<!-- <string name="key_descr_page_down">Page Down</string> -->
<!-- <string name="key_descr_home">Home</string> -->
<!-- <string name="key_descr_end">End</string> -->
<!-- <string name="pref_category_advanced">Advanced</string> -->
</resources> </resources>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<!-- <string name="app_name" product="debug">Unexpected Keyboard (debug)</string> --> <!-- <string name="app_name_release">Unexpected Keyboard</string> -->
<!-- <string name="app_name" product="default">Unexpected Keyboard</string> --> <!-- <string name="app_name_debug">Unexpected Keyboard (Debug)</string> -->
<string name="settings_activity_label">Unexpected Keyboard 설정</string> <string name="settings_activity_label">Unexpected Keyboard 설정</string>
<!-- <string name="pref_portrait">In portrait mode</string> --> <!-- <string name="pref_portrait">In portrait mode</string> -->
<!-- <string name="pref_landscape">In landscape mode</string> --> <!-- <string name="pref_landscape">In landscape mode</string> -->
@@ -10,13 +10,12 @@
<!-- <string name="pref_keyboard_opacity">Adjust keyboard background opacity</string> --> <!-- <string name="pref_keyboard_opacity">Adjust keyboard background opacity</string> -->
<!-- <string name="pref_key_opacity">Adjust key opacity</string> --> <!-- <string name="pref_key_opacity">Adjust key opacity</string> -->
<!-- <string name="pref_key_activated_opacity">Adjust pressed key opacity</string> --> <!-- <string name="pref_key_activated_opacity">Adjust pressed key opacity</string> -->
<string name="pref_layout_title">키보드 레이아웃 변경</string>
<string name="pref_layout_e_system">시스템 세팅</string> <string name="pref_layout_e_system">시스템 세팅</string>
<!-- <string name="pref_layout_e_custom">Custom layout</string> --> <!-- <string name="pref_layout_e_custom">Custom layout</string> -->
<string name="pref_accents_title">악센트</string> <!-- <string name="pref_layouts_add">Add an alternate layout</string> -->
<string name="pref_accents_e_all_installed">설치된 모든 언어의 악센트 표시</string> <!-- <string name="pref_layouts_item">Layout %1$d: %2$s</string> -->
<string name="pref_accents_e_selected">선택한 언어의 악센트만 표시</string> <!-- <string name="pref_layouts_remove_custom">Remove layout</string> -->
<string name="pref_accents_e_none">모든 언어의 악센트 숨기기</string> <!-- <string name="pref_custom_layout_title">Custom layout</string> -->
<!-- <string name="pref_show_numpad_title">Show NumPad</string> --> <!-- <string name="pref_show_numpad_title">Show NumPad</string> -->
<!-- <string name="pref_show_numpad_never">Never</string> --> <!-- <string name="pref_show_numpad_never">Never</string> -->
<!-- <string name="pref_show_numpad_landscape">Only in landscape mode</string> --> <!-- <string name="pref_show_numpad_landscape">Only in landscape mode</string> -->
@@ -27,6 +26,8 @@
<!-- <string name="pref_numpad_layout_e_high_first">High digits first</string> --> <!-- <string name="pref_numpad_layout_e_high_first">High digits first</string> -->
<!-- <string name="pref_numpad_layout_e_low_first">Low digits first</string> --> <!-- <string name="pref_numpad_layout_e_low_first">Low digits first</string> -->
<!-- <string name="pref_extra_keys_title">Add keys to the keyboard</string> --> <!-- <string name="pref_extra_keys_title">Add keys to the keyboard</string> -->
<!-- <string name="pref_extra_keys_custom">Add custom keys</string> -->
<!-- <string name="pref_extra_keys_internal">Select keys to add to the keyboard</string> -->
<!-- <string name="pref_second_layout_title">Secondary layout</string> --> <!-- <string name="pref_second_layout_title">Secondary layout</string> -->
<!-- <string name="pref_second_layout_none">None</string> --> <!-- <string name="pref_second_layout_none">None</string> -->
<string name="pref_category_typing">타자</string> <string name="pref_category_typing">타자</string>
@@ -41,8 +42,10 @@
<!-- <string name="pref_autocapitalisation_summary">Press Shift at the beginning of a sentence</string> --> <!-- <string name="pref_autocapitalisation_summary">Press Shift at the beginning of a sentence</string> -->
<!-- <string name="pref_switch_input_immediate_title">Switch to the last used keyboard</string> --> <!-- <string name="pref_switch_input_immediate_title">Switch to the last used keyboard</string> -->
<!-- <string name="pref_switch_input_immediate_summary">Behavior of the keyboard-switching key</string> --> <!-- <string name="pref_switch_input_immediate_summary">Behavior of the keyboard-switching key</string> -->
<string name="pref_vibrate_title">진동</string> <!-- <string name="pref_vibrate_custom">Custom vibration</string> -->
<string name="pref_vibrate_summary">키 누를 때 진동 키거/끄기</string> <!-- <string name="pref_vibrate_duration_title">Vibration intensity</string> -->
<!-- <string name="pref_pin_entry_enabled_title">Pin entry layout</string> -->
<!-- <string name="pref_pin_entry_enabled_summary">When typing numbers, dates and phone numbers</string> -->
<string name="pref_category_style">스타일</string> <string name="pref_category_style">스타일</string>
<string name="pref_margin_bottom_title">아래 넓이</string> <string name="pref_margin_bottom_title">아래 넓이</string>
<string name="pref_keyboard_height_title">키보드 높이</string> <string name="pref_keyboard_height_title">키보드 높이</string>
@@ -57,6 +60,8 @@
<!-- <string name="pref_theme_e_altblack">Alternative Black</string> --> <!-- <string name="pref_theme_e_altblack">Alternative Black</string> -->
<!-- <string name="pref_theme_e_white">White</string> --> <!-- <string name="pref_theme_e_white">White</string> -->
<!-- <string name="pref_theme_e_epaper">ePaper</string> --> <!-- <string name="pref_theme_e_epaper">ePaper</string> -->
<!-- <string name="pref_theme_e_desert">Desert</string> -->
<!-- <string name="pref_theme_e_jungle">Jungle</string> -->
<string name="pref_swipe_dist_e_very_short">매우 짧음</string> <string name="pref_swipe_dist_e_very_short">매우 짧음</string>
<string name="pref_swipe_dist_e_short">짧음</string> <string name="pref_swipe_dist_e_short">짧음</string>
<string name="pref_swipe_dist_e_default">보통</string> <string name="pref_swipe_dist_e_default">보통</string>
@@ -64,14 +69,6 @@
<string name="pref_swipe_dist_e_very_far">매우 넓음</string> <string name="pref_swipe_dist_e_very_far">매우 넓음</string>
<string name="pref_key_horizontal_space">키보드 양 옆 간격</string> <string name="pref_key_horizontal_space">키보드 양 옆 간격</string>
<string name="pref_key_vertical_space">키보드 세로 간격</string> <string name="pref_key_vertical_space">키보드 세로 간격</string>
<!-- <string name="pref_category_advanced">Advanced</string> -->
<!-- <string name="pref_custom_layout_title">Custom layout</string> -->
<!-- <string name="pref_custom_layout_summary">See the source code. This option is not meant to be used.</string> -->
<!-- <string name="pref_vibration_e_disabled">Disabled</string> -->
<!-- <string name="pref_vibration_e_system">System</string> -->
<!-- <string name="pref_vibration_e_strong">Strong</string> -->
<!-- <string name="pref_vibration_e_medium">Medium</string> -->
<!-- <string name="pref_vibration_e_light">Light</string> -->
<string name="key_action_next">다음</string> <string name="key_action_next">다음</string>
<string name="key_action_done">확인</string> <string name="key_action_done">확인</string>
<string name="key_action_go">Go</string> <string name="key_action_go">Go</string>
@@ -79,7 +76,29 @@
<string name="key_action_search">검색</string> <string name="key_action_search">검색</string>
<string name="key_action_send">보내기</string> <string name="key_action_send">보내기</string>
<!-- <string name="launcher_button_imesettings">Enable keyboard</string> --> <!-- <string name="launcher_button_imesettings">Enable keyboard</string> -->
<!-- <string name="launcher_button_imepicker">Select keyboard</string> -->
<!-- <string name="launcher_description">This application is a virtual keyboard. Go to the system settings by clicking on the button below and enable Unexpected-Keyboard.</string> --> <!-- <string name="launcher_description">This application is a virtual keyboard. Go to the system settings by clicking on the button below and enable Unexpected-Keyboard.</string> -->
<!-- <string name="launcher_sourcecode">This is an free and open source application. You can find the source code or report bugs on <a href="https://github.com/Julow/Unexpected-Keyboard/">Github</a>.</string> --> <!-- <string name="launcher_sourcecode">This is an free and open source application. You can find the source code or report bugs on Github.</string> -->
<!-- <string name="launcher_tryhere">After enabling, you can try the keyboard here:</string> --> <!-- <string name="launcher_tryhere">After enabling, you can try the keyboard here:</string> -->
<!-- <string name="key_descr_capslock">Caps lock</string> -->
<!-- <string name="key_descr_switch_greekmath">Greek &amp; math symbols</string> -->
<!-- <string name="key_descr_change_method">Switch keyboard</string> -->
<!-- <string name="key_descr_voice_typing">Voice typing</string> -->
<!-- <string name="key_descr_copy">Copy</string> -->
<!-- <string name="key_descr_paste">Paste</string> -->
<!-- <string name="key_descr_cut">Cut</string> -->
<!-- <string name="key_descr_selectAll">Select all</string> -->
<!-- <string name="key_descr_shareText">Share text</string> -->
<!-- <string name="key_descr_pasteAsPlainText">Paste as plain text</string> -->
<!-- <string name="key_descr_undo">Undo</string> -->
<!-- <string name="key_descr_redo">Redo</string> -->
<!-- <string name="key_descr_ª">Ordinal Indicator</string> -->
<!-- <string name="key_descr_º">Ordinal Indicator</string> -->
<!-- <string name="key_descr_superscript">Superscript</string> -->
<!-- <string name="key_descr_subscript">Subscript</string> -->
<!-- <string name="key_descr_page_up">Page Up</string> -->
<!-- <string name="key_descr_page_down">Page Down</string> -->
<!-- <string name="key_descr_home">Home</string> -->
<!-- <string name="key_descr_end">End</string> -->
<!-- <string name="pref_category_advanced">Advanced</string> -->
</resources> </resources>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="app_name" product="debug">Unexpected Keyboard (atkļūdošana)</string> <string name="app_name_release">Unexpected Keyboard</string>
<string name="app_name" product="default">Unexpected Keyboard</string> <string name="app_name_debug">Unexpected Keyboard (atkļūdošana)</string>
<string name="settings_activity_label">Unexpected Keyboard iestatījumi</string> <string name="settings_activity_label">Unexpected Keyboard iestatījumi</string>
<string name="pref_portrait">Stateniski</string> <string name="pref_portrait">Stateniski</string>
<string name="pref_landscape">Guleniski</string> <string name="pref_landscape">Guleniski</string>
@@ -10,13 +10,12 @@
<string name="pref_keyboard_opacity">Pielāgot tastatūras fona necaurredzamību</string> <string name="pref_keyboard_opacity">Pielāgot tastatūras fona necaurredzamību</string>
<string name="pref_key_opacity">Pielāgot taustiņu necaurredzamību</string> <string name="pref_key_opacity">Pielāgot taustiņu necaurredzamību</string>
<string name="pref_key_activated_opacity">Pielāgot piespiesta taustiņa necaurredzamību</string> <string name="pref_key_activated_opacity">Pielāgot piespiesta taustiņa necaurredzamību</string>
<string name="pref_layout_title">Mainīt tastatūras izkārtojumu</string>
<string name="pref_layout_e_system">Ierīces iestatījumi</string> <string name="pref_layout_e_system">Ierīces iestatījumi</string>
<string name="pref_layout_e_custom">Pielāgots izkārtojums</string> <string name="pref_layout_e_custom">Pielāgots izkārtojums</string>
<string name="pref_accents_title">Uzsvara zīmes</string> <string name="pref_layouts_add">Pievienot aizstājējizkārtojumu</string>
<string name="pref_accents_e_all_installed">Rādīt uzsvara zīmes visām uzstādītajām valodām</string> <string name="pref_layouts_item">Izkārtojums %1$d: %2$s</string>
<string name="pref_accents_e_selected">Rādīt uzsvara zīmes tikai atlasītajām valodām</string> <string name="pref_layouts_remove_custom">Noņemt izkārtojumu</string>
<string name="pref_accents_e_none">Paslēpt uzsvara zīmes</string> <string name="pref_custom_layout_title">Pielāgots izkārtojums</string>
<string name="pref_show_numpad_title">Rādīt ciparnīcu</string> <string name="pref_show_numpad_title">Rādīt ciparnīcu</string>
<string name="pref_show_numpad_never">Nekad</string> <string name="pref_show_numpad_never">Nekad</string>
<string name="pref_show_numpad_landscape">Tikai guleniskajā skatā</string> <string name="pref_show_numpad_landscape">Tikai guleniskajā skatā</string>
@@ -27,6 +26,8 @@
<string name="pref_numpad_layout_e_high_first">Vispirms lielākie cipari</string> <string name="pref_numpad_layout_e_high_first">Vispirms lielākie cipari</string>
<string name="pref_numpad_layout_e_low_first">Vispirms mazākie cipari</string> <string name="pref_numpad_layout_e_low_first">Vispirms mazākie cipari</string>
<string name="pref_extra_keys_title">Pievienot tastatūrai taustiņus</string> <string name="pref_extra_keys_title">Pievienot tastatūrai taustiņus</string>
<string name="pref_extra_keys_custom">Pievienot pielāgotus taustiņus</string>
<string name="pref_extra_keys_internal">Atlasīt taustiņus, ko pievienot tastatūrai</string>
<string name="pref_second_layout_title">Otrējais izkārtojums</string> <string name="pref_second_layout_title">Otrējais izkārtojums</string>
<string name="pref_second_layout_none">Neviens</string> <string name="pref_second_layout_none">Neviens</string>
<string name="pref_category_typing">Rakstīšana</string> <string name="pref_category_typing">Rakstīšana</string>
@@ -41,8 +42,10 @@
<string name="pref_autocapitalisation_summary">Piespiest Shift teikuma sākumā</string> <string name="pref_autocapitalisation_summary">Piespiest Shift teikuma sākumā</string>
<string name="pref_switch_input_immediate_title">Pārslēgties uz pēdējo izmantoto tastatūru</string> <string name="pref_switch_input_immediate_title">Pārslēgties uz pēdējo izmantoto tastatūru</string>
<string name="pref_switch_input_immediate_summary">Tastatūras pārslēgšanas taustiņa uzvedība</string> <string name="pref_switch_input_immediate_summary">Tastatūras pārslēgšanas taustiņa uzvedība</string>
<string name="pref_vibrate_title">Trīcēšana</string> <!-- <string name="pref_vibrate_custom">Custom vibration</string> -->
<string name="pref_vibrate_summary">Iespējot/atspējot taustiņa piespiešanas trīcēšanu</string> <!-- <string name="pref_vibrate_duration_title">Vibration intensity</string> -->
<string name="pref_pin_entry_enabled_title">Piespraust ievadīšanas izkārtojumu</string>
<string name="pref_pin_entry_enabled_summary">Kad ievada skaitļus, datumus un tālruņa numurus</string>
<string name="pref_category_style">Izskata pielāgojumi</string> <string name="pref_category_style">Izskata pielāgojumi</string>
<string name="pref_margin_bottom_title">Apakšējā apmale</string> <string name="pref_margin_bottom_title">Apakšējā apmale</string>
<string name="pref_keyboard_height_title">Tastatūras augstums</string> <string name="pref_keyboard_height_title">Tastatūras augstums</string>
@@ -57,6 +60,8 @@
<string name="pref_theme_e_altblack">Citādi melns</string> <string name="pref_theme_e_altblack">Citādi melns</string>
<string name="pref_theme_e_white">Balts</string> <string name="pref_theme_e_white">Balts</string>
<string name="pref_theme_e_epaper">ePapīrs</string> <string name="pref_theme_e_epaper">ePapīrs</string>
<string name="pref_theme_e_desert">Tuksnesis</string>
<string name="pref_theme_e_jungle">Džungļi</string>
<string name="pref_swipe_dist_e_very_short">Ļoti tuvs</string> <string name="pref_swipe_dist_e_very_short">Ļoti tuvs</string>
<string name="pref_swipe_dist_e_short">Tuvs</string> <string name="pref_swipe_dist_e_short">Tuvs</string>
<string name="pref_swipe_dist_e_default">Vidējs</string> <string name="pref_swipe_dist_e_default">Vidējs</string>
@@ -64,22 +69,38 @@
<string name="pref_swipe_dist_e_very_far">Ļoti tāls</string> <string name="pref_swipe_dist_e_very_far">Ļoti tāls</string>
<string name="pref_key_horizontal_space">Līmeniskais attālums starp taustiņiem</string> <string name="pref_key_horizontal_space">Līmeniskais attālums starp taustiņiem</string>
<string name="pref_key_vertical_space">Stateniskais attālums starp taustiņiem</string> <string name="pref_key_vertical_space">Stateniskais attālums starp taustiņiem</string>
<string name="pref_category_advanced">Papildu</string>
<string name="pref_custom_layout_title">Pielāgots izkārtojums</string>
<string name="pref_custom_layout_summary">Skatīt pirmkodu. Šī iespēja nav paredzēta izmantošanai.</string>
<!-- <string name="pref_vibration_e_disabled">Disabled</string> -->
<!-- <string name="pref_vibration_e_system">System</string> -->
<!-- <string name="pref_vibration_e_strong">Strong</string> -->
<!-- <string name="pref_vibration_e_medium">Medium</string> -->
<!-- <string name="pref_vibration_e_light">Light</string> -->
<string name="key_action_next">Nākamais</string> <string name="key_action_next">Nākamais</string>
<string name="key_action_done">Darīts</string> <string name="key_action_done">Darīts</string>
<string name="key_action_go">Aiziet</string> <string name="key_action_go">Aiziet</string>
<string name="key_action_prev">Iepriekšējais</string> <string name="key_action_prev">Iepriekšējais</string>
<string name="key_action_search">Meklēt</string> <string name="key_action_search">Meklēt</string>
<string name="key_action_send">Sūtīt</string> <string name="key_action_send">Sūtīt</string>
<!-- <string name="launcher_button_imesettings">Enable keyboard</string> --> <string name="launcher_button_imesettings">Iespējot tastatūru</string>
<!-- <string name="launcher_description">This application is a virtual keyboard. Go to the system settings by clicking on the button below and enable Unexpected-Keyboard.</string> --> <string name="launcher_button_imepicker">Izvēlēties tastatūru</string>
<!-- <string name="launcher_sourcecode">This is an free and open source application. You can find the source code or report bugs on <a href="https://github.com/Julow/Unexpected-Keyboard/">Github</a>.</string> --> <string name="launcher_description">Šī lietotne ir virtuālā tastatūra.
<!-- <string name="launcher_tryhere">After enabling, you can try the keyboard here:</string> --> Ar zemāk esošo pogu var atvērt sistēmas iestatījumus un iespējot Unexpected Keyboard.</string>
<string name="launcher_sourcecode">Šī ir bezmaksas un atvērtā pirmkoda lietotne.
GitHub var atrast pirmkodu un ziņot par nepilnībām.</string>
<string name="launcher_tryhere">Pēc iespējošanas šeit var izmēģināt tastatūru:</string>
<string name="key_descr_capslock">Burtslēgs</string>
<string name="key_descr_switch_greekmath">Grieķu un matemātikas rakstzīmes</string>
<!-- <string name="key_descr_change_method">Switch keyboard</string> -->
<string name="key_descr_voice_typing">Rakstīšana ar balsi</string>
<string name="key_descr_copy">Ievietot starpliktuvē</string>
<string name="key_descr_paste">Ielīmēt</string>
<string name="key_descr_cut">Izgriezt</string>
<string name="key_descr_selectAll">Iezīmēt visu</string>
<string name="key_descr_shareText">Kopīgot tekstu</string>
<string name="key_descr_pasteAsPlainText">Ielīmēt kā vienkāršu tekstu</string>
<string name="key_descr_undo">Atsaukt</string>
<string name="key_descr_redo">Atatsaukt</string>
<string name="key_descr_ª">Kārtas rādītājs</string>
<string name="key_descr_º">Kārtas rādītājs</string>
<string name="key_descr_superscript">Augšraksts</string>
<string name="key_descr_subscript">Apakšraksts</string>
<string name="key_descr_page_up">Augšupšķirt</string>
<string name="key_descr_page_down">Lejupšķirt</string>
<string name="key_descr_home">Sākums</string>
<string name="key_descr_end">Beigas</string>
<string name="pref_category_advanced">Papildu</string>
</resources> </resources>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="appTheme" parent="@android:style/Theme.Material"/>
</resources>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="app_name" product="debug">Unexpected Keyboard (debug)</string> <string name="app_name_release">Unexpected Keyboard</string>
<string name="app_name" product="default">Unexpected Keyboard</string> <string name="app_name_debug">Unexpected Keyboard (debug)</string>
<string name="settings_activity_label">Ustawienia Unexpected Keyboard</string> <string name="settings_activity_label">Ustawienia Unexpected Keyboard</string>
<string name="pref_portrait">W widoku pionowym</string> <string name="pref_portrait">W widoku pionowym</string>
<string name="pref_landscape">W widoku poziomym</string> <string name="pref_landscape">W widoku poziomym</string>
@@ -10,13 +10,12 @@
<string name="pref_keyboard_opacity">Nieprzezroczystość tła klawiatury</string> <string name="pref_keyboard_opacity">Nieprzezroczystość tła klawiatury</string>
<string name="pref_key_opacity">Nieprzezroczystość klawisza</string> <string name="pref_key_opacity">Nieprzezroczystość klawisza</string>
<string name="pref_key_activated_opacity">Nieprzezroczystość naciśniętego klawisza</string> <string name="pref_key_activated_opacity">Nieprzezroczystość naciśniętego klawisza</string>
<string name="pref_layout_title">Zmień układ klawiatury</string>
<string name="pref_layout_e_system">Systemowy</string> <string name="pref_layout_e_system">Systemowy</string>
<string name="pref_layout_e_custom">Własny układ</string> <string name="pref_layout_e_custom">Własny układ</string>
<string name="pref_accents_title">Znaki diakrytyczne</string> <string name="pref_layouts_add">Dodaj dodatkowy układ</string>
<string name="pref_accents_e_all_installed">Pokaż znaki diakryt. dla wszystkich zainstalowanych języków</string> <string name="pref_layouts_item">Układ %1$d: %2$s</string>
<string name="pref_accents_e_selected">Pokaż znaki diakryt. tylko dla wybranego języka</string> <string name="pref_layouts_remove_custom">Usuń układ</string>
<string name="pref_accents_e_none">Ukryj znaki diakrytyczne</string> <string name="pref_custom_layout_title">Własny układ</string>
<string name="pref_show_numpad_title">Pokaż klawiaturę numeryczną</string> <string name="pref_show_numpad_title">Pokaż klawiaturę numeryczną</string>
<string name="pref_show_numpad_never">Nigdy</string> <string name="pref_show_numpad_never">Nigdy</string>
<string name="pref_show_numpad_landscape">Tylko w orientacji poziomej</string> <string name="pref_show_numpad_landscape">Tylko w orientacji poziomej</string>
@@ -27,6 +26,8 @@
<string name="pref_numpad_layout_e_high_first">Od największej cyfry</string> <string name="pref_numpad_layout_e_high_first">Od największej cyfry</string>
<string name="pref_numpad_layout_e_low_first">Od najmniejszej cyfry</string> <string name="pref_numpad_layout_e_low_first">Od najmniejszej cyfry</string>
<string name="pref_extra_keys_title">Dodaj klawisze do klawiatury</string> <string name="pref_extra_keys_title">Dodaj klawisze do klawiatury</string>
<string name="pref_extra_keys_custom">Dodaj niestandardowe klawisze</string>
<string name="pref_extra_keys_internal">Wybierz klawisze, które chcesz dodać do klawiatury</string>
<string name="pref_second_layout_title">Drugi układ</string> <string name="pref_second_layout_title">Drugi układ</string>
<string name="pref_second_layout_none">Żaden</string> <string name="pref_second_layout_none">Żaden</string>
<string name="pref_category_typing">Pisanie</string> <string name="pref_category_typing">Pisanie</string>
@@ -41,8 +42,10 @@
<string name="pref_autocapitalisation_summary">Naciśnij Shift na początku zdania</string> <string name="pref_autocapitalisation_summary">Naciśnij Shift na początku zdania</string>
<string name="pref_switch_input_immediate_title">Przełącz na ostatnio używaną klawiaturę</string> <string name="pref_switch_input_immediate_title">Przełącz na ostatnio używaną klawiaturę</string>
<string name="pref_switch_input_immediate_summary">Działanie klawisza przełączającego klawiaturę</string> <string name="pref_switch_input_immediate_summary">Działanie klawisza przełączającego klawiaturę</string>
<string name="pref_vibrate_title">Wibracje</string> <!-- <string name="pref_vibrate_custom">Custom vibration</string> -->
<string name="pref_vibrate_summary">Wł./wył. wibrację przy naciśnięciu klawisza</string> <!-- <string name="pref_vibrate_duration_title">Vibration intensity</string> -->
<string name="pref_pin_entry_enabled_title">Układ klawiatury PIN</string>
<string name="pref_pin_entry_enabled_summary">Podczas wpisywania liczb, dat i numerów telefonu</string>
<string name="pref_category_style">Styl</string> <string name="pref_category_style">Styl</string>
<string name="pref_margin_bottom_title">Margines dolny</string> <string name="pref_margin_bottom_title">Margines dolny</string>
<string name="pref_keyboard_height_title">Wysokość klawiatury</string> <string name="pref_keyboard_height_title">Wysokość klawiatury</string>
@@ -57,6 +60,8 @@
<string name="pref_theme_e_altblack">Alternatywny Czarny</string> <string name="pref_theme_e_altblack">Alternatywny Czarny</string>
<string name="pref_theme_e_white">Biały</string> <string name="pref_theme_e_white">Biały</string>
<string name="pref_theme_e_epaper">e-paper</string> <string name="pref_theme_e_epaper">e-paper</string>
<string name="pref_theme_e_desert">Pustynny</string>
<string name="pref_theme_e_jungle">Dżunglowy</string>
<string name="pref_swipe_dist_e_very_short">Bardzo mała</string> <string name="pref_swipe_dist_e_very_short">Bardzo mała</string>
<string name="pref_swipe_dist_e_short">Mała</string> <string name="pref_swipe_dist_e_short">Mała</string>
<string name="pref_swipe_dist_e_default">Normalna</string> <string name="pref_swipe_dist_e_default">Normalna</string>
@@ -64,14 +69,6 @@
<string name="pref_swipe_dist_e_very_far">Bardzo duża</string> <string name="pref_swipe_dist_e_very_far">Bardzo duża</string>
<string name="pref_key_horizontal_space">Odległość pomiędzy klawiszami w poziomie</string> <string name="pref_key_horizontal_space">Odległość pomiędzy klawiszami w poziomie</string>
<string name="pref_key_vertical_space">Odległość pomiędzy klawiszami w pionie</string> <string name="pref_key_vertical_space">Odległość pomiędzy klawiszami w pionie</string>
<string name="pref_category_advanced">Zaawansowane</string>
<string name="pref_custom_layout_title">Własny układ</string>
<string name="pref_custom_layout_summary">Zobacz kod źródłowy. Ta opcja nie jest przeznaczona do użycia.</string>
<string name="pref_vibration_e_disabled">Wyłączone</string>
<string name="pref_vibration_e_system">Systemowe</string>
<string name="pref_vibration_e_strong">Silne</string>
<string name="pref_vibration_e_medium">Normalne</string>
<string name="pref_vibration_e_light">Słabe</string>
<string name="key_action_next">Dalej</string> <string name="key_action_next">Dalej</string>
<string name="key_action_done">OK</string> <string name="key_action_done">OK</string>
<string name="key_action_go">Przejdź</string> <string name="key_action_go">Przejdź</string>
@@ -79,7 +76,29 @@
<string name="key_action_search">Szukaj</string> <string name="key_action_search">Szukaj</string>
<string name="key_action_send">Wyślij</string> <string name="key_action_send">Wyślij</string>
<string name="launcher_button_imesettings">Włącz klawiaturę</string> <string name="launcher_button_imesettings">Włącz klawiaturę</string>
<string name="launcher_button_imepicker">Wybierz klawiaturę</string>
<string name="launcher_description">Ta aplikacja jest klawiaturą ekranową. Naciśnij poniższy przycisk, aby przejść do ustawień systemu i włącz Unexpected-Keyboard.</string> <string name="launcher_description">Ta aplikacja jest klawiaturą ekranową. Naciśnij poniższy przycisk, aby przejść do ustawień systemu i włącz Unexpected-Keyboard.</string>
<string name="launcher_sourcecode">Jest to darmowa aplikacja o otwartym kodzie źródłowym. Możesz zobaczyć kod źródłowy oraz zgłosić błedy na <a href="https://github.com/Julow/Unexpected-Keyboard/">Githubie</a>.</string> <string name="launcher_sourcecode">Jest to darmowa aplikacja o otwartym kodzie źródłowym. Możesz zobaczyć kod źródłowy oraz zgłosić błedy na Githubie.</string>
<string name="launcher_tryhere">Po jej włączeniu, możesz wypróbować klawiaturę tutaj:</string> <string name="launcher_tryhere">Po jej włączeniu, możesz wypróbować klawiaturę tutaj:</string>
<string name="key_descr_capslock">Caps lock</string>
<string name="key_descr_switch_greekmath">Symbole greckie i matematyczne</string>
<!-- <string name="key_descr_change_method">Switch keyboard</string> -->
<string name="key_descr_voice_typing">Pisanie głosowe</string>
<string name="key_descr_copy">Kopiuj</string>
<string name="key_descr_paste">Wklej</string>
<string name="key_descr_cut">Wytnij</string>
<string name="key_descr_selectAll">Zaznacz wszystko</string>
<string name="key_descr_shareText">Udostępnij tekst</string>
<string name="key_descr_pasteAsPlainText">Wklej sam tekst</string>
<string name="key_descr_undo">Cofnij</string>
<string name="key_descr_redo">Ponów</string>
<string name="key_descr_ª">Wskaźnik porządkowy (żeński)</string>
<string name="key_descr_º">Wskaźnik porządkowy (męski)</string>
<string name="key_descr_superscript">Indeks górny</string>
<string name="key_descr_subscript">Indeks dolny</string>
<string name="key_descr_page_up">Page Up</string>
<string name="key_descr_page_down">Page Down</string>
<string name="key_descr_home">Home</string>
<string name="key_descr_end">End</string>
<string name="pref_category_advanced">Zaawansowane</string>
</resources> </resources>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="app_name" product="debug">Teclado Unexpected</string> <string name="app_name_release">Teclado Unexpected</string>
<string name="app_name" product="default">Teclado Unexpected</string> <string name="app_name_debug">Teclado Unexpected</string>
<string name="settings_activity_label">Configurações</string> <string name="settings_activity_label">Configurações</string>
<string name="pref_portrait">No modo retrato</string> <string name="pref_portrait">No modo retrato</string>
<string name="pref_landscape">No modo paisagem</string> <string name="pref_landscape">No modo paisagem</string>
@@ -10,13 +10,12 @@
<string name="pref_keyboard_opacity">Ajustar opacidade do fundo do teclado</string> <string name="pref_keyboard_opacity">Ajustar opacidade do fundo do teclado</string>
<string name="pref_key_opacity">Ajustar opacidade das teclas</string> <string name="pref_key_opacity">Ajustar opacidade das teclas</string>
<string name="pref_key_activated_opacity">Ajustar opacidade das teclas pressionadas</string> <string name="pref_key_activated_opacity">Ajustar opacidade das teclas pressionadas</string>
<string name="pref_layout_title">Mudar layout do teclado</string>
<string name="pref_layout_e_system">Mesmo do sistema</string> <string name="pref_layout_e_system">Mesmo do sistema</string>
<string name="pref_layout_e_custom">Layout personalizado</string> <string name="pref_layout_e_custom">Layout personalizado</string>
<string name="pref_accents_title">Acentos</string> <string name="pref_layouts_add">Adicione um layout alternativo</string>
<string name="pref_accents_e_all_installed">Mostrar acentos para todos os idiomas instalados</string> <string name="pref_layouts_item">Layout %1$d: %2$s</string>
<string name="pref_accents_e_selected">Mostrar acentos só para o idioma selecionado</string> <string name="pref_layouts_remove_custom">Remover layout</string>
<string name="pref_accents_e_none">Ocultar acentos</string> <string name="pref_custom_layout_title">Layout personalizado</string>
<string name="pref_show_numpad_title">Mostrar Teclado Numérico</string> <string name="pref_show_numpad_title">Mostrar Teclado Numérico</string>
<string name="pref_show_numpad_never">Nunca</string> <string name="pref_show_numpad_never">Nunca</string>
<string name="pref_show_numpad_landscape">Somente no modo paisagem</string> <string name="pref_show_numpad_landscape">Somente no modo paisagem</string>
@@ -27,6 +26,8 @@
<string name="pref_numpad_layout_e_high_first">Dígitos maiores primeiro</string> <string name="pref_numpad_layout_e_high_first">Dígitos maiores primeiro</string>
<string name="pref_numpad_layout_e_low_first">Dígitos menores primeiro</string> <string name="pref_numpad_layout_e_low_first">Dígitos menores primeiro</string>
<string name="pref_extra_keys_title">Adicionar teclas ao teclado</string> <string name="pref_extra_keys_title">Adicionar teclas ao teclado</string>
<string name="pref_extra_keys_custom">Adicionar teclas customizadas</string>
<string name="pref_extra_keys_internal">Selecione teclas para serem adicionadas ao teclado</string>
<string name="pref_second_layout_title">Layout secundário</string> <string name="pref_second_layout_title">Layout secundário</string>
<string name="pref_second_layout_none">Nenhum</string> <string name="pref_second_layout_none">Nenhum</string>
<string name="pref_category_typing">Digitação</string> <string name="pref_category_typing">Digitação</string>
@@ -34,15 +35,17 @@
<string name="pref_swipe_dist_summary">Distância até acionar os cantos das teclas (%s)</string> <string name="pref_swipe_dist_summary">Distância até acionar os cantos das teclas (%s)</string>
<string name="pref_long_timeout_title">Tempo até repetir tecla</string> <string name="pref_long_timeout_title">Tempo até repetir tecla</string>
<string name="pref_long_interval_title">Intervalo de repetição de tecla</string> <string name="pref_long_interval_title">Intervalo de repetição de tecla</string>
<string name="pref_lock_double_tap_title">Tecle duas vezes no shift para caixa alta</string> <string name="pref_lock_double_tap_title">Tecle duas vezes no shift para travá-lo acionado</string>
<string name="pref_lock_double_tap_summary">Ao invés de apertar e segurar por um tempo</string> <string name="pref_lock_double_tap_summary">Ao invés de apertar e segurar por um tempo</string>
<string name="pref_category_behavior">Comportamento</string> <string name="pref_category_behavior">Comportamento</string>
<string name="pref_autocapitalisation_title">Capitalização automática</string> <string name="pref_autocapitalisation_title">Capitalização automática</string>
<string name="pref_autocapitalisation_summary">Aciona o shift no início de cada frase</string> <string name="pref_autocapitalisation_summary">Aciona o shift no início de cada frase</string>
<string name="pref_switch_input_immediate_title">Alternar para o último teclado usado</string> <string name="pref_switch_input_immediate_title">Alternar para o último teclado usado</string>
<string name="pref_switch_input_immediate_summary">Comportamento da tecla de troca de teclado</string> <string name="pref_switch_input_immediate_summary">Comportamento da tecla de troca de teclado</string>
<string name="pref_vibrate_title">Vibração</string> <string name="pref_vibrate_custom">Vibração personalizada</string>
<string name="pref_vibrate_summary">Ativar/desativar vibração ao digitar</string> <string name="pref_vibrate_duration_title">Intensidade da vibração</string>
<string name="pref_pin_entry_enabled_title">Layout PIN</string>
<string name="pref_pin_entry_enabled_summary">Quando digitando números, datas ou números de telefone</string>
<string name="pref_category_style">Estilo</string> <string name="pref_category_style">Estilo</string>
<string name="pref_margin_bottom_title">Margem inferior</string> <string name="pref_margin_bottom_title">Margem inferior</string>
<string name="pref_keyboard_height_title">Altura do teclado</string> <string name="pref_keyboard_height_title">Altura do teclado</string>
@@ -57,21 +60,15 @@
<string name="pref_theme_e_altblack">Preto Alternativo</string> <string name="pref_theme_e_altblack">Preto Alternativo</string>
<string name="pref_theme_e_white">Branco</string> <string name="pref_theme_e_white">Branco</string>
<string name="pref_theme_e_epaper">Papel Eletrônico</string> <string name="pref_theme_e_epaper">Papel Eletrônico</string>
<string name="pref_swipe_dist_e_very_short">Muito curto</string> <string name="pref_theme_e_desert">Deserto</string>
<string name="pref_theme_e_jungle">Selva</string>
<string name="pref_swipe_dist_e_very_short">Bem curto</string>
<string name="pref_swipe_dist_e_short">Curto</string> <string name="pref_swipe_dist_e_short">Curto</string>
<string name="pref_swipe_dist_e_default">Normal</string> <string name="pref_swipe_dist_e_default">Normal</string>
<string name="pref_swipe_dist_e_far">Longo</string> <string name="pref_swipe_dist_e_far">Longo</string>
<string name="pref_swipe_dist_e_very_far">Muito longo</string> <string name="pref_swipe_dist_e_very_far">Bem longo</string>
<string name="pref_key_horizontal_space">Distância horizontal entre teclas</string> <string name="pref_key_horizontal_space">Distância horizontal entre teclas</string>
<string name="pref_key_vertical_space">Distância vertical entre teclas</string> <string name="pref_key_vertical_space">Distância vertical entre teclas</string>
<string name="pref_category_advanced">Avançado</string>
<string name="pref_custom_layout_title">Layout personalizado</string>
<string name="pref_custom_layout_summary">Veja o código-fonte. Esta opção não deve ser usada.</string>
<!-- <string name="pref_vibration_e_disabled">Disabled</string> -->
<!-- <string name="pref_vibration_e_system">System</string> -->
<!-- <string name="pref_vibration_e_strong">Strong</string> -->
<!-- <string name="pref_vibration_e_medium">Medium</string> -->
<!-- <string name="pref_vibration_e_light">Light</string> -->
<string name="key_action_next">Próximo</string> <string name="key_action_next">Próximo</string>
<string name="key_action_done">Pronto</string> <string name="key_action_done">Pronto</string>
<string name="key_action_go">Ir</string> <string name="key_action_go">Ir</string>
@@ -79,7 +76,29 @@
<string name="key_action_search">Buscar</string> <string name="key_action_search">Buscar</string>
<string name="key_action_send">Enviar</string> <string name="key_action_send">Enviar</string>
<string name="launcher_button_imesettings">Ativar teclado</string> <string name="launcher_button_imesettings">Ativar teclado</string>
<string name="launcher_button_imepicker">Selecionar teclado</string>
<string name="launcher_description">Este app é um teclado virtual. Vá para as configurações do sistema clicando no botão abaixo e ative o Teclado Unexpected.</string> <string name="launcher_description">Este app é um teclado virtual. Vá para as configurações do sistema clicando no botão abaixo e ative o Teclado Unexpected.</string>
<string name="launcher_sourcecode">Este app é gratuito é de código aberto. Você pode consultar o código ou fazer sugestões em <a href="https://github.com/Julow/Unexpected-Keyboard/">Github</a>.</string> <string name="launcher_sourcecode">Este app é gratuito é de código aberto. Você pode consultar o código ou fazer sugestões em Github.</string>
<string name="launcher_tryhere">Após ativar, experimente aqui:</string> <string name="launcher_tryhere">Após ativar, experimente aqui:</string>
<string name="key_descr_capslock">Caps lock</string>
<string name="key_descr_switch_greekmath">Grego &amp; símbolos matemáticos</string>
<string name="key_descr_change_method">Trocar de teclado</string>
<string name="key_descr_voice_typing">Digitação por voz</string>
<string name="key_descr_copy">Copiar</string>
<string name="key_descr_paste">Colar</string>
<string name="key_descr_cut">Recortar</string>
<string name="key_descr_selectAll">Selecionar tudo</string>
<string name="key_descr_shareText">Compartilhar texto</string>
<string name="key_descr_pasteAsPlainText">Colar texto não formatado</string>
<string name="key_descr_undo">Desfazer</string>
<string name="key_descr_redo">Refazer</string>
<string name="key_descr_ª">Indicador Ordinal</string>
<string name="key_descr_º">Indicador Ordinal</string>
<string name="key_descr_superscript">Sobrescrito</string>
<string name="key_descr_subscript">Subscrito</string>
<!-- <string name="key_descr_page_up">Page Up</string> -->
<!-- <string name="key_descr_page_down">Page Down</string> -->
<!-- <string name="key_descr_home">Home</string> -->
<!-- <string name="key_descr_end">End</string> -->
<string name="pref_category_advanced">Avançado</string>
</resources> </resources>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="app_name" product="debug">Tastatură Unexpected (depanare)</string> <string name="app_name_release">Tastatură Unexpected</string>
<string name="app_name" product="default">Tastatură Unexpected</string> <string name="app_name_debug">Tastatură Unexpected (depanare)</string>
<string name="settings_activity_label">Setări Tastatură Unexpected</string> <string name="settings_activity_label">Setări Tastatură Unexpected</string>
<string name="pref_portrait">În mod portret</string> <string name="pref_portrait">În mod portret</string>
<string name="pref_landscape">În mod panoramă</string> <string name="pref_landscape">În mod panoramă</string>
@@ -10,13 +10,12 @@
<string name="pref_keyboard_opacity">Modifică opacitatea fundalului tastaturii</string> <string name="pref_keyboard_opacity">Modifică opacitatea fundalului tastaturii</string>
<string name="pref_key_opacity">Modifică opacitatea tastelor</string> <string name="pref_key_opacity">Modifică opacitatea tastelor</string>
<string name="pref_key_activated_opacity">Modifică opacitatea tastei apăsate</string> <string name="pref_key_activated_opacity">Modifică opacitatea tastei apăsate</string>
<string name="pref_layout_title">Schimbă aranjamentul tastaturii</string>
<string name="pref_layout_e_system">Setări de Sistem</string> <string name="pref_layout_e_system">Setări de Sistem</string>
<string name="pref_layout_e_custom">Aranjament personalizat</string> <string name="pref_layout_e_custom">Aranjament personalizat</string>
<string name="pref_accents_title">Accente</string> <!-- <string name="pref_layouts_add">Add an alternate layout</string> -->
<string name="pref_accents_e_all_installed">Arată accentele pentru toate limbile instalate</string> <!-- <string name="pref_layouts_item">Layout %1$d: %2$s</string> -->
<string name="pref_accents_e_selected">Aratp accentele doar pentru limba selectată</string> <!-- <string name="pref_layouts_remove_custom">Remove layout</string> -->
<string name="pref_accents_e_none">Ascunde accentele</string> <string name="pref_custom_layout_title">Aranjament personalizat</string>
<string name="pref_show_numpad_title">Arată NumPad</string> <string name="pref_show_numpad_title">Arată NumPad</string>
<string name="pref_show_numpad_never">Niciodată</string> <string name="pref_show_numpad_never">Niciodată</string>
<string name="pref_show_numpad_landscape">Doar în mod panoramă</string> <string name="pref_show_numpad_landscape">Doar în mod panoramă</string>
@@ -27,6 +26,8 @@
<string name="pref_numpad_layout_e_high_first">Mai întâi cifrele mari</string> <string name="pref_numpad_layout_e_high_first">Mai întâi cifrele mari</string>
<string name="pref_numpad_layout_e_low_first">Mai întâi cifrele mici</string> <string name="pref_numpad_layout_e_low_first">Mai întâi cifrele mici</string>
<string name="pref_extra_keys_title">Adaugă taste pe tastatură</string> <string name="pref_extra_keys_title">Adaugă taste pe tastatură</string>
<!-- <string name="pref_extra_keys_custom">Add custom keys</string> -->
<!-- <string name="pref_extra_keys_internal">Select keys to add to the keyboard</string> -->
<string name="pref_second_layout_title">Aranjament secundar</string> <string name="pref_second_layout_title">Aranjament secundar</string>
<string name="pref_second_layout_none">Nimic</string> <string name="pref_second_layout_none">Nimic</string>
<string name="pref_category_typing">Tipărire</string> <string name="pref_category_typing">Tipărire</string>
@@ -41,8 +42,10 @@
<string name="pref_autocapitalisation_summary">Autoapăsare Shift la începutul fiecărei propoziții</string> <string name="pref_autocapitalisation_summary">Autoapăsare Shift la începutul fiecărei propoziții</string>
<string name="pref_switch_input_immediate_title">Schimbă la ultima tastatură folosită</string> <string name="pref_switch_input_immediate_title">Schimbă la ultima tastatură folosită</string>
<string name="pref_switch_input_immediate_summary">Comportamentul tastei pentru schimbarea tastaturii</string> <string name="pref_switch_input_immediate_summary">Comportamentul tastei pentru schimbarea tastaturii</string>
<string name="pref_vibrate_title">Vibrație</string> <!-- <string name="pref_vibrate_custom">Custom vibration</string> -->
<string name="pref_vibrate_summary">Activați/dezactivați vibrația la apăsarea tastelor</string> <!-- <string name="pref_vibrate_duration_title">Vibration intensity</string> -->
<!-- <string name="pref_pin_entry_enabled_title">Pin entry layout</string> -->
<!-- <string name="pref_pin_entry_enabled_summary">When typing numbers, dates and phone numbers</string> -->
<string name="pref_category_style">Stil</string> <string name="pref_category_style">Stil</string>
<string name="pref_margin_bottom_title">Marginea de jos</string> <string name="pref_margin_bottom_title">Marginea de jos</string>
<string name="pref_keyboard_height_title">Înălțimea tastaturii</string> <string name="pref_keyboard_height_title">Înălțimea tastaturii</string>
@@ -57,6 +60,8 @@
<string name="pref_theme_e_altblack">Negru Alternativ</string> <string name="pref_theme_e_altblack">Negru Alternativ</string>
<string name="pref_theme_e_white">Albă</string> <string name="pref_theme_e_white">Albă</string>
<string name="pref_theme_e_epaper">ePaper</string> <string name="pref_theme_e_epaper">ePaper</string>
<!-- <string name="pref_theme_e_desert">Desert</string> -->
<!-- <string name="pref_theme_e_jungle">Jungle</string> -->
<string name="pref_swipe_dist_e_very_short">Foarte apropiată</string> <string name="pref_swipe_dist_e_very_short">Foarte apropiată</string>
<string name="pref_swipe_dist_e_short">Apropiată</string> <string name="pref_swipe_dist_e_short">Apropiată</string>
<string name="pref_swipe_dist_e_default">Normală</string> <string name="pref_swipe_dist_e_default">Normală</string>
@@ -64,14 +69,6 @@
<string name="pref_swipe_dist_e_very_far">Foarte depărtată</string> <string name="pref_swipe_dist_e_very_far">Foarte depărtată</string>
<string name="pref_key_horizontal_space">Distanța orizontală dintre taste</string> <string name="pref_key_horizontal_space">Distanța orizontală dintre taste</string>
<string name="pref_key_vertical_space">Distanța verticală dintre taste</string> <string name="pref_key_vertical_space">Distanța verticală dintre taste</string>
<string name="pref_category_advanced">Setări avansate</string>
<string name="pref_custom_layout_title">Aranjament personalizat</string>
<string name="pref_custom_layout_summary">Deschide codul sursă. Această opțiune nu e destinată spre folosință.</string>
<!-- <string name="pref_vibration_e_disabled">Disabled</string> -->
<!-- <string name="pref_vibration_e_system">System</string> -->
<!-- <string name="pref_vibration_e_strong">Strong</string> -->
<!-- <string name="pref_vibration_e_medium">Medium</string> -->
<!-- <string name="pref_vibration_e_light">Light</string> -->
<string name="key_action_next">Următor</string> <string name="key_action_next">Următor</string>
<string name="key_action_done">Gata</string> <string name="key_action_done">Gata</string>
<string name="key_action_go">Go</string> <string name="key_action_go">Go</string>
@@ -79,7 +76,29 @@
<string name="key_action_search">Caută</string> <string name="key_action_search">Caută</string>
<string name="key_action_send">Trimite</string> <string name="key_action_send">Trimite</string>
<string name="launcher_button_imesettings">Activează tastatura</string> <string name="launcher_button_imesettings">Activează tastatura</string>
<!-- <string name="launcher_button_imepicker">Select keyboard</string> -->
<string name="launcher_description">Această aplicație este o tastatură virtuală. Accesați setările sistemului făcând clic pe butonul de mai jos și activați tastatura Unexpected.</string> <string name="launcher_description">Această aplicație este o tastatură virtuală. Accesați setările sistemului făcând clic pe butonul de mai jos și activați tastatura Unexpected.</string>
<string name="launcher_sourcecode">Aceasta este o aplicație gratuită și open source. Puteți găsi codul sursă sau raporta erori folosind link-ul <a href="https://github.com/Julow/Unexpected-Keyboard/">Github</a>.</string> <string name="launcher_sourcecode">Aceasta este o aplicație gratuită și open source. Puteți găsi codul sursă sau raporta erori folosind link-ul Github.</string>
<string name="launcher_tryhere">După activare, puteți să încercați tastatura aici:</string> <string name="launcher_tryhere">După activare, puteți să încercați tastatura aici:</string>
<!-- <string name="key_descr_capslock">Caps lock</string> -->
<!-- <string name="key_descr_switch_greekmath">Greek &amp; math symbols</string> -->
<!-- <string name="key_descr_change_method">Switch keyboard</string> -->
<!-- <string name="key_descr_voice_typing">Voice typing</string> -->
<!-- <string name="key_descr_copy">Copy</string> -->
<!-- <string name="key_descr_paste">Paste</string> -->
<!-- <string name="key_descr_cut">Cut</string> -->
<!-- <string name="key_descr_selectAll">Select all</string> -->
<!-- <string name="key_descr_shareText">Share text</string> -->
<!-- <string name="key_descr_pasteAsPlainText">Paste as plain text</string> -->
<!-- <string name="key_descr_undo">Undo</string> -->
<!-- <string name="key_descr_redo">Redo</string> -->
<!-- <string name="key_descr_ª">Ordinal Indicator</string> -->
<!-- <string name="key_descr_º">Ordinal Indicator</string> -->
<!-- <string name="key_descr_superscript">Superscript</string> -->
<!-- <string name="key_descr_subscript">Subscript</string> -->
<!-- <string name="key_descr_page_up">Page Up</string> -->
<!-- <string name="key_descr_page_down">Page Down</string> -->
<!-- <string name="key_descr_home">Home</string> -->
<!-- <string name="key_descr_end">End</string> -->
<string name="pref_category_advanced">Setări avansate</string>
</resources> </resources>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="app_name" product="debug">Unexpected Keyboard (отладка)</string> <string name="app_name_release">Unexpected Keyboard</string>
<string name="app_name" product="default">Unexpected Keyboard</string> <string name="app_name_debug">Unexpected Keyboard (отладка)</string>
<string name="settings_activity_label">Unexpected Keyboard Настройки</string> <string name="settings_activity_label">Unexpected Keyboard Настройки</string>
<string name="pref_portrait">В портретном режиме</string> <string name="pref_portrait">В портретном режиме</string>
<string name="pref_landscape">В ландшафтном режиме</string> <string name="pref_landscape">В ландшафтном режиме</string>
@@ -10,13 +10,12 @@
<string name="pref_keyboard_opacity">Изменить прозрачность фона</string> <string name="pref_keyboard_opacity">Изменить прозрачность фона</string>
<string name="pref_key_opacity">Изменить прозрачность клавиш</string> <string name="pref_key_opacity">Изменить прозрачность клавиш</string>
<string name="pref_key_activated_opacity">Изменить прозрачность нажатой клавиши</string> <string name="pref_key_activated_opacity">Изменить прозрачность нажатой клавиши</string>
<string name="pref_layout_title">Изменить раскладку клавиатуры</string>
<string name="pref_layout_e_system">Системные настройки</string> <string name="pref_layout_e_system">Системные настройки</string>
<string name="pref_layout_e_custom">Пользовательская раскладка</string> <string name="pref_layout_e_custom">Пользовательская раскладка</string>
<string name="pref_accents_title">Акцент</string> <!-- <string name="pref_layouts_add">Add an alternate layout</string> -->
<string name="pref_accents_e_all_installed">Показывать акценты для всех установленных языков</string> <!-- <string name="pref_layouts_item">Layout %1$d: %2$s</string> -->
<string name="pref_accents_e_selected">Показывать акценты только для выбранного языка</string> <!-- <string name="pref_layouts_remove_custom">Remove layout</string> -->
<string name="pref_accents_e_none">Скрыть акценты</string> <string name="pref_custom_layout_title">Пользовательская раскладка</string>
<string name="pref_show_numpad_title">Показывать NumPad</string> <string name="pref_show_numpad_title">Показывать NumPad</string>
<string name="pref_show_numpad_never">Никогда</string> <string name="pref_show_numpad_never">Никогда</string>
<string name="pref_show_numpad_landscape">Только в ландшафтном режиме</string> <string name="pref_show_numpad_landscape">Только в ландшафтном режиме</string>
@@ -27,6 +26,8 @@
<string name="pref_numpad_layout_e_high_first">Старшие цифры сверху</string> <string name="pref_numpad_layout_e_high_first">Старшие цифры сверху</string>
<string name="pref_numpad_layout_e_low_first">Младшие цифры сверху</string> <string name="pref_numpad_layout_e_low_first">Младшие цифры сверху</string>
<string name="pref_extra_keys_title">Добавить клавиши на клавиатуру</string> <string name="pref_extra_keys_title">Добавить клавиши на клавиатуру</string>
<!-- <string name="pref_extra_keys_custom">Add custom keys</string> -->
<!-- <string name="pref_extra_keys_internal">Select keys to add to the keyboard</string> -->
<string name="pref_second_layout_title">Дополнительная раскладка</string> <string name="pref_second_layout_title">Дополнительная раскладка</string>
<string name="pref_second_layout_none">Нет</string> <string name="pref_second_layout_none">Нет</string>
<string name="pref_category_typing">Печать</string> <string name="pref_category_typing">Печать</string>
@@ -41,8 +42,10 @@
<string name="pref_autocapitalisation_summary">Автонажатие Shift в начале каждого предложения</string> <string name="pref_autocapitalisation_summary">Автонажатие Shift в начале каждого предложения</string>
<string name="pref_switch_input_immediate_title">Переключаться к последней используемой клавиатуре</string> <string name="pref_switch_input_immediate_title">Переключаться к последней используемой клавиатуре</string>
<string name="pref_switch_input_immediate_summary">Поведение клавиши переключения клавиатуры</string> <string name="pref_switch_input_immediate_summary">Поведение клавиши переключения клавиатуры</string>
<string name="pref_vibrate_title">Вибрация</string> <!-- <string name="pref_vibrate_custom">Custom vibration</string> -->
<string name="pref_vibrate_summary">Включение/выключение вибрации при нажатии клавиши</string> <!-- <string name="pref_vibrate_duration_title">Vibration intensity</string> -->
<!-- <string name="pref_pin_entry_enabled_title">Pin entry layout</string> -->
<!-- <string name="pref_pin_entry_enabled_summary">When typing numbers, dates and phone numbers</string> -->
<string name="pref_category_style">Стиль</string> <string name="pref_category_style">Стиль</string>
<string name="pref_margin_bottom_title">Нижняя граница поля</string> <string name="pref_margin_bottom_title">Нижняя граница поля</string>
<string name="pref_keyboard_height_title">Высота клавиатуры</string> <string name="pref_keyboard_height_title">Высота клавиатуры</string>
@@ -57,6 +60,8 @@
<string name="pref_theme_e_altblack">Альтернативный черный</string> <string name="pref_theme_e_altblack">Альтернативный черный</string>
<string name="pref_theme_e_white">Белая</string> <string name="pref_theme_e_white">Белая</string>
<string name="pref_theme_e_epaper">ePaper</string> <string name="pref_theme_e_epaper">ePaper</string>
<!-- <string name="pref_theme_e_desert">Desert</string> -->
<!-- <string name="pref_theme_e_jungle">Jungle</string> -->
<string name="pref_swipe_dist_e_very_short">Очень близко</string> <string name="pref_swipe_dist_e_very_short">Очень близко</string>
<string name="pref_swipe_dist_e_short">Близко</string> <string name="pref_swipe_dist_e_short">Близко</string>
<string name="pref_swipe_dist_e_default">Нормально</string> <string name="pref_swipe_dist_e_default">Нормально</string>
@@ -64,14 +69,6 @@
<string name="pref_swipe_dist_e_very_far">Очень далеко</string> <string name="pref_swipe_dist_e_very_far">Очень далеко</string>
<string name="pref_key_horizontal_space">Горизонтальное расстояние между клавишами</string> <string name="pref_key_horizontal_space">Горизонтальное расстояние между клавишами</string>
<string name="pref_key_vertical_space">Расстояние по вертикали между клавишами</string> <string name="pref_key_vertical_space">Расстояние по вертикали между клавишами</string>
<string name="pref_category_advanced">Расширенные настройки</string>
<string name="pref_custom_layout_title">Пользовательская раскладка</string>
<string name="pref_custom_layout_summary">Откройте исходный код. Эта параметр не предназначен для использования.</string>
<!-- <string name="pref_vibration_e_disabled">Disabled</string> -->
<!-- <string name="pref_vibration_e_system">System</string> -->
<!-- <string name="pref_vibration_e_strong">Strong</string> -->
<!-- <string name="pref_vibration_e_medium">Medium</string> -->
<!-- <string name="pref_vibration_e_light">Light</string> -->
<string name="key_action_next">Далее</string> <string name="key_action_next">Далее</string>
<string name="key_action_done">Ввод</string> <string name="key_action_done">Ввод</string>
<string name="key_action_go">Go</string> <string name="key_action_go">Go</string>
@@ -79,7 +76,29 @@
<string name="key_action_search">Поиск</string> <string name="key_action_search">Поиск</string>
<string name="key_action_send">Отправить</string> <string name="key_action_send">Отправить</string>
<string name="launcher_button_imesettings">Включить клавиатуру</string> <string name="launcher_button_imesettings">Включить клавиатуру</string>
<!-- <string name="launcher_button_imepicker">Select keyboard</string> -->
<string name="launcher_description">Данное приложение является виртуальной клавиатурой. Зайдите в настройки, нажав кнопку внизу и активируйте Unexpected-Keyboard.</string> <string name="launcher_description">Данное приложение является виртуальной клавиатурой. Зайдите в настройки, нажав кнопку внизу и активируйте Unexpected-Keyboard.</string>
<string name="launcher_sourcecode">Это бесплатное приложение с открытым исходным кодом. Вы можете изучить код или сообщить об ошибках по ссылке <a href="https://github.com/Julow/Unexpected-Keyboard/">Github</a>.</string> <string name="launcher_sourcecode">Это бесплатное приложение с открытым исходным кодом. Вы можете изучить код или сообщить об ошибках по ссылке Github.</string>
<string name="launcher_tryhere">После активации вы можете попробовать клавиатуру прямо здесь:</string> <string name="launcher_tryhere">После активации вы можете попробовать клавиатуру прямо здесь:</string>
<!-- <string name="key_descr_capslock">Caps lock</string> -->
<!-- <string name="key_descr_switch_greekmath">Greek &amp; math symbols</string> -->
<!-- <string name="key_descr_change_method">Switch keyboard</string> -->
<!-- <string name="key_descr_voice_typing">Voice typing</string> -->
<!-- <string name="key_descr_copy">Copy</string> -->
<!-- <string name="key_descr_paste">Paste</string> -->
<!-- <string name="key_descr_cut">Cut</string> -->
<!-- <string name="key_descr_selectAll">Select all</string> -->
<!-- <string name="key_descr_shareText">Share text</string> -->
<!-- <string name="key_descr_pasteAsPlainText">Paste as plain text</string> -->
<!-- <string name="key_descr_undo">Undo</string> -->
<!-- <string name="key_descr_redo">Redo</string> -->
<!-- <string name="key_descr_ª">Ordinal Indicator</string> -->
<!-- <string name="key_descr_º">Ordinal Indicator</string> -->
<!-- <string name="key_descr_superscript">Superscript</string> -->
<!-- <string name="key_descr_subscript">Subscript</string> -->
<!-- <string name="key_descr_page_up">Page Up</string> -->
<!-- <string name="key_descr_page_down">Page Down</string> -->
<!-- <string name="key_descr_home">Home</string> -->
<!-- <string name="key_descr_end">End</string> -->
<string name="pref_category_advanced">Расширенные настройки</string>
</resources> </resources>

View File

@@ -1,62 +1,67 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="app_name" product="debug">Unexpected Keyboard (debug)</string> <string name="app_name_release">Unexpected Keyboard</string>
<string name="app_name" product="default">Unexpected Keyboard</string> <string name="app_name_debug">Unexpected Keyboard (debug)</string>
<string name="settings_activity_label">Unexpected Keyboard Ayarları</string> <string name="settings_activity_label">Unexpected Keyboard Ayarları</string>
<!-- <string name="pref_portrait">In portrait mode</string> --> <string name="pref_portrait">Portre modunda</string>
<!-- <string name="pref_landscape">In landscape mode</string> --> <string name="pref_landscape">Manzara modunda</string>
<string name="pref_category_layout">Düzen</string> <string name="pref_category_layout">Tuş düzeni</string>
<!-- <string name="pref_label_brightness">Adjust label brightness</string> --> <string name="pref_label_brightness">Adjust label brightness</string>
<!-- <string name="pref_keyboard_opacity">Adjust keyboard background opacity</string> --> <string name="pref_keyboard_opacity">Klavye arkaplanı opaklığını ayarla</string>
<!-- <string name="pref_key_opacity">Adjust key opacity</string> --> <string name="pref_key_opacity">Tuş opaklığını ayarla</string>
<!-- <string name="pref_key_activated_opacity">Adjust pressed key opacity</string> --> <string name="pref_key_activated_opacity">Tuşa basıldığındaki opaklığı ayarla</string>
<string name="pref_layout_title">Klavye Düzenini Değiştir</string> <string name="pref_layout_e_system">Sistem ayarlarını kullan</string>
<string name="pref_layout_e_system">Sistem Ayarları</string> <string name="pref_layout_e_custom">Özel tuş düeni</string>
<!-- <string name="pref_layout_e_custom">Custom layout</string> --> <string name="pref_layouts_add">Alternatif bir tuş düzeni ekle</string>
<string name="pref_accents_title">Aksanlar</string> <string name="pref_layouts_item">Tuş düzeni %1$d: %2$s</string>
<string name="pref_accents_e_all_installed">Yüklü tüm dillerin aksanlarını göster</string> <string name="pref_layouts_remove_custom">Tuş düzenini kaldır</string>
<string name="pref_accents_e_selected">Sadece seçili dilin aksanlarını göster</string> <string name="pref_custom_layout_title">Özel tuş düzeni</string>
<string name="pref_accents_e_none">Aksanları gizle</string> <string name="pref_show_numpad_title">NumPadi göster</string>
<!-- <string name="pref_show_numpad_title">Show NumPad</string> --> <string name="pref_show_numpad_never">Asla</string>
<!-- <string name="pref_show_numpad_never">Never</string> --> <string name="pref_show_numpad_landscape">Sadece manzara modunda</string>
<!-- <string name="pref_show_numpad_landscape">Only in landscape mode</string> --> <string name="pref_show_numpad_always">Her zaman</string>
<!-- <string name="pref_show_numpad_always">Always</string> --> <string name="pref_number_row_title">Rakam satırını göster</string>
<!-- <string name="pref_number_row_title">Show number row</string> --> <string name="pref_number_row_summary">NumPad gizlendiğinde klavyenin üstüne rakam satırı ekle</string>
<!-- <string name="pref_number_row_summary">Add a number row at the top of the keyboard when the numpad is hidden</string> --> <string name="pref_numpad_layout">NumPad düzeni</string>
<!-- <string name="pref_numpad_layout">NumPad layout</string> --> <string name="pref_numpad_layout_e_high_first">9dan 1e</string>
<!-- <string name="pref_numpad_layout_e_high_first">High digits first</string> --> <string name="pref_numpad_layout_e_low_first">1den 9a</string>
<!-- <string name="pref_numpad_layout_e_low_first">Low digits first</string> --> <string name="pref_extra_keys_title">Tuş ekle</string>
<!-- <string name="pref_extra_keys_title">Add keys to the keyboard</string> --> <string name="pref_extra_keys_custom">Özel tuş ekle</string>
<!-- <string name="pref_second_layout_title">Secondary layout</string> --> <string name="pref_extra_keys_internal">Klavyeye eklenecek tuşları seçin</string>
<string name="pref_second_layout_title">İklncil tuş düzeni</string>
<string name="pref_second_layout_none">Hiçbiri</string> <string name="pref_second_layout_none">Hiçbiri</string>
<string name="pref_category_typing">Yazma</string> <string name="pref_category_typing">Yazma</string>
<string name="pref_swipe_dist_title">Kaydırma mesafesi</string> <string name="pref_swipe_dist_title">Kaydırma mesafesi</string>
<string name="pref_swipe_dist_summary">Tuşların köşelerindeki karakterlerin uzaklıkları (%s)</string> <string name="pref_swipe_dist_summary">Tuşların köşelerinden kaydırma mesafesi (%s)</string>
<string name="pref_long_timeout_title">Tuş tekrarlama beklemesi</string> <string name="pref_long_timeout_title">Tuşların tekrarlaması için geçmesi gereken süre</string>
<string name="pref_long_interval_title">Tuş tekrarlama aralığı</string> <string name="pref_long_interval_title">Tuşların tekrarlama sıklığı</string>
<!-- <string name="pref_lock_double_tap_title">Double tap on shift for caps lock</string> --> <string name="pref_lock_double_tap_title">CapsLock için Shift tuşuna çift bas</string>
<!-- <string name="pref_lock_double_tap_summary">You can lock any modifier by holding it</string> --> <string name="pref_lock_double_tap_summary">Uzun basarak CapsLock açılabilir</string>
<!-- <string name="pref_category_behavior">Behavior</string> --> <string name="pref_category_behavior">Klavye davranışı</string>
<!-- <string name="pref_autocapitalisation_title">Automatic capitalisation</string> --> <string name="pref_autocapitalisation_title">Otomatik büyük harf</string>
<!-- <string name="pref_autocapitalisation_summary">Press Shift at the beginning of a sentence</string> --> <string name="pref_autocapitalisation_summary">Noktadan sonra ve her cümlenin başında büyük harf yapar</string>
<!-- <string name="pref_switch_input_immediate_title">Switch to the last used keyboard</string> --> <string name="pref_switch_input_immediate_title">Son kullanılan klavyeye geç</string>
<!-- <string name="pref_switch_input_immediate_summary">Behavior of the keyboard-switching key</string> --> <string name="pref_switch_input_immediate_summary">Klavye değistirme tuşunun davranışını belirler</string>
<string name="pref_vibrate_title">Titreşim</string> <!-- <string name="pref_vibrate_custom">Custom vibration</string> -->
<string name="pref_vibrate_summary">Tuşa basıldığında titreşimi etkinleştir</string> <!-- <string name="pref_vibrate_duration_title">Vibration intensity</string> -->
<string name="pref_category_style">Stil</string> <string name="pref_pin_entry_enabled_title">NumPad</string>
<string name="pref_pin_entry_enabled_summary">Sayıları, tarihleri ve telefon numaralarını yazarken</string>
<string name="pref_category_style">Tarz</string>
<string name="pref_margin_bottom_title">Alt boşluk</string> <string name="pref_margin_bottom_title">Alt boşluk</string>
<string name="pref_keyboard_height_title">Klavye yüksekliği</string> <string name="pref_keyboard_height_title">Klavye yüksekliği</string>
<string name="pref_horizontal_margin_title">Yatay boşluk</string> <string name="pref_horizontal_margin_title">Yatay boşluk</string>
<string name="pref_character_size_title">Etiket boyutu</string> <string name="pref_character_size_title">Etiket boyutu</string>
<string name="pref_character_size_summary">Klavye üzerinde gösterilecek karakter boyutu (%.2fx)</string> <string name="pref_character_size_summary">Klavye üzerindeki karakterlerin boyutu (%.2fx)</string>
<string name="pref_theme">Tema</string> <string name="pref_theme">Tema</string>
<string name="pref_theme_e_system">Sistem Ayarları</string> <string name="pref_theme_e_system">Sistem Temasını Kullan</string>
<string name="pref_theme_e_dark">Koyu</string> <string name="pref_theme_e_dark">Koyu</string>
<string name="pref_theme_e_light">Açık</string> <string name="pref_theme_e_light">Aydınlık</string>
<string name="pref_theme_e_black">Siyah</string> <string name="pref_theme_e_black">Siyah</string>
<!-- <string name="pref_theme_e_altblack">Alternative Black</string> --> <string name="pref_theme_e_altblack">Alternatif Siyah</string>
<!-- <string name="pref_theme_e_white">White</string> --> <string name="pref_theme_e_white">Beyaz</string>
<!-- <string name="pref_theme_e_epaper">ePaper</string> --> <string name="pref_theme_e_epaper">E-Kağıt</string>
<string name="pref_theme_e_desert">Çöl</string>
<string name="pref_theme_e_jungle">Orman</string>
<string name="pref_swipe_dist_e_very_short">Çok kısa</string> <string name="pref_swipe_dist_e_very_short">Çok kısa</string>
<string name="pref_swipe_dist_e_short">Kısa</string> <string name="pref_swipe_dist_e_short">Kısa</string>
<string name="pref_swipe_dist_e_default">Normal</string> <string name="pref_swipe_dist_e_default">Normal</string>
@@ -64,22 +69,36 @@
<string name="pref_swipe_dist_e_very_far">Çok uzun</string> <string name="pref_swipe_dist_e_very_far">Çok uzun</string>
<string name="pref_key_horizontal_space">Tuşlar arasındaki yatay boşluk</string> <string name="pref_key_horizontal_space">Tuşlar arasındaki yatay boşluk</string>
<string name="pref_key_vertical_space">Tuşlar arasındaki dikey boşluk</string> <string name="pref_key_vertical_space">Tuşlar arasındaki dikey boşluk</string>
<!-- <string name="pref_category_advanced">Advanced</string> --> <string name="key_action_next">Sonraki</string>
<!-- <string name="pref_custom_layout_title">Custom layout</string> --> <string name="key_action_done">Tamam</string>
<!-- <string name="pref_custom_layout_summary">See the source code. This option is not meant to be used.</string> --> <string name="key_action_go">ileri</string>
<!-- <string name="pref_vibration_e_disabled">Disabled</string> --> <string name="key_action_prev">Önceki</string>
<!-- <string name="pref_vibration_e_system">System</string> -->
<!-- <string name="pref_vibration_e_strong">Strong</string> -->
<!-- <string name="pref_vibration_e_medium">Medium</string> -->
<!-- <string name="pref_vibration_e_light">Light</string> -->
<string name="key_action_next">İleri</string>
<string name="key_action_done">Bitti</string>
<string name="key_action_go">İlerle</string>
<string name="key_action_prev">Geri</string>
<string name="key_action_search">Ara</string> <string name="key_action_search">Ara</string>
<string name="key_action_send">Gönder</string> <string name="key_action_send">Gönder</string>
<!-- <string name="launcher_button_imesettings">Enable keyboard</string> --> <string name="launcher_button_imesettings">Ayarlarda aktif et</string>
<!-- <string name="launcher_description">This application is a virtual keyboard. Go to the system settings by clicking on the button below and enable Unexpected-Keyboard.</string> --> <string name="launcher_button_imepicker">Klavye Seç</string>
<!-- <string name="launcher_sourcecode">This is an free and open source application. You can find the source code or report bugs on <a href="https://github.com/Julow/Unexpected-Keyboard/">Github</a>.</string> --> <string name="launcher_description">Bu uygulama bir sanal klavye uygulamasıdır. Aşağıdaki butona basarak sistem ayarlarında etkinleştiriniz.</string>
<!-- <string name="launcher_tryhere">After enabling, you can try the keyboard here:</string> --> <string name="launcher_sourcecode">Bu uygulama ücretsiz ve açık kaynaklıdır. Kaynak koduna erişmek veya bir hata raporlamak için GitHub</string>
<string name="launcher_tryhere">Ayarlardan aktif ettikten sonra klavyeyi burada test edebilirsin:</string>
<string name="key_descr_capslock">CapsLock</string>
<string name="key_descr_switch_greekmath">Greek &amp; math sembolleri</string>
<!-- <string name="key_descr_change_method">Switch keyboard</string> -->
<string name="key_descr_voice_typing">Sesle yazma</string>
<string name="key_descr_copy">Kopyala</string>
<string name="key_descr_paste">Yapıştır</string>
<string name="key_descr_cut">Kes</string>
<string name="key_descr_selectAll">Tümünü seç</string>
<string name="key_descr_shareText">Metni paylaş</string>
<string name="key_descr_pasteAsPlainText">Düz metin olarak yapıştır</string>
<string name="key_descr_undo">Geri al</string>
<string name="key_descr_redo">İleri al</string>
<string name="key_descr_ª">Sıralı göstergesi</string>
<string name="key_descr_º">Sıralı göstergesi</string>
<string name="key_descr_superscript">Süperscript</string>
<string name="key_descr_subscript">Anascript</string>
<string name="key_descr_page_up">Yukarı</string>
<string name="key_descr_page_down">Aşağı</string>
<string name="key_descr_home">BAŞ(Sol yön tuşu)</string>
<string name="key_descr_end">SON(Sağ yön tuşu)</string>
<string name="pref_category_advanced">Gelişmiş</string>
</resources> </resources>

104
res/values-uk/strings.xml Normal file
View File

@@ -0,0 +1,104 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name_release">Unexpected Keyboard</string>
<string name="app_name_debug">Unexpected Keyboard (Налагодження)</string>
<string name="settings_activity_label">Unexpected Keyboard Налаштування</string>
<string name="pref_portrait">У портретному режимі</string>
<string name="pref_landscape">У альбомному режимі</string>
<string name="pref_category_layout">Макет</string>
<string name="pref_label_brightness">Налаштувати яскравість символів</string>
<string name="pref_keyboard_opacity">Налаштувати прозорість фону клавіатури</string>
<string name="pref_key_opacity">Налаштувати прозорість клавіш</string>
<string name="pref_key_activated_opacity">Налаштувати прозорість натиснутої клавіші</string>
<string name="pref_layout_e_system">Системні налаштування</string>
<string name="pref_layout_e_custom">Власний макет</string>
<string name="pref_layouts_add">Додати альтернативний макет</string>
<string name="pref_layouts_item">Макет %1$d: %2$s</string>
<string name="pref_layouts_remove_custom">Видалити макет</string>
<string name="pref_custom_layout_title">Власний макет</string>
<string name="pref_show_numpad_title">Показувати числову клавіатуру </string>
<string name="pref_show_numpad_never">Ніколи</string>
<string name="pref_show_numpad_landscape">Тільки в альбомному режимі</string>
<string name="pref_show_numpad_always">Завжди</string>
<string name="pref_number_row_title">Показувати рядок чисел</string>
<string name="pref_number_row_summary">Додати рядок чисел у верхній частині клавіатури, коли числову клавіатуру приховано</string>
<string name="pref_numpad_layout">Макет числової клавіатури</string>
<string name="pref_numpad_layout_e_high_first">Від найбільшої цифри</string>
<string name="pref_numpad_layout_e_low_first">Від найменшої цифри</string>
<string name="pref_extra_keys_title">Додати клавіші до клавіатури</string>
<string name="pref_extra_keys_custom">Додайте власні клавіші</string>
<string name="pref_extra_keys_internal">Виберіть клавіші, які потрібно додати до клавіатури</string>
<string name="pref_second_layout_title">Додаткова розкладка</string>
<string name="pref_second_layout_none">Немає</string>
<string name="pref_category_typing">Введення</string>
<string name="pref_swipe_dist_title">Відстань проведення</string>
<string name="pref_swipe_dist_summary">Відстань між символами в кутах клавіш (%s)</string>
<string name="pref_long_timeout_title">Час очікування повтору клавіші</string>
<string name="pref_long_interval_title">Інтервал повторення клавіш</string>
<string name="pref_lock_double_tap_title">Двічі торкніться Shift для Caps Lock</string>
<string name="pref_lock_double_tap_summary">Ви можете заблокувати будь-який модифікатор, утримуючи його</string>
<string name="pref_category_behavior">Поведінка</string>
<string name="pref_autocapitalisation_title">Автоматичне введення великих літер</string>
<string name="pref_autocapitalisation_summary">Натиснути Shift на початку речення</string>
<string name="pref_switch_input_immediate_title">Перейти до останньої використаної клавіатури</string>
<string name="pref_switch_input_immediate_summary">Поведінка клавіші перемикання клавіатури</string>
<string name="pref_vibrate_custom">Спеціальна вібрація</string>
<string name="pref_vibrate_duration_title">Інтенсивність вібрації</string>
<string name="pref_pin_entry_enabled_title">Макет введення PIN-коду</string>
<string name="pref_pin_entry_enabled_summary">При наборі чисел, дат і номерів телефонів</string>
<string name="pref_category_style">Стиль</string>
<string name="pref_margin_bottom_title">Поле знизу</string>
<string name="pref_keyboard_height_title">Висота клавіатури</string>
<string name="pref_horizontal_margin_title">Горизонтальне поле</string>
<string name="pref_character_size_title">Розмір символів</string>
<string name="pref_character_size_summary">Розмір символів, що відображаються на клавіатурі (%.2fx)</string>
<string name="pref_theme">Тема</string>
<string name="pref_theme_e_system">Налаштування системи</string>
<string name="pref_theme_e_dark">Темна</string>
<string name="pref_theme_e_light">Світла</string>
<string name="pref_theme_e_black">Чорна</string>
<string name="pref_theme_e_altblack">Альтернативний чорний</string>
<string name="pref_theme_e_white">Біла</string>
<string name="pref_theme_e_epaper">ePaper</string>
<string name="pref_theme_e_desert">Пустеля</string>
<string name="pref_theme_e_jungle">Джунглі</string>
<string name="pref_swipe_dist_e_very_short">Дуже коротка</string>
<string name="pref_swipe_dist_e_short">Коротка</string>
<string name="pref_swipe_dist_e_default">Звичайна</string>
<string name="pref_swipe_dist_e_far">Далека</string>
<string name="pref_swipe_dist_e_very_far">Дуже далека</string>
<string name="pref_key_horizontal_space">Горизонтальна відстань між клавішами</string>
<string name="pref_key_vertical_space">Вертикальна відстань між клавішами</string>
<string name="key_action_next">Далі</string>
<string name="key_action_done">Готово</string>
<string name="key_action_go">Іти</string>
<string name="key_action_prev">Назад</string>
<string name="key_action_search">Пошук</string>
<string name="key_action_send">Надіслати</string>
<string name="launcher_button_imesettings">Увімкнути клавіатуру</string>
<string name="launcher_button_imepicker">Вибрати клавіатуру</string>
<string name="launcher_description">Ця програма є віртуальною клавіатурою. Перейдіть до системних налаштувань, натиснувши кнопку нижче, і ввімкніть Unexpected-Keyboard.</string>
<string name="launcher_sourcecode">Це безкоштовна програма з відкритим кодом. Ви можете знайти початковий код або повідомити про помилки на GitHub.</string>
<string name="launcher_tryhere">Після ввімкнення ви можете спробувати клавіатуру тут:</string>
<string name="key_descr_capslock">Caps lock</string>
<string name="key_descr_switch_greekmath">Грецькі та математичні символи</string>
<string name="key_descr_change_method">Переключити клавіатуру</string>
<string name="key_descr_voice_typing">Голосове введення</string>
<string name="key_descr_copy">Копіювати</string>
<string name="key_descr_paste">Вставити</string>
<string name="key_descr_cut">Вирізати</string>
<string name="key_descr_selectAll">Вибрати все</string>
<string name="key_descr_shareText">Поділитися текстом</string>
<string name="key_descr_pasteAsPlainText">Вставити як звичайний текст</string>
<string name="key_descr_undo">Відмінити</string>
<string name="key_descr_redo">Повторити</string>
<string name="key_descr_ª">Жіночий порядковий вказівник</string>
<string name="key_descr_º">Чоловічий порядковий вказівник</string>
<string name="key_descr_superscript">Верхній індекс</string>
<string name="key_descr_subscript">Нижній індекс</string>
<string name="key_descr_page_up">Page Up</string>
<string name="key_descr_page_down">Page Down</string>
<string name="key_descr_home">Home</string>
<string name="key_descr_end">End</string>
<string name="pref_category_advanced">Додаткові</string>
</resources>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="appTheme" parent="@android:style/Theme.Material.Light"/>
</resources>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="app_name" product="debug">Unexpected Keyboard (gỡ lỗi)</string> <string name="app_name_release">Unexpected Keyboard</string>
<string name="app_name" product="default">Unexpected Keyboard</string> <string name="app_name_debug">Unexpected Keyboard (gỡ lỗi)</string>
<string name="settings_activity_label">Cài đặt Unexpected Keyboard</string> <string name="settings_activity_label">Cài đặt Unexpected Keyboard</string>
<string name="pref_portrait">Trong chế độ chân dung</string> <string name="pref_portrait">Trong chế độ chân dung</string>
<string name="pref_landscape">Trong chế độ phong cảnh</string> <string name="pref_landscape">Trong chế độ phong cảnh</string>
@@ -10,15 +10,12 @@
<string name="pref_keyboard_opacity">Tùy chỉnh độ trong suốt của bàn phím</string> <string name="pref_keyboard_opacity">Tùy chỉnh độ trong suốt của bàn phím</string>
<string name="pref_key_opacity">Tùy chỉnh độ trong suốt của phím</string> <string name="pref_key_opacity">Tùy chỉnh độ trong suốt của phím</string>
<string name="pref_key_activated_opacity">Tùy chỉnh độ trong suốt của phím khi nhấn</string> <string name="pref_key_activated_opacity">Tùy chỉnh độ trong suốt của phím khi nhấn</string>
<string name="pref_layout_title">Thay đổi bố cục bàn phím</string>
<string name="pref_layout_e_system">Hệ thống</string> <string name="pref_layout_e_system">Hệ thống</string>
<string name="pref_layout_e_custom">Tùy chỉnh bố cục</string> <string name="pref_layout_e_custom">Tùy chỉnh bố cục</string>
<string name="pref_accents_title">Dấu phụ</string> <!-- <string name="pref_layouts_add">Add an alternate layout</string> -->
<string name="pref_accents_e_all_installed">Hiển thị cho các ngôn ngữ đã cài đặt</string> <!-- <string name="pref_layouts_item">Layout %1$d: %2$s</string> -->
<string name="pref_accents_e_selected">Chỉ hiển thị cho các ngôn ngữ đã chọn</string> <!-- <string name="pref_layouts_remove_custom">Remove layout</string> -->
<string name="pref_accents_e_none"> <string name="pref_custom_layout_title">Tùy chỉnh bố cục</string>
Ẩn dấu phụ
</string>
<string name="pref_show_numpad_title">Hiện NumPad</string> <string name="pref_show_numpad_title">Hiện NumPad</string>
<string name="pref_show_numpad_never">Không bao giờ</string> <string name="pref_show_numpad_never">Không bao giờ</string>
<string name="pref_show_numpad_landscape">Chỉ trong chế độ phong cảnh</string> <string name="pref_show_numpad_landscape">Chỉ trong chế độ phong cảnh</string>
@@ -29,6 +26,8 @@
<string name="pref_numpad_layout_e_high_first">Số lớn nhất trước</string> <string name="pref_numpad_layout_e_high_first">Số lớn nhất trước</string>
<string name="pref_numpad_layout_e_low_first">Số nhỏ nhất trước</string> <string name="pref_numpad_layout_e_low_first">Số nhỏ nhất trước</string>
<string name="pref_extra_keys_title">Thêm phím vào bàn phím</string> <string name="pref_extra_keys_title">Thêm phím vào bàn phím</string>
<!-- <string name="pref_extra_keys_custom">Add custom keys</string> -->
<!-- <string name="pref_extra_keys_internal">Select keys to add to the keyboard</string> -->
<string name="pref_second_layout_title">Bố cục phụ</string> <string name="pref_second_layout_title">Bố cục phụ</string>
<string name="pref_second_layout_none">Không</string> <string name="pref_second_layout_none">Không</string>
<string name="pref_category_typing"></string> <string name="pref_category_typing"></string>
@@ -43,8 +42,10 @@
<string name="pref_autocapitalisation_summary">Nhấn Shift ở đầu câu</string> <string name="pref_autocapitalisation_summary">Nhấn Shift ở đầu câu</string>
<!-- <string name="pref_switch_input_immediate_title">Switch to the last used keyboard</string> --> <!-- <string name="pref_switch_input_immediate_title">Switch to the last used keyboard</string> -->
<!-- <string name="pref_switch_input_immediate_summary">Behavior of the keyboard-switching key</string> --> <!-- <string name="pref_switch_input_immediate_summary">Behavior of the keyboard-switching key</string> -->
<string name="pref_vibrate_title">Sự rung</string> <!-- <string name="pref_vibrate_custom">Custom vibration</string> -->
<string name="pref_vibrate_summary">Bật/tắt rung khi nhấn</string> <!-- <string name="pref_vibrate_duration_title">Vibration intensity</string> -->
<!-- <string name="pref_pin_entry_enabled_title">Pin entry layout</string> -->
<!-- <string name="pref_pin_entry_enabled_summary">When typing numbers, dates and phone numbers</string> -->
<string name="pref_category_style">Kiểu cách</string> <string name="pref_category_style">Kiểu cách</string>
<string name="pref_margin_bottom_title">Căn lề dưới</string> <string name="pref_margin_bottom_title">Căn lề dưới</string>
<string name="pref_keyboard_height_title">Chiều cao bàn phím</string> <string name="pref_keyboard_height_title">Chiều cao bàn phím</string>
@@ -59,6 +60,8 @@
<!-- <string name="pref_theme_e_altblack">Alternative Black</string> --> <!-- <string name="pref_theme_e_altblack">Alternative Black</string> -->
<string name="pref_theme_e_white">Trắng</string> <string name="pref_theme_e_white">Trắng</string>
<string name="pref_theme_e_epaper">ePaper</string> <string name="pref_theme_e_epaper">ePaper</string>
<!-- <string name="pref_theme_e_desert">Desert</string> -->
<!-- <string name="pref_theme_e_jungle">Jungle</string> -->
<string name="pref_swipe_dist_e_very_short">Rất gần</string> <string name="pref_swipe_dist_e_very_short">Rất gần</string>
<string name="pref_swipe_dist_e_short">Gần</string> <string name="pref_swipe_dist_e_short">Gần</string>
<string name="pref_swipe_dist_e_default">Trungbình</string> <string name="pref_swipe_dist_e_default">Trungbình</string>
@@ -66,14 +69,6 @@
<string name="pref_swipe_dist_e_very_far">Rất xa</string> <string name="pref_swipe_dist_e_very_far">Rất xa</string>
<string name="pref_key_horizontal_space">Khoảng cách giữa các phím theo chiều ngang</string> <string name="pref_key_horizontal_space">Khoảng cách giữa các phím theo chiều ngang</string>
<string name="pref_key_vertical_space">Khoảng cách giữa các phím theo chiều dọc</string> <string name="pref_key_vertical_space">Khoảng cách giữa các phím theo chiều dọc</string>
<string name="pref_category_advanced">Nâng cao</string>
<string name="pref_custom_layout_title">Tùy chỉnh bố cục</string>
<string name="pref_custom_layout_summary">Hãy xem mã nguồn. Lựa chọn này không có mục đích sử dụng.</string>
<!-- <string name="pref_vibration_e_disabled">Disabled</string> -->
<!-- <string name="pref_vibration_e_system">System</string> -->
<!-- <string name="pref_vibration_e_strong">Strong</string> -->
<!-- <string name="pref_vibration_e_medium">Medium</string> -->
<!-- <string name="pref_vibration_e_light">Light</string> -->
<string name="key_action_next">Tiếp</string> <string name="key_action_next">Tiếp</string>
<string name="key_action_done">Xong</string> <string name="key_action_done">Xong</string>
<string name="key_action_go">Đi</string> <string name="key_action_go">Đi</string>
@@ -81,7 +76,29 @@
<string name="key_action_search">Tìm</string> <string name="key_action_search">Tìm</string>
<string name="key_action_send">Gửi</string> <string name="key_action_send">Gửi</string>
<!-- <string name="launcher_button_imesettings">Enable keyboard</string> --> <!-- <string name="launcher_button_imesettings">Enable keyboard</string> -->
<!-- <string name="launcher_button_imepicker">Select keyboard</string> -->
<!-- <string name="launcher_description">This application is a virtual keyboard. Go to the system settings by clicking on the button below and enable Unexpected-Keyboard.</string> --> <!-- <string name="launcher_description">This application is a virtual keyboard. Go to the system settings by clicking on the button below and enable Unexpected-Keyboard.</string> -->
<!-- <string name="launcher_sourcecode">This is an free and open source application. You can find the source code or report bugs on <a href="https://github.com/Julow/Unexpected-Keyboard/">Github</a>.</string> --> <!-- <string name="launcher_sourcecode">This is an free and open source application. You can find the source code or report bugs on Github.</string> -->
<!-- <string name="launcher_tryhere">After enabling, you can try the keyboard here:</string> --> <!-- <string name="launcher_tryhere">After enabling, you can try the keyboard here:</string> -->
<!-- <string name="key_descr_capslock">Caps lock</string> -->
<!-- <string name="key_descr_switch_greekmath">Greek &amp; math symbols</string> -->
<!-- <string name="key_descr_change_method">Switch keyboard</string> -->
<!-- <string name="key_descr_voice_typing">Voice typing</string> -->
<!-- <string name="key_descr_copy">Copy</string> -->
<!-- <string name="key_descr_paste">Paste</string> -->
<!-- <string name="key_descr_cut">Cut</string> -->
<!-- <string name="key_descr_selectAll">Select all</string> -->
<!-- <string name="key_descr_shareText">Share text</string> -->
<!-- <string name="key_descr_pasteAsPlainText">Paste as plain text</string> -->
<!-- <string name="key_descr_undo">Undo</string> -->
<!-- <string name="key_descr_redo">Redo</string> -->
<!-- <string name="key_descr_ª">Ordinal Indicator</string> -->
<!-- <string name="key_descr_º">Ordinal Indicator</string> -->
<!-- <string name="key_descr_superscript">Superscript</string> -->
<!-- <string name="key_descr_subscript">Subscript</string> -->
<!-- <string name="key_descr_page_up">Page Up</string> -->
<!-- <string name="key_descr_page_down">Page Down</string> -->
<!-- <string name="key_descr_home">Home</string> -->
<!-- <string name="key_descr_end">End</string> -->
<string name="pref_category_advanced">Nâng cao</string>
</resources> </resources>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="app_name" product="debug">Unexpected Keyboard (debug)</string> <string name="app_name_release">Unexpected Keyboard</string>
<string name="app_name" product="default">Unexpected Keyboard</string> <string name="app_name_debug">Unexpected Keyboard (debug)</string>
<string name="settings_activity_label">Unexpected Keyboard 设置</string> <string name="settings_activity_label">Unexpected Keyboard 设置</string>
<string name="pref_portrait">在竖屏模式下</string> <string name="pref_portrait">在竖屏模式下</string>
<string name="pref_landscape">在横屏模式下</string> <string name="pref_landscape">在横屏模式下</string>
@@ -10,13 +10,12 @@
<string name="pref_keyboard_opacity">调整键盘背景透明度</string> <string name="pref_keyboard_opacity">调整键盘背景透明度</string>
<string name="pref_key_opacity">调整按键透明度</string> <string name="pref_key_opacity">调整按键透明度</string>
<string name="pref_key_activated_opacity">调整按下的按键的透明度</string> <string name="pref_key_activated_opacity">调整按下的按键的透明度</string>
<string name="pref_layout_title">改变键盘布局</string>
<string name="pref_layout_e_system">系统设置</string> <string name="pref_layout_e_system">系统设置</string>
<string name="pref_layout_e_custom">自定义布局</string> <string name="pref_layout_e_custom">自定义布局</string>
<string name="pref_accents_title">声调</string> <!-- <string name="pref_layouts_add">Add an alternate layout</string> -->
<string name="pref_accents_e_all_installed">显示所有安装的语言的声调符号</string> <!-- <string name="pref_layouts_item">Layout %1$d: %2$s</string> -->
<string name="pref_accents_e_selected">只显示选择的语言的声调符号</string> <!-- <string name="pref_layouts_remove_custom">Remove layout</string> -->
<string name="pref_accents_e_none">隐藏声调符号</string> <string name="pref_custom_layout_title">自定义布局</string>
<string name="pref_show_numpad_title">显示数字小键盘</string> <string name="pref_show_numpad_title">显示数字小键盘</string>
<string name="pref_show_numpad_never">从不</string> <string name="pref_show_numpad_never">从不</string>
<string name="pref_show_numpad_landscape">只在横屏显示</string> <string name="pref_show_numpad_landscape">只在横屏显示</string>
@@ -27,6 +26,8 @@
<string name="pref_numpad_layout_e_high_first">大数字在上方</string> <string name="pref_numpad_layout_e_high_first">大数字在上方</string>
<string name="pref_numpad_layout_e_low_first">小数字在上方</string> <string name="pref_numpad_layout_e_low_first">小数字在上方</string>
<string name="pref_extra_keys_title">选择要显示的按键</string> <string name="pref_extra_keys_title">选择要显示的按键</string>
<!-- <string name="pref_extra_keys_custom">Add custom keys</string> -->
<!-- <string name="pref_extra_keys_internal">Select keys to add to the keyboard</string> -->
<string name="pref_second_layout_title">第二键盘布局</string> <string name="pref_second_layout_title">第二键盘布局</string>
<string name="pref_second_layout_none"></string> <string name="pref_second_layout_none"></string>
<string name="pref_category_typing">输入</string> <string name="pref_category_typing">输入</string>
@@ -41,8 +42,10 @@
<string name="pref_autocapitalisation_summary">在句子的开头自动按下Shift</string> <string name="pref_autocapitalisation_summary">在句子的开头自动按下Shift</string>
<string name="pref_switch_input_immediate_title">切换到最近使用的键盘</string> <string name="pref_switch_input_immediate_title">切换到最近使用的键盘</string>
<string name="pref_switch_input_immediate_summary">切换键盘按钮的行为</string> <string name="pref_switch_input_immediate_summary">切换键盘按钮的行为</string>
<string name="pref_vibrate_title">振动</string> <!-- <string name="pref_vibrate_custom">Custom vibration</string> -->
<string name="pref_vibrate_summary">启用或者禁用按下按键时振动</string> <!-- <string name="pref_vibrate_duration_title">Vibration intensity</string> -->
<!-- <string name="pref_pin_entry_enabled_title">Pin entry layout</string> -->
<!-- <string name="pref_pin_entry_enabled_summary">When typing numbers, dates and phone numbers</string> -->
<string name="pref_category_style">样式</string> <string name="pref_category_style">样式</string>
<string name="pref_margin_bottom_title">键盘下边距</string> <string name="pref_margin_bottom_title">键盘下边距</string>
<string name="pref_keyboard_height_title">键盘高度</string> <string name="pref_keyboard_height_title">键盘高度</string>
@@ -57,6 +60,8 @@
<string name="pref_theme_e_altblack">黑色带边框</string> <string name="pref_theme_e_altblack">黑色带边框</string>
<string name="pref_theme_e_white">白色</string> <string name="pref_theme_e_white">白色</string>
<string name="pref_theme_e_epaper">白色带边框</string> <string name="pref_theme_e_epaper">白色带边框</string>
<!-- <string name="pref_theme_e_desert">Desert</string> -->
<!-- <string name="pref_theme_e_jungle">Jungle</string> -->
<string name="pref_swipe_dist_e_very_short">非常短</string> <string name="pref_swipe_dist_e_very_short">非常短</string>
<string name="pref_swipe_dist_e_short"></string> <string name="pref_swipe_dist_e_short"></string>
<string name="pref_swipe_dist_e_default">中(默认)</string> <string name="pref_swipe_dist_e_default">中(默认)</string>
@@ -64,14 +69,6 @@
<string name="pref_swipe_dist_e_very_far">非常长</string> <string name="pref_swipe_dist_e_very_far">非常长</string>
<string name="pref_key_horizontal_space">按键的左右边距</string> <string name="pref_key_horizontal_space">按键的左右边距</string>
<string name="pref_key_vertical_space">按键的上下边距</string> <string name="pref_key_vertical_space">按键的上下边距</string>
<string name="pref_category_advanced">高级设置</string>
<string name="pref_custom_layout_title">自定义布局</string>
<string name="pref_custom_layout_summary">请查看源代码。这个选项不应该在正常情况下使用。</string>
<string name="pref_vibration_e_disabled">禁用</string>
<string name="pref_vibration_e_system">使用系统振动强度</string>
<string name="pref_vibration_e_strong"></string>
<string name="pref_vibration_e_medium"></string>
<string name="pref_vibration_e_light"></string>
<string name="key_action_next">下一项</string> <string name="key_action_next">下一项</string>
<string name="key_action_done">完成</string> <string name="key_action_done">完成</string>
<string name="key_action_go">前往</string> <string name="key_action_go">前往</string>
@@ -79,7 +76,29 @@
<string name="key_action_search">搜索</string> <string name="key_action_search">搜索</string>
<string name="key_action_send">发送</string> <string name="key_action_send">发送</string>
<string name="launcher_button_imesettings">启用键盘</string> <string name="launcher_button_imesettings">启用键盘</string>
<!-- <string name="launcher_button_imepicker">Select keyboard</string> -->
<string name="launcher_description">这是一个虚拟键盘软件。点击按钮进入系统设置,然后启用 Unexpected-Keyboard 即可使用。</string> <string name="launcher_description">这是一个虚拟键盘软件。点击按钮进入系统设置,然后启用 Unexpected-Keyboard 即可使用。</string>
<string name="launcher_sourcecode">这是一个免费且开源的软件。你可以在 <a href="https://github.com/Julow/Unexpected-Keyboard/">Github</a> 上找到源代码或者反馈 bug。</string> <string name="launcher_sourcecode">这是一个免费且开源的软件。你可以在 Github 上找到源代码或者反馈 bug。</string>
<string name="launcher_tryhere">启用键盘后,可以在这里测试效果:</string> <string name="launcher_tryhere">启用键盘后,可以在这里测试效果:</string>
<!-- <string name="key_descr_capslock">Caps lock</string> -->
<!-- <string name="key_descr_switch_greekmath">Greek &amp; math symbols</string> -->
<!-- <string name="key_descr_change_method">Switch keyboard</string> -->
<!-- <string name="key_descr_voice_typing">Voice typing</string> -->
<!-- <string name="key_descr_copy">Copy</string> -->
<!-- <string name="key_descr_paste">Paste</string> -->
<!-- <string name="key_descr_cut">Cut</string> -->
<!-- <string name="key_descr_selectAll">Select all</string> -->
<!-- <string name="key_descr_shareText">Share text</string> -->
<!-- <string name="key_descr_pasteAsPlainText">Paste as plain text</string> -->
<!-- <string name="key_descr_undo">Undo</string> -->
<!-- <string name="key_descr_redo">Redo</string> -->
<!-- <string name="key_descr_ª">Ordinal Indicator</string> -->
<!-- <string name="key_descr_º">Ordinal Indicator</string> -->
<!-- <string name="key_descr_superscript">Superscript</string> -->
<!-- <string name="key_descr_subscript">Subscript</string> -->
<!-- <string name="key_descr_page_up">Page Up</string> -->
<!-- <string name="key_descr_page_down">Page Down</string> -->
<!-- <string name="key_descr_home">Home</string> -->
<!-- <string name="key_descr_end">End</string> -->
<string name="pref_category_advanced">高级设置</string>
</resources> </resources>

View File

@@ -1,10 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string-array name="pref_accents_entries">
<item>@string/pref_accents_e_all_installed</item>
<item>@string/pref_accents_e_selected</item>
<item>@string/pref_accents_e_none</item>
</string-array>
<string-array name="pref_show_numpad_values"> <string-array name="pref_show_numpad_values">
<item>never</item> <item>never</item>
<item>landscape</item> <item>landscape</item>
@@ -23,11 +18,6 @@
<item>@string/pref_numpad_layout_e_high_first</item> <item>@string/pref_numpad_layout_e_high_first</item>
<item>@string/pref_numpad_layout_e_low_first</item> <item>@string/pref_numpad_layout_e_low_first</item>
</string-array> </string-array>
<string-array name="pref_accents_values">
<item>1</item>
<item>2</item>
<item>4</item>
</string-array>
<string-array name="pref_theme_entries"> <string-array name="pref_theme_entries">
<item>@string/pref_theme_e_system</item> <item>@string/pref_theme_e_system</item>
<item>@string/pref_theme_e_dark</item> <item>@string/pref_theme_e_dark</item>
@@ -36,6 +26,8 @@
<item>@string/pref_theme_e_altblack</item> <item>@string/pref_theme_e_altblack</item>
<item>@string/pref_theme_e_white</item> <item>@string/pref_theme_e_white</item>
<item>@string/pref_theme_e_epaper</item> <item>@string/pref_theme_e_epaper</item>
<item>@string/pref_theme_e_desert</item>
<item>@string/pref_theme_e_jungle</item>
</string-array> </string-array>
<string-array name="pref_theme_values"> <string-array name="pref_theme_values">
<item>system</item> <item>system</item>
@@ -45,6 +37,8 @@
<item>altblack</item> <item>altblack</item>
<item>white</item> <item>white</item>
<item>epaper</item> <item>epaper</item>
<item>desert</item>
<item>jungle</item>
</string-array> </string-array>
<string-array name="pref_swipe_dist_entries"> <string-array name="pref_swipe_dist_entries">
<item>@string/pref_swipe_dist_e_very_short</item> <item>@string/pref_swipe_dist_e_very_short</item>
@@ -60,18 +54,4 @@
<item>25</item> <item>25</item>
<item>35</item> <item>35</item>
</string-array> </string-array>
<string-array name="pref_vibration_entries">
<item>@string/pref_vibration_e_disabled</item>
<item>@string/pref_vibration_e_system</item>
<item>@string/pref_vibration_e_strong</item>
<item>@string/pref_vibration_e_medium</item>
<item>@string/pref_vibration_e_light</item>
</string-array>
<string-array name="pref_vibration_values">
<item>disabled</item>
<item>system</item>
<item>strong</item>
<item>medium</item>
<item>light</item>
</string-array>
</resources> </resources>

View File

@@ -3,7 +3,4 @@
<declare-styleable name="ExtraKeyCheckBoxPreference"> <declare-styleable name="ExtraKeyCheckBoxPreference">
<attr name="index" format="integer"/> <attr name="index" format="integer"/>
</declare-styleable> </declare-styleable>
<declare-styleable name="LayoutListPreference">
<attr name="defaultString" format="string"/>
</declare-styleable>
</resources> </resources>

View File

@@ -2,18 +2,22 @@
<resources> <resources>
<!--DO NOT EDIT. This file is generated, see gen_layouts.py.--> <!--DO NOT EDIT. This file is generated, see gen_layouts.py.-->
<string-array name="pref_layout_values"> <string-array name="pref_layout_values">
<item>none</item> <item>system</item>
<item>latn_qwerty_us</item> <item>latn_qwerty_us</item>
<item>latn_colemak</item> <item>latn_colemak</item>
<item>latn_dvorak</item> <item>latn_dvorak</item>
<item>arab_alt</item> <item>arab_alt</item>
<item>arab_hamvaj_tly</item>
<item>arab_pc</item> <item>arab_pc</item>
<item>arab_pc_ckb</item> <item>arab_pc_ckb</item>
<item>arab_pc_hindu</item>
<item>arab_pc_ir</item> <item>arab_pc_ir</item>
<item>armenian_ph_am</item>
<item>beng_national</item> <item>beng_national</item>
<item>beng_provat</item> <item>beng_provat</item>
<item>cyrl_jcuken_ru</item> <item>cyrl_jcuken_ru</item>
<item>cyrl_jcuken_uk</item> <item>cyrl_jcuken_uk</item>
<item>cyrl_ueishsht</item>
<item>cyrl_yaverti</item> <item>cyrl_yaverti</item>
<item>deva_alt</item> <item>deva_alt</item>
<item>deva_inscript</item> <item>deva_inscript</item>
@@ -22,9 +26,11 @@
<item>hebr_1_il</item> <item>hebr_1_il</item>
<item>hebr_2_il</item> <item>hebr_2_il</item>
<item>latn_azerty_fr</item> <item>latn_azerty_fr</item>
<item>latn_bepo_fr</item>
<item>latn_bone</item> <item>latn_bone</item>
<item>latn_neo2</item> <item>latn_neo2</item>
<item>latn_qwerty_br</item> <item>latn_qwerty_br</item>
<item>latn_qwerty_cz</item>
<item>latn_qwerty_es</item> <item>latn_qwerty_es</item>
<item>latn_qwerty_hu</item> <item>latn_qwerty_hu</item>
<item>latn_qwerty_lv</item> <item>latn_qwerty_lv</item>
@@ -32,29 +38,36 @@
<item>latn_qwerty_pl</item> <item>latn_qwerty_pl</item>
<item>latn_qwerty_ro</item> <item>latn_qwerty_ro</item>
<item>latn_qwerty_se</item> <item>latn_qwerty_se</item>
<item>latn_qwerty_tly</item>
<item>latn_qwerty_tr</item> <item>latn_qwerty_tr</item>
<item>latn_qwerty_vi</item> <item>latn_qwerty_vi</item>
<item>latn_qwertz</item> <item>latn_qwertz</item>
<item>latn_qwertz_cz</item> <item>latn_qwertz_cz</item>
<item>latn_qwertz_cz_multifunctional</item> <item>latn_qwertz_cz_multifunctional</item>
<item>latn_qwertz_de</item> <item>latn_qwertz_de</item>
<item>latn_qwertz_fr_ch</item>
<item>latn_qwertz_hu</item> <item>latn_qwertz_hu</item>
<item>latn_qwertz_sk</item> <item>latn_qwertz_sk</item>
<item>urdu_phonetic_ur</item>
<item>custom</item> <item>custom</item>
</string-array> </string-array>
<string-array name="pref_layout_entries"> <string-array name="pref_layout_entries">
<item>None</item> <item>@string/pref_layout_e_system</item>
<item>QWERTY (US)</item> <item>QWERTY (US)</item>
<item>Colemak</item> <item>Colemak</item>
<item>Dvorak</item> <item>Dvorak</item>
<item>Arabic Alt</item> <item>Arabic Alt</item>
<item>Talysh (تالشی همواج)</item>
<item>Arabic PC</item> <item>Arabic PC</item>
<item>Arabic (کوردی)</item> <item>Kurdish (کوردی)</item>
<item>Arabic PC (Hindu numerals)</item>
<item>Persian PC</item> <item>Persian PC</item>
<item>Armenian</item>
<item>বাংলা (জাতীয়)</item> <item>বাংলা (জাতীয়)</item>
<item>বাংলা (প্রভাত)</item> <item>বাংলা (প্রভাত)</item>
<item>ЙЦУКЕН (Русский)</item> <item>ЙЦУКЕН (Русский)</item>
<item>ЙЦУКЕН (Українська)</item> <item>ЙЦУКЕН (Українська)</item>
<item>УЕИШЩ (Български, БДС)</item>
<item>ЯВЕРТЪ</item> <item>ЯВЕРТЪ</item>
<item>देवनागरी (हिंदी)-2</item> <item>देवनागरी (हिंदी)-2</item>
<item>देवनागरी (हिंदी)-1</item> <item>देवनागरी (हिंदी)-1</item>
@@ -63,9 +76,11 @@
<item>Hebrew 1</item> <item>Hebrew 1</item>
<item>Hebrew 2</item> <item>Hebrew 2</item>
<item>AZERTY (Français)</item> <item>AZERTY (Français)</item>
<item>BEPO (Français)</item>
<item>Bone</item> <item>Bone</item>
<item>Neo 2</item> <item>Neo 2</item>
<item>QWERTY (Brasileiro)</item> <item>QWERTY (Brasileiro)</item>
<item>QWERTY (Czech)</item>
<item>QWERTY (Español)</item> <item>QWERTY (Español)</item>
<item>QWERTY (Magyar)</item> <item>QWERTY (Magyar)</item>
<item>QWERTY (Latvian)</item> <item>QWERTY (Latvian)</item>
@@ -73,14 +88,17 @@
<item>QWERTY (Polski)</item> <item>QWERTY (Polski)</item>
<item>QWERTY (Română)</item> <item>QWERTY (Română)</item>
<item>QWERTY (Swedish)</item> <item>QWERTY (Swedish)</item>
<item>QWERTY (Talysh New Latin)</item>
<item>QWERTY (Türkçe)</item> <item>QWERTY (Türkçe)</item>
<item>QWERTY (Vietnamese)</item> <item>QWERTY (Vietnamese)</item>
<item>QWERTZ</item> <item>QWERTZ</item>
<item>QWERTZ (Czech)</item> <item>QWERTZ (Czech)</item>
<item>QWERTZ Multifunctional (Czech)</item> <item>QWERTZ Multifunctional (Czech)</item>
<item>QWERTZ (Deutsch)</item> <item>QWERTZ (Deutsch)</item>
<item>QWERTZ (Swiss French)</item>
<item>QWERTZ (Magyar)</item> <item>QWERTZ (Magyar)</item>
<item>QWERTZ (Slovak)</item> <item>QWERTZ (Slovak)</item>
<item>Urdu Phonetic</item>
<item>@string/pref_layout_e_custom</item> <item>@string/pref_layout_e_custom</item>
</string-array> </string-array>
<integer-array name="layout_ids"> <integer-array name="layout_ids">
@@ -89,13 +107,17 @@
<item>@xml/latn_colemak</item> <item>@xml/latn_colemak</item>
<item>@xml/latn_dvorak</item> <item>@xml/latn_dvorak</item>
<item>@xml/arab_alt</item> <item>@xml/arab_alt</item>
<item>@xml/arab_hamvaj_tly</item>
<item>@xml/arab_pc</item> <item>@xml/arab_pc</item>
<item>@xml/arab_pc_ckb</item> <item>@xml/arab_pc_ckb</item>
<item>@xml/arab_pc_hindu</item>
<item>@xml/arab_pc_ir</item> <item>@xml/arab_pc_ir</item>
<item>@xml/armenian_ph_am</item>
<item>@xml/beng_national</item> <item>@xml/beng_national</item>
<item>@xml/beng_provat</item> <item>@xml/beng_provat</item>
<item>@xml/cyrl_jcuken_ru</item> <item>@xml/cyrl_jcuken_ru</item>
<item>@xml/cyrl_jcuken_uk</item> <item>@xml/cyrl_jcuken_uk</item>
<item>@xml/cyrl_ueishsht</item>
<item>@xml/cyrl_yaverti</item> <item>@xml/cyrl_yaverti</item>
<item>@xml/deva_alt</item> <item>@xml/deva_alt</item>
<item>@xml/deva_inscript</item> <item>@xml/deva_inscript</item>
@@ -104,9 +126,11 @@
<item>@xml/hebr_1_il</item> <item>@xml/hebr_1_il</item>
<item>@xml/hebr_2_il</item> <item>@xml/hebr_2_il</item>
<item>@xml/latn_azerty_fr</item> <item>@xml/latn_azerty_fr</item>
<item>@xml/latn_bepo_fr</item>
<item>@xml/latn_bone</item> <item>@xml/latn_bone</item>
<item>@xml/latn_neo2</item> <item>@xml/latn_neo2</item>
<item>@xml/latn_qwerty_br</item> <item>@xml/latn_qwerty_br</item>
<item>@xml/latn_qwerty_cz</item>
<item>@xml/latn_qwerty_es</item> <item>@xml/latn_qwerty_es</item>
<item>@xml/latn_qwerty_hu</item> <item>@xml/latn_qwerty_hu</item>
<item>@xml/latn_qwerty_lv</item> <item>@xml/latn_qwerty_lv</item>
@@ -114,14 +138,17 @@
<item>@xml/latn_qwerty_pl</item> <item>@xml/latn_qwerty_pl</item>
<item>@xml/latn_qwerty_ro</item> <item>@xml/latn_qwerty_ro</item>
<item>@xml/latn_qwerty_se</item> <item>@xml/latn_qwerty_se</item>
<item>@xml/latn_qwerty_tly</item>
<item>@xml/latn_qwerty_tr</item> <item>@xml/latn_qwerty_tr</item>
<item>@xml/latn_qwerty_vi</item> <item>@xml/latn_qwerty_vi</item>
<item>@xml/latn_qwertz</item> <item>@xml/latn_qwertz</item>
<item>@xml/latn_qwertz_cz</item> <item>@xml/latn_qwertz_cz</item>
<item>@xml/latn_qwertz_cz_multifunctional</item> <item>@xml/latn_qwertz_cz_multifunctional</item>
<item>@xml/latn_qwertz_de</item> <item>@xml/latn_qwertz_de</item>
<item>@xml/latn_qwertz_fr_ch</item>
<item>@xml/latn_qwertz_hu</item> <item>@xml/latn_qwertz_hu</item>
<item>@xml/latn_qwertz_sk</item> <item>@xml/latn_qwertz_sk</item>
<item>@xml/urdu_phonetic_ur</item>
<item>-1</item> <item>-1</item>
</integer-array> </integer-array>
</resources> </resources>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="app_name" product="debug">Unexpected Keyboard (debug)</string> <string name="app_name_release">Unexpected Keyboard</string>
<string name="app_name" product="default">Unexpected Keyboard</string> <string name="app_name_debug">Unexpected Keyboard (Debug)</string>
<string name="settings_activity_label">Unexpected Keyboard Settings</string> <string name="settings_activity_label">Unexpected Keyboard Settings</string>
<string name="pref_portrait">In portrait mode</string> <string name="pref_portrait">In portrait mode</string>
<string name="pref_landscape">In landscape mode</string> <string name="pref_landscape">In landscape mode</string>
@@ -10,13 +10,12 @@
<string name="pref_keyboard_opacity">Adjust keyboard background opacity</string> <string name="pref_keyboard_opacity">Adjust keyboard background opacity</string>
<string name="pref_key_opacity">Adjust key opacity</string> <string name="pref_key_opacity">Adjust key opacity</string>
<string name="pref_key_activated_opacity">Adjust pressed key opacity</string> <string name="pref_key_activated_opacity">Adjust pressed key opacity</string>
<string name="pref_layout_title">Change keyboard layout</string>
<string name="pref_layout_e_system">System settings</string> <string name="pref_layout_e_system">System settings</string>
<string name="pref_layout_e_custom">Custom layout</string> <string name="pref_layout_e_custom">Custom layout</string>
<string name="pref_accents_title">Accents</string> <string name="pref_layouts_add">Add an alternate layout</string>
<string name="pref_accents_e_all_installed">Show accents for all installed languages</string> <string name="pref_layouts_item">Layout %1$d: %2$s</string>
<string name="pref_accents_e_selected">Only show accents for the selected language</string> <string name="pref_layouts_remove_custom">Remove layout</string>
<string name="pref_accents_e_none">Hide accents</string> <string name="pref_custom_layout_title">Custom layout</string>
<string name="pref_show_numpad_title">Show NumPad</string> <string name="pref_show_numpad_title">Show NumPad</string>
<string name="pref_show_numpad_never">Never</string> <string name="pref_show_numpad_never">Never</string>
<string name="pref_show_numpad_landscape">Only in landscape mode</string> <string name="pref_show_numpad_landscape">Only in landscape mode</string>
@@ -27,6 +26,8 @@
<string name="pref_numpad_layout_e_high_first">High digits first</string> <string name="pref_numpad_layout_e_high_first">High digits first</string>
<string name="pref_numpad_layout_e_low_first">Low digits first</string> <string name="pref_numpad_layout_e_low_first">Low digits first</string>
<string name="pref_extra_keys_title">Add keys to the keyboard</string> <string name="pref_extra_keys_title">Add keys to the keyboard</string>
<string name="pref_extra_keys_custom">Add custom keys</string>
<string name="pref_extra_keys_internal">Select keys to add to the keyboard</string>
<string name="pref_second_layout_title">Secondary layout</string> <string name="pref_second_layout_title">Secondary layout</string>
<string name="pref_second_layout_none">None</string> <string name="pref_second_layout_none">None</string>
<string name="pref_category_typing">Typing</string> <string name="pref_category_typing">Typing</string>
@@ -41,8 +42,10 @@
<string name="pref_autocapitalisation_summary">Press Shift at the beginning of a sentence</string> <string name="pref_autocapitalisation_summary">Press Shift at the beginning of a sentence</string>
<string name="pref_switch_input_immediate_title">Switch to the last used keyboard</string> <string name="pref_switch_input_immediate_title">Switch to the last used keyboard</string>
<string name="pref_switch_input_immediate_summary">Behavior of the keyboard-switching key</string> <string name="pref_switch_input_immediate_summary">Behavior of the keyboard-switching key</string>
<string name="pref_vibrate_title">Vibration</string> <string name="pref_vibrate_custom">Custom vibration</string>
<string name="pref_vibrate_summary">Enable/disable vibration on keypress</string> <string name="pref_vibrate_duration_title">Vibration intensity</string>
<string name="pref_pin_entry_enabled_title">Pin entry layout</string>
<string name="pref_pin_entry_enabled_summary">When typing numbers, dates and phone numbers</string>
<string name="pref_category_style">Style</string> <string name="pref_category_style">Style</string>
<string name="pref_margin_bottom_title">Margin bottom</string> <string name="pref_margin_bottom_title">Margin bottom</string>
<string name="pref_keyboard_height_title">Keyboard height</string> <string name="pref_keyboard_height_title">Keyboard height</string>
@@ -57,6 +60,8 @@
<string name="pref_theme_e_altblack">Alternative Black</string> <string name="pref_theme_e_altblack">Alternative Black</string>
<string name="pref_theme_e_white">White</string> <string name="pref_theme_e_white">White</string>
<string name="pref_theme_e_epaper">ePaper</string> <string name="pref_theme_e_epaper">ePaper</string>
<string name="pref_theme_e_desert">Desert</string>
<string name="pref_theme_e_jungle">Jungle</string>
<string name="pref_swipe_dist_e_very_short">Very short</string> <string name="pref_swipe_dist_e_very_short">Very short</string>
<string name="pref_swipe_dist_e_short">Short</string> <string name="pref_swipe_dist_e_short">Short</string>
<string name="pref_swipe_dist_e_default">Normal</string> <string name="pref_swipe_dist_e_default">Normal</string>
@@ -64,14 +69,6 @@
<string name="pref_swipe_dist_e_very_far">Very far</string> <string name="pref_swipe_dist_e_very_far">Very far</string>
<string name="pref_key_horizontal_space">Horizontal spacing between the keys</string> <string name="pref_key_horizontal_space">Horizontal spacing between the keys</string>
<string name="pref_key_vertical_space">Vertical spacing between the keys</string> <string name="pref_key_vertical_space">Vertical spacing between the keys</string>
<string name="pref_category_advanced">Advanced</string>
<string name="pref_custom_layout_title">Custom layout</string>
<string name="pref_custom_layout_summary">See the source code. This option is not meant to be used.</string>
<string name="pref_vibration_e_disabled">Disabled</string>
<string name="pref_vibration_e_system">System</string>
<string name="pref_vibration_e_strong">Strong</string>
<string name="pref_vibration_e_medium">Medium</string>
<string name="pref_vibration_e_light">Light</string>
<string name="key_action_next">Next</string> <string name="key_action_next">Next</string>
<string name="key_action_done">Done</string> <string name="key_action_done">Done</string>
<string name="key_action_go">Go</string> <string name="key_action_go">Go</string>
@@ -79,7 +76,30 @@
<string name="key_action_search">Search</string> <string name="key_action_search">Search</string>
<string name="key_action_send">Send</string> <string name="key_action_send">Send</string>
<string name="launcher_button_imesettings">Enable keyboard</string> <string name="launcher_button_imesettings">Enable keyboard</string>
<string name="launcher_button_imepicker">Select keyboard</string>
<string name="launcher_description">This application is a virtual keyboard. Go to the system settings by clicking on the button below and enable Unexpected-Keyboard.</string> <string name="launcher_description">This application is a virtual keyboard. Go to the system settings by clicking on the button below and enable Unexpected-Keyboard.</string>
<string name="launcher_sourcecode">This is an free and open source application. You can find the source code or report bugs on <a href="https://github.com/Julow/Unexpected-Keyboard/">Github</a>.</string> <string name="launcher_sourcecode">This is an free and open source application. You can find the source code or report bugs on Github.</string>
<string name="launcher_tryhere">After enabling, you can try the keyboard here:</string> <string name="launcher_tryhere">After enabling, you can try the keyboard here:</string>
<string name="key_descr_capslock">Caps lock</string>
<string name="key_descr_switch_greekmath">Greek &amp; math symbols</string>
<string name="key_descr_change_method">Switch keyboard</string>
<string name="key_descr_voice_typing">Voice typing</string>
<string name="key_descr_copy">Copy</string>
<string name="key_descr_paste">Paste</string>
<string name="key_descr_cut">Cut</string>
<string name="key_descr_selectAll">Select all</string>
<string name="key_descr_shareText">Share text</string>
<string name="key_descr_pasteAsPlainText">Paste as plain text</string>
<string name="key_descr_undo">Undo</string>
<string name="key_descr_redo">Redo</string>
<string name="key_descr_ª">Ordinal Indicator</string>
<string name="key_descr_º">Ordinal Indicator</string>
<string name="key_descr_superscript">Superscript</string>
<string name="key_descr_subscript">Subscript</string>
<string name="key_descr_page_up">Page Up</string>
<string name="key_descr_page_down">Page Down</string>
<string name="key_descr_home">Home</string>
<string name="key_descr_end">End</string>
<!-- Unused -->
<string name="pref_category_advanced">Advanced</string>
</resources> </resources>

View File

@@ -8,15 +8,6 @@
<item name="android:textColor">?attr/emoji_key_text</item> <item name="android:textColor">?attr/emoji_key_text</item>
<item name="android:textSize">18dp</item> <item name="android:textSize">18dp</item>
</style> </style>
<style name="emojiKeyButton">
<item name="android:layout_width">0px</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_weight">1</item>
<item name="android:padding">0px</item>
<item name="android:background">?attr/emoji_key_bg</item>
<item name="android:textColor">?attr/emoji_key_text</item>
<item name="android:textSize">18dp</item>
</style>
<style name="emojiGridButton"> <style name="emojiGridButton">
<item name="android:layout_width">fill_parent</item> <item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">fill_parent</item> <item name="android:layout_height">fill_parent</item>
@@ -31,4 +22,5 @@
<item name="android:layout_marginHorizontal">16dp</item> <item name="android:layout_marginHorizontal">16dp</item>
<item name="android:layout_gravity">center</item> <item name="android:layout_gravity">center</item>
</style> </style>
<style name="appTheme" parent="@android:style/Theme.DeviceDefault.DayNight"/>
</resources> </resources>

View File

@@ -137,4 +137,42 @@
<item name="emoji_button_bg">#ffffff</item> <item name="emoji_button_bg">#ffffff</item>
<item name="emoji_color">#000000</item> <item name="emoji_color">#000000</item>
</style> </style>
<style name="Desert" parent="@style/BaseTheme">
<item name="android:isLightTheme">true</item>
<item name="colorKeyboard">#ffe0b2</item>
<item name="colorKey">#fff3e0</item>
<item name="colorKeyActivated">#ffcc80</item>
<item name="colorLabel">#000000</item>
<item name="colorLabelActivated">#ffffff</item>
<item name="colorLabelLocked">#e65100</item>
<item name="secondaryLightOffset">0.1</item>
<item name="colorSubLabel">#333333</item>
<item name="keyBorderWidth">0.0dip</item>
<item name="keyBorderWidthActivated">0.0dip</item>
<item name="keyBorderColorLeft">#000000</item>
<item name="keyBorderColorTop">#000000</item>
<item name="keyBorderColorRight">#000000</item>
<item name="keyBorderColorBottom">#000000</item>
<item name="emoji_button_bg">?colorKeyActivated</item>
<item name="emoji_color">#000000</item>
</style>
<style name="Jungle" parent="@style/BaseTheme">
<item name="android:isLightTheme">true</item>
<item name="colorKeyboard">#4db6ac</item>
<item name="colorKey">#e0f2f1</item>
<item name="colorKeyActivated">#00695c</item>
<item name="colorLabel">#000000</item>
<item name="colorLabelActivated">#ffffff</item>
<item name="colorLabelLocked">#64ffda</item>
<item name="secondaryLightOffset">0.0</item>
<item name="colorSubLabel">#004d40</item>
<item name="keyBorderWidth">0.0dip</item>
<item name="keyBorderWidthActivated">0.0dip</item>
<item name="keyBorderColorLeft">#00f0f0f0</item>
<item name="keyBorderColorTop">#00f0f0f0</item>
<item name="keyBorderColorRight">#00eeeeee</item>
<item name="keyBorderColorBottom">#00eeeeee</item>
<item name="emoji_button_bg">?colorKeyActivated</item>
<item name="emoji_color">#000000</item>
</style>
</resources> </resources>

View File

@@ -5,6 +5,6 @@
<dimen name="emoji_type_button_height">56dp</dimen> <dimen name="emoji_type_button_height">56dp</dimen>
<dimen name="emoji_grid_height">250dp</dimen> <dimen name="emoji_grid_height">250dp</dimen>
<dimen name="emoji_text_size">28dp</dimen> <dimen name="emoji_text_size">28dp</dimen>
<bool name="debug_logs" product="debug">true</bool> <dimen name="pref_button_size">28dp</dimen>
<bool name="debug_logs" product="default">false</bool> <bool name="debug_logs">false</bool> <!-- Will be overwritten automatically by Gradle for the debug build variant -->
</resources> </resources>

View File

@@ -1,43 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Adapted from standard SIRI 9147 -->
<keyboard name="Persian PC" script="arabic">
<row>
<key key0="ض" key2="۱"/>
<key key0="ص" key2="۲"/>
<key key0="ث" key2="۳"/>
<key key0="ق" key2="۴"/>
<key key0="ف" key2="۵"/>
<key key0="غ" key1="۶" key2="،"/>
<key key0="ع" key1="۷"/>
<key key0="ه" key1="۸"/>
<key key0="خ" key1="۹"/>
<key key0="ح" key1="۰"/>
<key key0="ج"/>
</row>
<row>
<key key0="ش" key2="\@"/>
<key key0="س" key2="\#"/>
<key key0="ی" key2="﷼"/>
<key key0="ب" key2="٪"/>
<key key0="ل" key2="&amp;"/>
<key key0="ا" key1="آ" key2="ء" key4="-"/>
<key key0="ت" key1="&#x200C;" key2="+"/>
<key key0="ن" key1="("/>
<key key0="م" key1=")"/>
<key key0="ک"/>
<key key0="گ"/>
</row>
<row>
<key key0="ظ" key2="&#1567;"/>
<key key0="ط"/>
<key key0="ز" key2="«"/>
<key key0="ر" key2="»"/>
<key key0="ژ" key2="."/>
<key key0="ذ" key2=":"/>
<key key0="د" key1="؛"/>
<key key0="پ" key1="!"/>
<key key0="و" key1="ـ"/>
<key key0="چ"/>
<key width="1.0" key0="backspace" key2="delete"/>
</row>
</keyboard>

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<row height="0.95"> <row height="0.95">
<key width="1.7" key0="ctrl" key1="loc switch_greekmath" key2="loc meta" key4="switch_numeric"/> <key width="1.7" key0="ctrl" key1="loc switch_greekmath" key2="loc meta" key4="switch_numeric"/>
<key width="1.1" key0="fn" key1="loc alt" key2="change_method" key3="switch_emoji" key4="config"/> <key width="1.1" key0="fn" key1="loc alt" key2="loc change_method" key3="switch_emoji" key4="config"/>
<key width="4.4" key0="space" key7="switch_second" key5="left" key6="right" slider="true"/> <key width="4.4" key0="space" key7="switch_forward" key8="switch_backward" key5="cursor_left" key6="cursor_right" slider="true"/>
<key width="1.1" key0="loc voice_typing" key7="up" key6="right" key5="left" key8="down"/> <key width="1.1" key7="up" key6="right" key5="left" key8="down" key1="loc home" key2="loc page_up" key3="loc end" key4="loc page_down"/>
<key width="1.7" key0="enter" key2="action"/> <key width="1.7" key0="enter" key1="loc voice_typing" key2="action"/>
</row> </row>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- The bottom row used in the emoji pane. -->
<keyboard bottom_row="false">
<row height="0.95">
<key key0="switch_back_emoji"/>
<key width="4" key0="space" key5="cursor_left" key6="cursor_right" slider="true"/>
<key key0="backspace"/>
<key key0="enter"/>
</row>
</keyboard>

View File

@@ -2,37 +2,37 @@
<keyboard bottom_row="false"> <keyboard bottom_row="false">
<row> <row>
<key key0="θ" key2="^"/> <key key0="θ" key2="^"/>
<key key0="δ" key1="⌊" key2="" key3="↔" key4="⊂"/> <key key0="ω" key1="⌊" key2="" key3="↔" key4="⊂"/>
<key key0="ϛ" key1="⌋" key2="∧" key3="↑" key4="⊃"/> <key key0="ε" key1="⌋" key2="∧" key3="↑" key4="⊃"/>
<key key0="α" key1="⌈" key2="⊥" key3="↕" key4="∀"/> <key key0="ρ" key1="⌈" key2="⊥" key3="↕" key4="∀"/>
<key key0="ξ" key1="⌉" key2="∡" key4="⊷"/> <key key0="τ" key1="⌉" key2="∡" key4="⊷"/>
<key key0="π" key1="∥" key3="≪" key4="7"/> <key key0="ψ" key1="∥" key3="≪" key4="7"/>
<key key0="ψ" key1="⌀" key2="⟨" key3="≡" key4="8"/> <key key0="υ" key1="⌀" key2="⟨" key3="≡" key4="8"/>
<key key0="λ" key1="∞" key2="⟩" key3="≫" key4="9"/> <key key0="ι" key1="∞" key2="⟩" key3="≫" key4="9"/>
<key key0="μ" key1="∝" key3="□" key4="f11_placeholder"/> <key key0="ο" key1="∝" key3="□" key4="f11_placeholder"/>
<key key0="ω" key1="∅" key3="∘" key4="f12_placeholder"/> <key key0="π" key1="∅" key3="∘" key4="f12_placeholder"/>
</row> </row>
<row> <row>
<key key0="χ" key4=""/> <key key0="α" key4=""/>
<key key0="τ" key3="←" key4="∂"/> <key key0="σ" key3="←" key4="∂"/>
<key key0="ι" key3="↓" key4="∫"/> <key key0="δ" key3="↓" key4="∫"/>
<key key0="ε" key3="→" key4="∃"/> <key key0="φ" key3="→" key4="∃"/>
<key key0="ο" key4="∈"/> <key key0="γ" key4="∈"/>
<key key0="β" key1="⊕" key4="4"/> <key key0="η" key1="⊕" key4="4"/>
<key key0="ν" key1="⊖" key3="" key4="5"/> <key key0="ξ" key1="⊖" key3="" key4="5"/>
<key key0="ρ" key1="⊙" key3="" key4="6"/> <key key0="κ" key1="⊙" key3="" key4="6"/>
<key key0="σ" key1="⊗"/> <key key0="λ" key1="⊗"/>
<key key0="γ" key1="⌀"/> <key key0="ϡ" key1="⌀"/>
</row> </row>
<row> <row>
<key width="1.5" key0="shift" key2="loc capslock"/> <key width="1.5" key0="shift" key2="loc capslock"/>
<key key0="φ" key3="⇌" key4="√"/> <key key0="ζ" key3="⇌" key4="√"/>
<key key0="η" key3="accent_arrow_right" key4=""/> <key key0="χ" key3="accent_arrow_right" key4=""/>
<key key0="ϡ" key4="∩"/> <key key0="ϛ" key4="∩"/>
<key key0="υ" key3="∇" key4="ℵ"/> <key key0="ϟ" key3="∇" key4="ℵ"/>
<key key0="ζ" key1="≤" key3="" key4="1"/> <key key0="β" key1="≤" key3="" key4="1"/>
<key key0="Ϟ" key1="≠" key3="" key4="2"/> <key key0="ν" key1="≠" key3="" key4="2"/>
<key key0="κ" key1="≥" key3="×" key4="3"/> <key key0="μ" key1="≥" key3="×" key4="3"/>
<key width="1.5" key0="backspace" key3="delete"/> <key width="1.5" key0="backspace" key3="delete"/>
</row> </row>
<row height="0.95"> <row height="0.95">

View File

@@ -1,35 +1,40 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<input-method xmlns:android="http://schemas.android.com/apk/res/android" android:settingsActivity="juloo.keyboard2.SettingsActivity" android:supportsSwitchingToNextInputMethod="true"> <input-method xmlns:android="http://schemas.android.com/apk/res/android" android:settingsActivity="juloo.keyboard2.SettingsActivity" android:supportsSwitchingToNextInputMethod="true">
<subtype android:label="%s" android:languageTag="ar" android:imeSubtypeLocale="ar" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=arabic,default_layout=arab_ibm"/> <subtype android:label="%s" android:languageTag="ar" android:imeSubtypeLocale="ar" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=arabic,default_layout=arab_pc_hindu"/>
<subtype android:label="%s" android:languageTag="ar" android:imeSubtypeLocale="ar_TN" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=arabic,default_layout=arab_pc"/>
<subtype android:label="%s" android:languageTag="ay" android:imeSubtypeLocale="ay_AM" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=armenian,default_layout=armenian_ph_am"/>
<subtype android:label="%s" android:languageTag="be" android:imeSubtypeLocale="be_BY" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=cyrillic,default_layout=cyrl_jcuken_ru,extra_keys=ґ|є|і|ї|ў"/> <subtype android:label="%s" android:languageTag="be" android:imeSubtypeLocale="be_BY" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=cyrillic,default_layout=cyrl_jcuken_ru,extra_keys=ґ|є|і|ї|ў"/>
<subtype android:label="%s" android:languageTag="bg" android:imeSubtypeLocale="bg_BG" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=cyrillic,default_layout=cyrl_yaverti,extra_keys=€"/> <subtype android:label="%s" android:languageTag="bg" android:imeSubtypeLocale="bg_BG" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=cyrillic,default_layout=cyrl_ueishsht,extra_keys=€"/>
<subtype android:label="%s" android:languageTag="bn" android:imeSubtypeLocale="bn_BD" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_us,extra_keys=৳"/> <subtype android:label="%s" android:languageTag="bn" android:imeSubtypeLocale="bn_BD" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_us,extra_keys=৳"/>
<subtype android:label="%s" android:languageTag="cs" android:imeSubtypeLocale="cs_CZ" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwertz_cz,extra_keys=a|accent_cedille|accent_circonflexe"/> <subtype android:label="%s" android:languageTag="cs" android:imeSubtypeLocale="cs_CZ" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwertz_cz,extra_keys=accent_aigu:á:é:í:ó:ú:ý|accent_ring:ů|accent_caron:č:ě:ň:ř:š:ž:ď:ť"/>
<subtype android:label="%s" android:languageTag="de" android:imeSubtypeLocale="de_DE" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwertz_de,extra_keys=accent_trema|ß|€"/> <subtype android:label="%s" android:languageTag="de" android:imeSubtypeLocale="de_DE" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwertz_de,extra_keys=accent_trema:ä:ö:ü|ß|€"/>
<subtype android:label="%s" android:languageTag="el" android:imeSubtypeLocale="el" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=grek_qwerty,extra_keys=£|€"/> <subtype android:label="%s" android:languageTag="el" android:imeSubtypeLocale="el" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=grek_qwerty,extra_keys=£|€"/>
<subtype android:label="%s" android:languageTag="en-GB" android:imeSubtypeLocale="en_GB" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_us,extra_keys=£|€"/> <subtype android:label="%s" android:languageTag="en-GB" android:imeSubtypeLocale="en_GB" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_us,extra_keys=£|€"/>
<subtype android:label="%s" android:languageTag="en-US" android:imeSubtypeLocale="en_US" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_us"/> <subtype android:label="%s" android:languageTag="en-US" android:imeSubtypeLocale="en_US" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_us"/>
<subtype android:label="%s" android:languageTag="es" android:imeSubtypeLocale="es_ES" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_es,extra_keys=accent_grave|accent_aigu|accent_tilde|accent_trema|€"/> <subtype android:label="%s" android:languageTag="es" android:imeSubtypeLocale="es_ES" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_es,extra_keys=accent_aigu:á:é:í:ó:ú|accent_tilde:ñ|accent_grave|accent_trema|€"/>
<subtype android:label="%s" android:languageTag="fr" android:imeSubtypeLocale="fr_FR" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_azerty_fr,extra_keys=accent_grave|accent_aigu|accent_circonflexe|accent_cedille|accent_trema|€"/> <subtype android:label="%s" android:languageTag="fa" android:imeSubtypeLocale="fa_IR" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=arab_pc_ir"/>
<subtype android:label="%s" android:languageTag="fr-CH" android:imeSubtypeLocale="fr_CH" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwertz_fr_ch,extra_keys=accent_grave:à:è:ù|accent_aigu:é|accent_circonflexe:â:ê:ô|accent_cedille:ç|accent_trema:ë:ï:ü:ÿ|€"/>
<subtype android:label="%s" android:languageTag="fr-FR" android:imeSubtypeLocale="fr_FR" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_azerty_fr,extra_keys=accent_grave:à:è:ù@a|accent_aigu:é@e|accent_circonflexe:â:ê:ô@e|accent_cedille:ç@c|accent_trema:ë:ï:ü:ÿ@l|€"/>
<subtype android:label="%s" android:languageTag="he" android:imeSubtypeLocale="he_IL" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=hebrew,default_layout=hebr_1_il,extra_keys=₪|€"/> <subtype android:label="%s" android:languageTag="he" android:imeSubtypeLocale="he_IL" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=hebrew,default_layout=hebr_1_il,extra_keys=₪|€"/>
<subtype android:label="%s" android:languageTag="hi" android:imeSubtypeLocale="hi_IN" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=devanagari,default_layout=deva_inscript,extra_keys=₹"/> <subtype android:label="%s" android:languageTag="hi" android:imeSubtypeLocale="hi_IN" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=devanagari,default_layout=deva_inscript,extra_keys=₹"/>
<subtype android:label="%s" android:languageTag="hu" android:imeSubtypeLocale="hu_HU" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwertz_hu,extra_keys=accent_aigu|accent_trema|accent_ogonek|€"/> <subtype android:label="%s" android:languageTag="hu" android:imeSubtypeLocale="hu_HU" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwertz_hu,extra_keys=accent_aigu:á:é:í:ó:ú|accent_trema:ö:ü|accent_ogonek|accent_double_aigu:ő:ű|€"/>
<subtype android:label="%s" android:languageTag="is" android:imeSubtypeLocale="is_IS" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_us,extra_keys=ð|þ|ö|æ|accent_aigu"/> <subtype android:label="%s" android:languageTag="is" android:imeSubtypeLocale="is_IS" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_us,extra_keys=ð|þ|æ|accent_trema:ö|accent_aigu:á:é:í:ó:ú:ý"/>
<subtype android:label="%s" android:languageTag="it" android:imeSubtypeLocale="it_IT" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_us,extra_keys=accent_grave|accent_aigu|€|ə"/> <subtype android:label="%s" android:languageTag="it" android:imeSubtypeLocale="it_IT" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_us,extra_keys=accent_grave:à:è:ì:ò:ù|accent_aigu:é:ó|accent_circonflexe:î|€|ə"/>
<subtype android:label="%s" android:languageTag="ko" android:imeSubtypeLocale="ko_KR" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=hangul,default_layout=latn_qwerty_us"/> <subtype android:label="%s" android:languageTag="ko" android:imeSubtypeLocale="ko_KR" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=hangul,default_layout=latn_qwerty_us"/>
<subtype android:label="%s" android:languageTag="lt" android:imeSubtypeLocale="lt_LT" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_us,extra_keys=accent_ogonek|accent_caron|accent_dot_above|accent_macron|€"/> <subtype android:label="%s" android:languageTag="lt" android:imeSubtypeLocale="lt_LT" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_us,extra_keys=accent_ogonek:ą:ę:į:ų|accent_caron:č:š:ž|accent_dot_above|accent_macron|€"/>
<subtype android:label="%s" android:languageTag="lv" android:imeSubtypeLocale="lv_LV" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_lv,extra_keys=accent_caron|accent_cedille|accent_macron|€"/> <subtype android:label="%s" android:languageTag="lv" android:imeSubtypeLocale="lv_LV" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_lv,extra_keys=accent_macron:ā:ē:ī:ū|accent_caron:č:š:ž|accent_ogonek:ķ:ļ:ņ|accent_cedille:ģ|€"/>
<subtype android:label="%s" android:languageTag="mr" android:imeSubtypeLocale="mr_IN" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=devanagari,default_layout=deva_inscript,extra_keys=₹"/> <subtype android:label="%s" android:languageTag="mr" android:imeSubtypeLocale="mr_IN" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=devanagari,default_layout=deva_inscript,extra_keys=₹"/>
<subtype android:label="%s" android:languageTag="ne" android:imeSubtypeLocale="ne_NE" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=devanagari,default_layout=deva_inscript,extra_keys=₹"/> <subtype android:label="%s" android:languageTag="ne" android:imeSubtypeLocale="ne_NE" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=devanagari,default_layout=deva_inscript,extra_keys=₹"/>
<subtype android:label="%s" android:languageTag="nl-BE" android:imeSubtypeLocale="nl_BE" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_azerty_fr,extra_keys=accent_grave|accent_aigu|accent_circonflexe|accent_cedille|accent_trema|€"/> <subtype android:label="%s" android:languageTag="nl-BE" android:imeSubtypeLocale="nl_BE" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_azerty_fr,extra_keys=accent_grave|accent_aigu:á:é:í:ó:ú:ý:j́|accent_circonflexe|accent_cedille|accent_trema|€"/>
<subtype android:label="%s" android:languageTag="no" android:imeSubtypeLocale="no_NO" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_no,extra_keys=€|æ|å|ø"/> <subtype android:label="%s" android:languageTag="no" android:imeSubtypeLocale="no_NO" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_no,extra_keys=€|æ|å|ø|accent_aigu:é:ó|accent_grave:è:ò:ù|accent_circonflexe:ê:ô"/>
<subtype android:label="%s" android:languageTag="pl" android:imeSubtypeLocale="pl_PL" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_pl"/> <subtype android:label="%s" android:languageTag="pl" android:imeSubtypeLocale="pl_PL" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_pl"/>
<subtype android:label="%s" android:languageTag="pt" android:imeSubtypeLocale="pt_BR" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_pt,extra_keys=accent_aigu|accent_cedille|accent_circonflexe|accent_grave|accent_tilde|€"/> <subtype android:label="%s" android:languageTag="pt" android:imeSubtypeLocale="pt_BR" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_pt,extra_keys=accent_aigu:á:é:í:ó:ú|accent_cedille|accent_circonflexe:â:ê:ô|accent_grave:à:ò|accent_tilde:ã:õ|€|ª|º"/>
<subtype android:label="%s" android:languageTag="ro" android:imeSubtypeLocale="ro_RO" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_ro,extra_keys=ă|â|î|ș|ț|€|$"/> <subtype android:label="%s" android:languageTag="ro" android:imeSubtypeLocale="ro_RO" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_ro,extra_keys=ă|â|î|ș|ț|€|$"/>
<subtype android:label="%s" android:languageTag="ru" android:imeSubtypeLocale="ru_RU" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=cyrl_jcuken_ru"/> <subtype android:label="%s" android:languageTag="ru" android:imeSubtypeLocale="ru_RU" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=cyrl_jcuken_ru"/>
<subtype android:label="%s" android:languageTag="sk" android:imeSubtypeLocale="sk_SK" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwertz_sk,extra_keys=é|ě|ŕ|ř|ť|ž|ü|ú|ů|í|ö|ó|ô|á|ä|ś|š|ď|ĺ|ľ|ý|č|ň"/> <subtype android:label="%s" android:languageTag="sk" android:imeSubtypeLocale="sk_SK" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwertz_sk,extra_keys=accent_caron:ě:ř:ž:š:č:ň:ď:ľ:ť|accent_ring:ů|accent_circonflexe:ô|accent_trema:ä:ü:ö|accent_aigu:á:é:í:ó:ú:ŕ:ś:ĺ:ý"/>
<subtype android:label="%s" android:languageTag="sv" android:imeSubtypeLocale="sv_SE" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_se,extra_keys=accent_aigu|accent_trema|accent_ring|€"/> <subtype android:label="%s" android:languageTag="sv" android:imeSubtypeLocale="sv_SE" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_se,extra_keys=accent_aigu|accent_trema:ä:ö|accent_ring|€"/>
<subtype android:label="%s" android:languageTag="tr" android:imeSubtypeLocale="tr_TR" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_tr,extra_keys=accent_cedille|accent_trema|₺|ı|ğ"/> <subtype android:label="%s" android:languageTag="tr" android:imeSubtypeLocale="tr_TR" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_tr,extra_keys=accent_cedille:ç:ş|accent_trema:ö:ü|accent_circonflexe:â:î:û|₺|ı|ğ"/>
<subtype android:label="%s" android:languageTag="uk" android:imeSubtypeLocale="uk_UA" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=cyrillic,default_layout=cyrl_jcuken_uk,extra_keys=ґ|є|і"/> <subtype android:label="%s" android:languageTag="tly" android:imeSubtypeLocale="tly_AZ" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_tly,extra_keys=á|ú|â|ê|ı|š|ž"/>
<subtype android:label="%s" android:languageTag="uk" android:imeSubtypeLocale="uk_UA" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=cyrillic,default_layout=cyrl_jcuken_uk,extra_keys=ґ|є|і|ї|₴"/>
<subtype android:label="%s" android:languageTag="vi" android:imeSubtypeLocale="vi_VN" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_vi"/> <subtype android:label="%s" android:languageTag="vi" android:imeSubtypeLocale="vi_VN" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="script=latin,default_layout=latn_qwerty_vi"/>
</input-method> </input-method>

View File

@@ -10,7 +10,7 @@
<key shift="1.0" key0="4" indication="GHI"/> <key shift="1.0" key0="4" indication="GHI"/>
<key key0="5" indication="JKL"/> <key key0="5" indication="JKL"/>
<key key0="6" indication="MNO"/> <key key0="6" indication="MNO"/>
<key key0="(" key3=":" key4="-"/> <key key0="(" key2="=" key3=":" key4="-"/>
</row> </row>
<row> <row>
<key shift="1.0" key0="7" indication="PQRS"/> <key shift="1.0" key0="7" indication="PQRS"/>

View File

@@ -1,85 +1,50 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto">
<PreferenceCategory android:title="@string/pref_category_layout"> <PreferenceCategory android:title="@string/pref_category_layout">
<juloo.keyboard2.LayoutListPreference android:key="layout" android:title="@string/pref_layout_title" app:defaultString="@string/pref_layout_e_system"/> <juloo.keyboard2.prefs.LayoutsPreference/>
<juloo.keyboard2.LayoutListPreference android:key="second_layout" android:title="@string/pref_second_layout_title" app:defaultString="@string/pref_second_layout_none"/>
<ListPreference android:key="accents" android:title="@string/pref_accents_title" android:summary="%s" android:defaultValue="1" android:entries="@array/pref_accents_entries" android:entryValues="@array/pref_accents_values"/>
<ListPreference android:key="show_numpad" android:title="@string/pref_show_numpad_title" android:summary="%s" android:defaultValue="1" android:entries="@array/pref_show_numpad_entries" android:entryValues="@array/pref_show_numpad_values"/>
<CheckBoxPreference android:key="number_row" android:title="@string/pref_number_row_title" android:summary="@string/pref_number_row_summary" android:defaultValue="false"/>
<PreferenceScreen android:title="@string/pref_extra_keys_title"> <PreferenceScreen android:title="@string/pref_extra_keys_title">
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="0"/> <PreferenceCategory android:title="@string/pref_extra_keys_custom">
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="1"/> <juloo.keyboard2.prefs.CustomExtraKeysPreference/>
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="2"/> </PreferenceCategory>
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="3"/> <juloo.keyboard2.prefs.ExtraKeysPreference android:title="@string/pref_extra_keys_internal"/>
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="4"/>
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="5"/>
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="6"/>
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="7"/>
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="8"/>
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="9"/>
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="10"/>
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="11"/>
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="12"/>
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="13"/>
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="14"/>
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="15"/>
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="16"/>
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="17"/>
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="18"/>
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="19"/>
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="20"/>
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="21"/>
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="22"/>
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="23"/>
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="24"/>
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="25"/>
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="26"/>
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="27"/>
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="28"/>
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="29"/>
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="30"/>
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="31"/>
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="32"/>
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="33"/>
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="34"/>
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="35"/>
</PreferenceScreen> </PreferenceScreen>
<CheckBoxPreference android:key="number_row" android:title="@string/pref_number_row_title" android:summary="@string/pref_number_row_summary" android:defaultValue="false"/>
<ListPreference android:key="show_numpad" android:title="@string/pref_show_numpad_title" android:summary="%s" android:defaultValue="1" android:entries="@array/pref_show_numpad_entries" android:entryValues="@array/pref_show_numpad_values"/>
<ListPreference android:key="numpad_layout" android:title="@string/pref_numpad_layout" android:summary="%s" android:defaultValue="high_first" android:entries="@array/pref_numpad_layout_entries" android:entryValues="@array/pref_numpad_layout_values"/> <ListPreference android:key="numpad_layout" android:title="@string/pref_numpad_layout" android:summary="%s" android:defaultValue="high_first" android:entries="@array/pref_numpad_layout_entries" android:entryValues="@array/pref_numpad_layout_values"/>
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory android:title="@string/pref_category_typing"> <PreferenceCategory android:title="@string/pref_category_typing">
<ListPreference android:key="swipe_dist" android:title="@string/pref_swipe_dist_title" android:summary="@string/pref_swipe_dist_summary" android:defaultValue="15" android:entries="@array/pref_swipe_dist_entries" android:entryValues="@array/pref_swipe_dist_values"/> <ListPreference android:key="swipe_dist" android:title="@string/pref_swipe_dist_title" android:summary="@string/pref_swipe_dist_summary" android:defaultValue="15" android:entries="@array/pref_swipe_dist_entries" android:entryValues="@array/pref_swipe_dist_values"/>
<juloo.common.IntSlideBarPreference android:key="longpress_timeout" android:title="@string/pref_long_timeout_title" android:summary="%sms" android:defaultValue="600" min="50" max="2000"/> <juloo.keyboard2.prefs.IntSlideBarPreference android:key="longpress_timeout" android:title="@string/pref_long_timeout_title" android:summary="%sms" android:defaultValue="600" min="50" max="2000"/>
<juloo.common.IntSlideBarPreference android:key="longpress_interval" android:title="@string/pref_long_interval_title" android:summary="%sms" android:defaultValue="25" min="5" max="100"/> <juloo.keyboard2.prefs.IntSlideBarPreference android:key="longpress_interval" android:title="@string/pref_long_interval_title" android:summary="%sms" android:defaultValue="25" min="5" max="100"/>
<CheckBoxPreference android:key="lock_double_tap" android:title="@string/pref_lock_double_tap_title" android:summary="@string/pref_lock_double_tap_summary" android:defaultValue="false"/> <CheckBoxPreference android:key="lock_double_tap" android:title="@string/pref_lock_double_tap_title" android:summary="@string/pref_lock_double_tap_summary" android:defaultValue="false"/>
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory android:title="@string/pref_category_behavior"> <PreferenceCategory android:title="@string/pref_category_behavior">
<CheckBoxPreference android:key="autocapitalisation" android:title="@string/pref_autocapitalisation_title" android:summary="@string/pref_autocapitalisation_summary" android:defaultValue="true"/> <CheckBoxPreference android:key="autocapitalisation" android:title="@string/pref_autocapitalisation_title" android:summary="@string/pref_autocapitalisation_summary" android:defaultValue="true"/>
<CheckBoxPreference android:key="switch_input_immediate" android:title="@string/pref_switch_input_immediate_title" android:summary="@string/pref_switch_input_immediate_summary" android:defaultValue="false"/> <CheckBoxPreference android:key="switch_input_immediate" android:title="@string/pref_switch_input_immediate_title" android:summary="@string/pref_switch_input_immediate_summary" android:defaultValue="false"/>
<ListPreference android:key="vibration_behavior" android:title="@string/pref_vibrate_title" android:summary="@string/pref_vibrate_summary" android:defaultValue="system" android:entries="@array/pref_vibration_entries" android:entryValues="@array/pref_vibration_values"/> <CheckBoxPreference android:key="vibrate_custom" android:title="@string/pref_vibrate_custom" android:defaultValue="false"/>
<juloo.keyboard2.prefs.IntSlideBarPreference android:dependency="vibrate_custom" android:key="vibrate_duration" android:title="@string/pref_vibrate_duration_title" android:summary="%sms" android:defaultValue="20" min="0" max="100"/>
<CheckBoxPreference android:key="pin_entry_enabled" android:title="@string/pref_pin_entry_enabled_title" android:summary="@string/pref_pin_entry_enabled_summary" android:defaultValue="true"/>
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory android:title="@string/pref_category_style"> <PreferenceCategory android:title="@string/pref_category_style">
<ListPreference android:key="theme" android:title="@string/pref_theme" android:summary="%s" android:defaultValue="system" android:entries="@array/pref_theme_entries" android:entryValues="@array/pref_theme_values"/> <ListPreference android:key="theme" android:title="@string/pref_theme" android:summary="%s" android:defaultValue="system" android:entries="@array/pref_theme_entries" android:entryValues="@array/pref_theme_values"/>
<juloo.common.IntSlideBarPreference android:key="label_brightness" android:title="@string/pref_label_brightness" android:summary="%s%%" android:defaultValue="100" min="50" max="100"/> <juloo.keyboard2.prefs.IntSlideBarPreference android:key="label_brightness" android:title="@string/pref_label_brightness" android:summary="%s%%" android:defaultValue="100" min="50" max="100"/>
<juloo.common.IntSlideBarPreference android:key="keyboard_opacity" android:title="@string/pref_keyboard_opacity" android:summary="%s%%" android:defaultValue="100" min="0" max="100"/> <juloo.keyboard2.prefs.IntSlideBarPreference android:key="keyboard_opacity" android:title="@string/pref_keyboard_opacity" android:summary="%s%%" android:defaultValue="100" min="0" max="100"/>
<juloo.common.IntSlideBarPreference android:key="key_opacity" android:title="@string/pref_key_opacity" android:summary="%s%%" android:defaultValue="100" min="0" max="100"/> <juloo.keyboard2.prefs.IntSlideBarPreference android:key="key_opacity" android:title="@string/pref_key_opacity" android:summary="%s%%" android:defaultValue="100" min="0" max="100"/>
<juloo.common.IntSlideBarPreference android:key="key_activated_opacity" android:title="@string/pref_key_activated_opacity" android:summary="%s%%" android:defaultValue="100" min="0" max="100"/> <juloo.keyboard2.prefs.IntSlideBarPreference android:key="key_activated_opacity" android:title="@string/pref_key_activated_opacity" android:summary="%s%%" android:defaultValue="100" min="0" max="100"/>
<PreferenceScreen android:title="@string/pref_margin_bottom_title"> <PreferenceScreen android:title="@string/pref_margin_bottom_title">
<juloo.common.IntSlideBarPreference android:key="margin_bottom_portrait" android:title="@string/pref_portrait" android:summary="%sdp" android:defaultValue="7" min="0" max="100"/> <juloo.keyboard2.prefs.IntSlideBarPreference android:key="margin_bottom_portrait" android:title="@string/pref_portrait" android:summary="%sdp" android:defaultValue="7" min="0" max="100"/>
<juloo.common.IntSlideBarPreference android:key="margin_bottom_landscape" android:title="@string/pref_landscape" android:summary="%sdp" android:defaultValue="3" min="0" max="100"/> <juloo.keyboard2.prefs.IntSlideBarPreference android:key="margin_bottom_landscape" android:title="@string/pref_landscape" android:summary="%sdp" android:defaultValue="3" min="0" max="100"/>
</PreferenceScreen> </PreferenceScreen>
<PreferenceScreen android:title="@string/pref_keyboard_height_title"> <PreferenceScreen android:title="@string/pref_keyboard_height_title">
<juloo.common.IntSlideBarPreference android:key="keyboard_height" android:title="@string/pref_portrait" android:summary="%s%%" android:defaultValue="35" min="10" max="50"/> <juloo.keyboard2.prefs.IntSlideBarPreference android:key="keyboard_height" android:title="@string/pref_portrait" android:summary="%s%%" android:defaultValue="35" min="10" max="50"/>
<juloo.common.IntSlideBarPreference android:key="keyboard_height_landscape" android:title="@string/pref_landscape" android:summary="%s%%" android:defaultValue="50" min="20" max="65"/> <juloo.keyboard2.prefs.IntSlideBarPreference android:key="keyboard_height_landscape" android:title="@string/pref_landscape" android:summary="%s%%" android:defaultValue="50" min="20" max="65"/>
</PreferenceScreen> </PreferenceScreen>
<PreferenceScreen android:title="@string/pref_horizontal_margin_title"> <PreferenceScreen android:title="@string/pref_horizontal_margin_title">
<juloo.common.IntSlideBarPreference android:key="horizontal_margin_portrait" android:title="@string/pref_portrait" android:summary="%sdp" android:defaultValue="3" min="0" max="30"/> <juloo.keyboard2.prefs.IntSlideBarPreference android:key="horizontal_margin_portrait" android:title="@string/pref_portrait" android:summary="%sdp" android:defaultValue="3" min="0" max="30"/>
<juloo.common.IntSlideBarPreference android:key="horizontal_margin_landscape" android:title="@string/pref_landscape" android:summary="%sdp" android:defaultValue="28" min="0" max="200"/> <juloo.keyboard2.prefs.IntSlideBarPreference android:key="horizontal_margin_landscape" android:title="@string/pref_landscape" android:summary="%sdp" android:defaultValue="28" min="0" max="200"/>
</PreferenceScreen> </PreferenceScreen>
<juloo.common.SlideBarPreference android:key="character_size" android:title="@string/pref_character_size_title" android:summary="@string/pref_character_size_summary" android:defaultValue="1.0" min="0.75" max="1.5"/> <juloo.keyboard2.prefs.SlideBarPreference android:key="character_size" android:title="@string/pref_character_size_title" android:summary="@string/pref_character_size_summary" android:defaultValue="1.0" min="0.75" max="1.5"/>
<juloo.common.IntSlideBarPreference android:key="key_vertical_space" android:title="@string/pref_key_vertical_space" android:summary="%sdp" android:defaultValue="2" min="0" max="8"/> <juloo.keyboard2.prefs.SlideBarPreference android:key="key_vertical_margin" android:title="@string/pref_key_vertical_space" android:summary="%s%%" android:defaultValue="1.5" min="0" max="5"/>
<juloo.common.IntSlideBarPreference android:key="key_horizontal_space" android:title="@string/pref_key_horizontal_space" android:summary="%sdp" android:defaultValue="2" min="0" max="8"/> <juloo.keyboard2.prefs.SlideBarPreference android:key="key_horizontal_margin" android:title="@string/pref_key_horizontal_space" android:summary="%s%%" android:defaultValue="2" min="0" max="5"/>
</PreferenceCategory>
<PreferenceCategory android:title="@string/pref_category_advanced">
<EditTextPreference android:key="custom_layout" android:title="@string/pref_custom_layout_title" android:summary="@string/pref_custom_layout_summary" android:inputType="text|textMultiLine|textLongMessage"/>
</PreferenceCategory> </PreferenceCategory>
</PreferenceScreen> </PreferenceScreen>

17
settings.gradle Normal file
View File

@@ -0,0 +1,17 @@
pluginManagement {
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
}
}
rootProject.name = "Unexpected-Keyboard"

View File

@@ -4,16 +4,30 @@
} }: } }:
let let
jdk = pkgs.openjdk8; jdk = pkgs.openjdk17;
build_tools_version = "33.0.1";
android = pkgs.androidenv.composeAndroidPackages { android = pkgs.androidenv.composeAndroidPackages {
buildToolsVersions = [ "30.0.3" ]; buildToolsVersions = [ build_tools_version ];
platformVersions = [ "30" ]; platformVersions = [ "33" ];
abiVersions = [ "armeabi-v7a" ]; abiVersions = [ "armeabi-v7a" ];
}; };
in ANDROID_SDK_ROOT = "${android.androidsdk}/libexec/android-sdk";
pkgs.mkShell {
buildInputs = [ pkgs.findutils jdk android.androidsdk pkgs.fontforge ]; # Without this option, aapt2 fails to run with a permissions error.
ANDROID_HOME = "${android.androidsdk}/libexec/android-sdk"; gradle_wrapped = pkgs.runCommandLocal "gradle-wrapped" {
nativeBuildInputs = with pkgs; [ makeBinaryWrapper ];
} ''
mkdir -p $out/bin
ln -s ${pkgs.gradle}/bin/gradle $out/bin/gradle
wrapProgram $out/bin/gradle \
--add-flags "-Dorg.gradle.project.android.aapt2FromMavenOverride=${ANDROID_SDK_ROOT}/build-tools/${build_tools_version}/aapt2"
'';
in pkgs.mkShell {
buildInputs =
[ pkgs.findutils pkgs.fontforge jdk android.androidsdk gradle_wrapped ];
JAVA_HOME = jdk.home;
inherit ANDROID_SDK_ROOT;
} }

View File

@@ -8,7 +8,7 @@ import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection; import android.view.inputmethod.InputConnection;
import android.view.KeyEvent; import android.view.KeyEvent;
final class Autocapitalisation public final class Autocapitalisation
{ {
boolean _enabled = false; boolean _enabled = false;
boolean _should_enable_shift = false; boolean _should_enable_shift = false;
@@ -49,7 +49,8 @@ final class Autocapitalisation
} }
_enabled = true; _enabled = true;
_should_enable_shift = (info.initialCapsMode != 0); _should_enable_shift = (info.initialCapsMode != 0);
_callback.update_shift_state(_should_enable_shift, true); _should_update_caps_mode = started_should_update_state(info.inputType);
callback_now(true);
} }
public void typed(CharSequence c) public void typed(CharSequence c)
@@ -77,6 +78,13 @@ final class Autocapitalisation
callback(true); callback(true);
} }
public void stop()
{
_should_enable_shift = false;
_should_update_caps_mode = false;
callback_now(true);
}
public static interface Callback public static interface Callback
{ {
public void update_shift_state(boolean should_enable, boolean should_disable); public void update_shift_state(boolean should_enable, boolean should_disable);
@@ -112,7 +120,11 @@ final class Autocapitalisation
} }
}; };
void callback(final boolean might_disable) /** Update the shift state if [_should_update_caps_mode] is true, then call
[_callback.update_shift_state]. This is done after a short delay to wait
for the editor to handle the events, as this might be called before the
corresponding event is sent. */
void callback(boolean might_disable)
{ {
_should_disable_shift = might_disable; _should_disable_shift = might_disable;
// The callback must be delayed because [getCursorCapsMode] would sometimes // The callback must be delayed because [getCursorCapsMode] would sometimes
@@ -120,6 +132,13 @@ final class Autocapitalisation
_handler.postDelayed(delayed_callback, 1); _handler.postDelayed(delayed_callback, 1);
} }
/** Like [callback] but runs immediately. */
void callback_now(boolean might_disable)
{
_should_disable_shift = might_disable;
delayed_callback.run();
}
void type_one_char(char c) void type_one_char(char c)
{ {
_cursor++; _cursor++;
@@ -139,4 +158,26 @@ final class Autocapitalisation
return false; return false;
} }
} }
/** Whether the caps state should be updated when input starts. [inputType]
is the field from the editor info object. */
boolean started_should_update_state(int inputType)
{
int class_ = inputType & InputType.TYPE_MASK_CLASS;
int variation = inputType & InputType.TYPE_MASK_VARIATION;
if (class_ != InputType.TYPE_CLASS_TEXT)
return false;
switch (variation)
{
case InputType.TYPE_TEXT_VARIATION_LONG_MESSAGE:
case InputType.TYPE_TEXT_VARIATION_NORMAL:
case InputType.TYPE_TEXT_VARIATION_PERSON_NAME:
case InputType.TYPE_TEXT_VARIATION_SHORT_MESSAGE:
case InputType.TYPE_TEXT_VARIATION_EMAIL_SUBJECT:
case InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT:
return true;
default:
return false;
}
}
} }

View File

@@ -3,17 +3,22 @@ package juloo.keyboard2;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.content.res.Resources; import android.content.res.Resources;
import android.content.res.TypedArray;
import android.os.Build; import android.os.Build;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.KeyEvent; import android.view.KeyEvent;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import juloo.keyboard2.prefs.CustomExtraKeysPreference;
import juloo.keyboard2.prefs.ExtraKeysPreference;
import juloo.keyboard2.prefs.LayoutsPreference;
final class Config public final class Config
{ {
private final SharedPreferences _prefs; private final SharedPreferences _prefs;
@@ -25,46 +30,51 @@ final class Config
public final float sublabelTextSize; public final float sublabelTextSize;
// From preferences // From preferences
public KeyboardData layout; // Or 'null' for the system defaults /** [null] represent the [system] layout. */
public KeyboardData second_layout; // Or 'null' for none public List<KeyboardData> layouts;
public KeyboardData custom_layout; // Might be 'null'
public boolean show_numpad = false; public boolean show_numpad = false;
// From the 'numpad_layout' option, also apply to the numeric pane. // From the 'numpad_layout' option, also apply to the numeric pane.
public boolean inverse_numpad = false; public boolean inverse_numpad = false;
public boolean number_row; public boolean number_row;
public float swipe_dist_px; public float swipe_dist_px;
public float slide_step_px; public float slide_step_px;
public VibratorCompat.VibrationBehavior vibration_behavior; // Let the system handle vibration when false.
public boolean vibrate_custom;
// Control the vibration if [vibrate_custom] is true.
public long vibrate_duration;
public long longPressTimeout; public long longPressTimeout;
public long longPressInterval; public long longPressInterval;
public float margin_bottom; public float margin_bottom;
public float keyHeight; public float keyHeight;
public float horizontal_margin; public float horizontal_margin;
public float keyVerticalInterval; public float key_vertical_margin;
public float keyHorizontalInterval; public float key_horizontal_margin;
public int labelBrightness; // 0 - 255 public int labelBrightness; // 0 - 255
public int keyboardOpacity; // 0 - 255 public int keyboardOpacity; // 0 - 255
public int keyOpacity; // 0 - 255 public int keyOpacity; // 0 - 255
public int keyActivatedOpacity; // 0 - 255 public int keyActivatedOpacity; // 0 - 255
public boolean double_tap_lock_shift; public boolean double_tap_lock_shift;
public float characterSize; // Ratio public float characterSize; // Ratio
public int accents; // Values are R.values.pref_accents_v_*
public int theme; // Values are R.style.* public int theme; // Values are R.style.*
public boolean autocapitalisation; public boolean autocapitalisation;
public boolean switch_input_immediate; public boolean switch_input_immediate;
public boolean pin_entry_enabled;
// Dynamically set // Dynamically set
public boolean shouldOfferSwitchingToNextInputMethod;
public boolean shouldOfferSwitchingToSecond;
public boolean shouldOfferVoiceTyping; public boolean shouldOfferVoiceTyping;
public String actionLabel; // Might be 'null' public String actionLabel; // Might be 'null'
public int actionId; // Meaningful only when 'actionLabel' isn't 'null' public int actionId; // Meaningful only when 'actionLabel' isn't 'null'
public boolean swapEnterActionKey; // Swap the "enter" and "action" keys public boolean swapEnterActionKey; // Swap the "enter" and "action" keys
public ExtraKeys extra_keys_subtype; public ExtraKeys extra_keys_subtype;
public Set<KeyValue> extra_keys_param; public Map<KeyValue, KeyboardData.PreferredPos> extra_keys_param;
public Map<KeyValue, KeyboardData.PreferredPos> extra_keys_custom;
public final IKeyEventHandler handler; public final IKeyEventHandler handler;
public boolean orientation_landscape = false; public boolean orientation_landscape = false;
/** Index in 'layouts' of the currently used layout. See
[get_current_layout()] and [set_current_layout()]. */
int current_layout_portrait;
int current_layout_landscape;
private Config(SharedPreferences prefs, Resources res, IKeyEventHandler h) private Config(SharedPreferences prefs, Resources res, IKeyEventHandler h)
{ {
@@ -77,8 +87,6 @@ final class Config
// from prefs // from prefs
refresh(res); refresh(res);
// initialized later // initialized later
shouldOfferSwitchingToNextInputMethod = false;
shouldOfferSwitchingToSecond = false;
shouldOfferVoiceTyping = false; shouldOfferVoiceTyping = false;
actionLabel = null; actionLabel = null;
actionId = 0; actionId = 0;
@@ -97,8 +105,6 @@ final class Config
// The height of the keyboard is relative to the height of the screen. // The height of the keyboard is relative to the height of the screen.
// This is the height of the keyboard if it have 4 rows. // This is the height of the keyboard if it have 4 rows.
int keyboardHeightPercent; int keyboardHeightPercent;
// Scale some dimensions depending on orientation
float horizontalIntervalScale = 1.f;
float characterSizeScale = 1.f; float characterSizeScale = 1.f;
String show_numpad_s = _prefs.getString("show_numpad", "never"); String show_numpad_s = _prefs.getString("show_numpad", "never");
show_numpad = "always".equals(show_numpad_s); show_numpad = "always".equals(show_numpad_s);
@@ -107,16 +113,13 @@ final class Config
if ("landscape".equals(show_numpad_s)) if ("landscape".equals(show_numpad_s))
show_numpad = true; show_numpad = true;
keyboardHeightPercent = _prefs.getInt("keyboard_height_landscape", 50); keyboardHeightPercent = _prefs.getInt("keyboard_height_landscape", 50);
horizontalIntervalScale = 2.f;
characterSizeScale = 1.25f; characterSizeScale = 1.25f;
} }
else else
{ {
keyboardHeightPercent = _prefs.getInt("keyboard_height", 35); keyboardHeightPercent = _prefs.getInt("keyboard_height", 35);
} }
layout = layout_of_string(res, _prefs.getString("layout", "none")); layouts = LayoutsPreference.load_from_preferences(res, _prefs);
second_layout = tweak_secondary_layout(layout_of_string(res, _prefs.getString("second_layout", "none")));
custom_layout = KeyboardData.load_string(_prefs.getString("custom_layout", ""));
inverse_numpad = _prefs.getString("numpad_layout", "default").equals("low_first"); inverse_numpad = _prefs.getString("numpad_layout", "default").equals("low_first");
number_row = _prefs.getBoolean("number_row", false); number_row = _prefs.getBoolean("number_row", false);
// The baseline for the swipe distance correspond to approximately the // The baseline for the swipe distance correspond to approximately the
@@ -128,21 +131,21 @@ final class Config
float swipe_dist_value = Float.valueOf(_prefs.getString("swipe_dist", "15")); float swipe_dist_value = Float.valueOf(_prefs.getString("swipe_dist", "15"));
swipe_dist_px = swipe_dist_value / 25.f * swipe_scaling; swipe_dist_px = swipe_dist_value / 25.f * swipe_scaling;
slide_step_px = swipe_dist_px / 4.f; slide_step_px = swipe_dist_px / 4.f;
vibration_behavior = vibrate_custom = _prefs.getBoolean("vibrate_custom", false);
VibratorCompat.VibrationBehavior.of_string(_prefs.getString("vibration_behavior", "system")); vibrate_duration = _prefs.getInt("vibrate_duration", 20);
longPressTimeout = _prefs.getInt("longpress_timeout", 600); longPressTimeout = _prefs.getInt("longpress_timeout", 600);
longPressInterval = _prefs.getInt("longpress_interval", 65); longPressInterval = _prefs.getInt("longpress_interval", 65);
margin_bottom = get_dip_pref_oriented(dm, "margin_bottom", 7, 3); margin_bottom = get_dip_pref_oriented(dm, "margin_bottom", 7, 3);
keyVerticalInterval = get_dip_pref(dm, "key_vertical_space", 2); key_vertical_margin = get_dip_pref(dm, "key_vertical_margin", 1.5f) / 100;
keyHorizontalInterval = get_dip_pref(dm, "key_horizontal_space", 2) * horizontalIntervalScale; key_horizontal_margin = get_dip_pref(dm, "key_horizontal_margin", 2) / 100;
// Label brightness is used as the alpha channel // Label brightness is used as the alpha channel
labelBrightness = _prefs.getInt("label_brightness", 100) * 255 / 100; labelBrightness = _prefs.getInt("label_brightness", 100) * 255 / 100;
// Keyboard opacity // Keyboard opacity
keyboardOpacity = _prefs.getInt("keyboard_opacity", 100) * 255 / 100; keyboardOpacity = _prefs.getInt("keyboard_opacity", 100) * 255 / 100;
keyOpacity = _prefs.getInt("key_opacity", 100) * 255 / 100; keyOpacity = _prefs.getInt("key_opacity", 100) * 255 / 100;
keyActivatedOpacity = _prefs.getInt("key_activated_opacity", 100) * 255 / 100; keyActivatedOpacity = _prefs.getInt("key_activated_opacity", 100) * 255 / 100;
// Do not substract keyVerticalInterval from keyHeight because this is done // Do not substract key_vertical_margin from keyHeight because this is done
// during rendered. // during rendering.
keyHeight = dm.heightPixels * keyboardHeightPercent / 100 / 4; keyHeight = dm.heightPixels * keyboardHeightPercent / 100 / 4;
horizontal_margin = horizontal_margin =
get_dip_pref_oriented(dm, "horizontal_margin", 3, 28); get_dip_pref_oriented(dm, "horizontal_margin", 3, 28);
@@ -150,11 +153,32 @@ final class Config
characterSize = characterSize =
_prefs.getFloat("character_size", 1.f) _prefs.getFloat("character_size", 1.f)
* characterSizeScale; * characterSizeScale;
accents = Integer.valueOf(_prefs.getString("accents", "1"));
theme = getThemeId(res, _prefs.getString("theme", "")); theme = getThemeId(res, _prefs.getString("theme", ""));
autocapitalisation = _prefs.getBoolean("autocapitalisation", true); autocapitalisation = _prefs.getBoolean("autocapitalisation", true);
switch_input_immediate = _prefs.getBoolean("switch_input_immediate", false); switch_input_immediate = _prefs.getBoolean("switch_input_immediate", false);
extra_keys_param = ExtraKeyCheckBoxPreference.get_extra_keys(_prefs); extra_keys_param = ExtraKeysPreference.get_extra_keys(_prefs);
extra_keys_custom = CustomExtraKeysPreference.get(_prefs);
pin_entry_enabled = _prefs.getBoolean("pin_entry_enabled", true);
current_layout_portrait = _prefs.getInt("current_layout_portrait", 0);
current_layout_landscape = _prefs.getInt("current_layout_landscape", 0);
}
public int get_current_layout()
{
return (orientation_landscape)
? current_layout_landscape : current_layout_portrait;
}
public void set_current_layout(int l)
{
if (orientation_landscape)
current_layout_landscape = l;
else
current_layout_portrait = l;
SharedPreferences.Editor e = _prefs.edit();
e.putInt("current_layout_portrait", current_layout_portrait);
e.putInt("current_layout_landscape", current_layout_landscape);
e.apply();
} }
KeyValue action_key() KeyValue action_key()
@@ -170,24 +194,33 @@ final class Config
* - Replace the action key to show the right label * - Replace the action key to show the right label
* - Swap the enter and action keys * - Swap the enter and action keys
* - Add the optional numpad and number row * - Add the optional numpad and number row
* - Add the extra keys
*/ */
public KeyboardData modify_layout(KeyboardData kw) public KeyboardData modify_layout(KeyboardData kw)
{ {
final KeyValue action_key = action_key(); final KeyValue action_key = action_key();
// Extra keys are removed from the set as they are encountered during the // Extra keys are removed from the set as they are encountered during the
// first iteration then automatically added. // first iteration then automatically added.
final Set<KeyValue> extra_keys = new HashSet<KeyValue>(); final Map<KeyValue, KeyboardData.PreferredPos> extra_keys = new HashMap<KeyValue, KeyboardData.PreferredPos>();
final Set<KeyValue> remove_keys = new HashSet<KeyValue>(); final Set<KeyValue> remove_keys = new HashSet<KeyValue>();
extra_keys.putAll(extra_keys_param);
extra_keys.putAll(extra_keys_custom);
if (extra_keys_subtype != null) if (extra_keys_subtype != null)
extra_keys_subtype.compute(extra_keys, kw.script); {
extra_keys.addAll(extra_keys_param); Set<KeyValue> present = new HashSet<KeyValue>();
present.addAll(kw.getKeys().keySet());
present.addAll(extra_keys_param.keySet());
present.addAll(extra_keys_custom.keySet());
extra_keys_subtype.compute(extra_keys,
new ExtraKeys.Query(kw.script, present));
}
boolean number_row = this.number_row && !show_numpad; boolean number_row = this.number_row && !show_numpad;
if (number_row) if (number_row)
KeyboardData.number_row.getKeys(remove_keys); remove_keys.addAll(KeyboardData.number_row.getKeys(0).keySet());
kw = kw.mapKeys(new KeyboardData.MapKeyValues() { kw = kw.mapKeys(new KeyboardData.MapKeyValues() {
public KeyValue apply(KeyValue key, boolean localized) public KeyValue apply(KeyValue key, boolean localized)
{ {
boolean is_extra_key = extra_keys.contains(key); boolean is_extra_key = extra_keys.containsKey(key);
if (is_extra_key) if (is_extra_key)
extra_keys.remove(key); extra_keys.remove(key);
if (localized && !is_extra_key) if (localized && !is_extra_key)
@@ -199,18 +232,19 @@ final class Config
case Event: case Event:
switch (key.getEvent()) switch (key.getEvent())
{ {
case CHANGE_METHOD: case CHANGE_METHOD_PICKER:
if (!shouldOfferSwitchingToNextInputMethod)
return null;
if (switch_input_immediate) if (switch_input_immediate)
return KeyValue.getKeyByName("change_method_prev"); return KeyValue.getKeyByName("change_method_prev");
return key; return key;
case ACTION: case ACTION:
return (swapEnterActionKey && action_key != null) ? return (swapEnterActionKey && action_key != null) ?
KeyValue.getKeyByName("enter") : action_key; KeyValue.getKeyByName("enter") : action_key;
case SWITCH_SECOND: case SWITCH_FORWARD:
return shouldOfferSwitchingToSecond ? key : null; return (layouts.size() > 1) ? key : null;
case SWITCH_BACKWARD:
return (layouts.size() > 2) ? key : null;
case SWITCH_VOICE_TYPING: case SWITCH_VOICE_TYPING:
case SWITCH_VOICE_TYPING_CHOOSER:
return shouldOfferVoiceTyping ? key : null; return shouldOfferVoiceTyping ? key : null;
} }
break; break;
@@ -234,20 +268,20 @@ final class Config
} }
}); });
if (show_numpad) if (show_numpad)
kw = kw.addNumPad(); kw = kw.addNumPad(modify_numpad(KeyboardData.num_pad, kw));
if (number_row) if (number_row)
kw = kw.addNumberRow(); kw = kw.addNumberRow();
if (extra_keys.size() > 0) if (extra_keys.size() > 0)
kw = kw.addExtraKeys(extra_keys.iterator()); kw = kw.addExtraKeys(extra_keys.entrySet().iterator());
return kw; return kw;
} }
/** /** Handle the numpad layout. The [main_kw] is used to adapt the numpad to
* Handle the numpad layout. the main layout's script. */
*/ public KeyboardData modify_numpad(KeyboardData kw, KeyboardData main_kw)
public KeyboardData modify_numpad(KeyboardData kw)
{ {
final KeyValue action_key = action_key(); final KeyValue action_key = action_key();
final KeyModifier.Map_char map_digit = KeyModifier.modify_numpad_script(main_kw.numpad_script);
return kw.mapKeys(new KeyboardData.MapKeyValues() { return kw.mapKeys(new KeyboardData.MapKeyValues() {
public KeyValue apply(KeyValue key, boolean localized) public KeyValue apply(KeyValue key, boolean localized)
{ {
@@ -269,11 +303,15 @@ final class Config
} }
break; break;
case Char: case Char:
char a = key.getChar(), b = a; char prev_c = key.getChar();
char c = prev_c;
if (inverse_numpad) if (inverse_numpad)
b = inverse_numpad_char(a); c = inverse_numpad_char(c);
if (a != b) String modified = map_digit.apply(c);
return key.withChar(b); if (modified != null) // Was modified by script
return key.withSymbol(modified);
if (prev_c != c) // Was inverted
return key.withChar(c);
break; break;
} }
return key; return key;
@@ -281,30 +319,13 @@ final class Config
}); });
} }
/** Modify a layout to turn it into a secondary layout by changing the
"switch_second" key. */
KeyboardData tweak_secondary_layout(KeyboardData layout)
{
if (layout == null)
return null;
return layout.mapKeys(new KeyboardData.MapKeyValues() {
public KeyValue apply(KeyValue key, boolean localized)
{
if (key.getKind() == KeyValue.Kind.Event
&& key.getEvent() == KeyValue.Event.SWITCH_SECOND)
return KeyValue.getKeyByName("switch_second_back");
return key;
}
});
}
private float get_dip_pref(DisplayMetrics dm, String pref_name, float def) private float get_dip_pref(DisplayMetrics dm, String pref_name, float def)
{ {
float value; float value;
try { value = _prefs.getInt(pref_name, -1); } try { value = _prefs.getInt(pref_name, -1); }
catch (Exception e) { value = _prefs.getFloat(pref_name, -1f); } catch (Exception e) { value = _prefs.getFloat(pref_name, -1f); }
if (value < 0f) if (value < 0f)
return (def); value = def;
return (TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, value, dm)); return (TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, value, dm));
} }
@@ -326,6 +347,8 @@ final class Config
case "dark": return R.style.Dark; case "dark": return R.style.Dark;
case "white": return R.style.White; case "white": return R.style.White;
case "epaper": return R.style.ePaper; case "epaper": return R.style.ePaper;
case "desert": return R.style.Desert;
case "jungle": return R.style.Jungle;
default: default:
case "system": case "system":
if (Build.VERSION.SDK_INT >= 8) if (Build.VERSION.SDK_INT >= 8)
@@ -338,36 +361,6 @@ final class Config
} }
} }
/** Obtained from XML. */
static List<String> layout_ids_str = null;
static TypedArray layout_ids_res = null;
/** Might return [null] if the selected layout is "system", "custom" or if
the name is not recognized. */
public KeyboardData layout_of_string(Resources res, String name)
{
if (layout_ids_str == null)
{
layout_ids_str = Arrays.asList(res.getStringArray(R.array.pref_layout_values));
layout_ids_res = res.obtainTypedArray(R.array.layout_ids);
}
int i = layout_ids_str.indexOf(name);
if (i >= 0)
{
int id = layout_ids_res.getResourceId(i, 0);
if (id > 0)
return KeyboardData.load(res, id);
// Fallthrough
}
switch (name)
{
case "custom": return custom_layout;
case "system":
case "none":
default: return null;
}
}
char inverse_numpad_char(char c) char inverse_numpad_char(char c)
{ {
switch (c) switch (c)
@@ -387,6 +380,7 @@ final class Config
public static void initGlobalConfig(SharedPreferences prefs, Resources res, public static void initGlobalConfig(SharedPreferences prefs, Resources res,
IKeyEventHandler handler) IKeyEventHandler handler)
{ {
migrate(prefs);
_globalConfig = new Config(prefs, res, handler); _globalConfig = new Config(prefs, res, handler);
} }
@@ -395,8 +389,56 @@ final class Config
return _globalConfig; return _globalConfig;
} }
public static SharedPreferences globalPrefs()
{
return _globalConfig._prefs;
}
public static interface IKeyEventHandler public static interface IKeyEventHandler
{ {
public void key_up(KeyValue value, Pointers.Modifiers flags); public void key_down(KeyValue value, boolean is_swipe);
public void key_up(KeyValue value, Pointers.Modifiers mods);
public void mods_changed(Pointers.Modifiers mods);
}
/** Config migrations. */
private static int CONFIG_VERSION = 1;
public static void migrate(SharedPreferences prefs)
{
int saved_version = prefs.getInt("version", 0);
Logs.debug_config_migration(saved_version, CONFIG_VERSION);
if (saved_version == CONFIG_VERSION)
return;
SharedPreferences.Editor e = prefs.edit();
e.putInt("version", CONFIG_VERSION);
// Migrations might run on an empty [prefs] for new installs, in this case
// they set the default values of complex options.
switch (saved_version) // Fallback switch
{
case 0:
// Primary, secondary and custom layout options are merged into the new
// Layouts option. This also sets the default value.
List<LayoutsPreference.Layout> l = new ArrayList<LayoutsPreference.Layout>();
l.add(migrate_layout(prefs.getString("layout", "system")));
String snd_layout = prefs.getString("second_layout", "none");
if (snd_layout != null && !snd_layout.equals("none"))
l.add(migrate_layout(snd_layout));
String custom_layout = prefs.getString("custom_layout", "");
if (custom_layout != null && !custom_layout.equals(""))
l.add(LayoutsPreference.CustomLayout.parse(custom_layout));
LayoutsPreference.save_to_preferences(e, l);
case 1:
default: break;
}
e.commit();
}
private static LayoutsPreference.Layout migrate_layout(String name)
{
if (name == null || name.equals("system"))
return new LayoutsPreference.SystemLayout();
return new LayoutsPreference.NamedLayout(name);
} }
} }

View File

@@ -0,0 +1,138 @@
package juloo.keyboard2;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Handler;
import android.text.InputType;
import android.text.Layout;
import android.widget.EditText;
public class CustomLayoutEditDialog
{
/** Dialog for specifying a custom layout. [initial_text] is the layout
description when modifying a layout. */
public static void show(Context ctx, String initial_text,
boolean allow_remove, final Callback callback)
{
final LayoutEntryEditText input = new LayoutEntryEditText(ctx);
input.setText(initial_text);
AlertDialog.Builder dialog = new AlertDialog.Builder(ctx)
.setView(input)
.setTitle(R.string.pref_custom_layout_title)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener(){
public void onClick(DialogInterface _dialog, int _which)
{
callback.select(input.getText().toString());
}
})
.setNegativeButton(android.R.string.cancel, null);
// Might be true when modifying an existing layout
if (allow_remove)
dialog.setNeutralButton(R.string.pref_layouts_remove_custom, new DialogInterface.OnClickListener(){
public void onClick(DialogInterface _dialog, int _which)
{
callback.select(null);
}
});
input.set_on_text_change(new LayoutEntryEditText.OnChangeListener()
{
public void on_change()
{
String error = callback.validate(input.getText().toString());
input.setError(error);
}
});
dialog.show();
}
public interface Callback
{
/** The entered text when the user clicks "OK", [null] when the user
cancels editing. */
public void select(String text);
/** Return a human readable error string if the [text] contains an error.
Return [null] otherwise. The error string will be displayed atop the
input box. This method is called everytime the text changes. */
public String validate(String text);
}
/** An editable text view that shows line numbers. */
static class LayoutEntryEditText extends EditText
{
/** Used to draw line numbers. */
Paint _ln_paint;
OnChangeListener _on_change_listener = null;
/** Delay validation to when user stops typing for a second. */
Handler _on_change_throttler;
Runnable _on_change_delayed = new Runnable()
{
public void run()
{
OnChangeListener l = LayoutEntryEditText.this._on_change_listener;
if (l != null)
l.on_change();
}
};
public LayoutEntryEditText(Context ctx)
{
super(ctx);
_ln_paint = new Paint(getPaint());
_ln_paint.setTextSize(_ln_paint.getTextSize() * 0.8f);
setHorizontallyScrolling(true);
setInputType(InputType.TYPE_CLASS_TEXT
| InputType.TYPE_TEXT_FLAG_MULTI_LINE);
_on_change_throttler = new Handler(ctx.getMainLooper());
}
public void set_on_text_change(OnChangeListener l)
{
_on_change_listener = l;
}
@Override
protected void onDraw(Canvas canvas)
{
float digit_width = _ln_paint.measureText("0");
int line_count = getLineCount();
// Extra '+ 1' serves as padding.
setPadding((int)(((int)Math.log10(line_count) + 1 + 1) * digit_width), 0, 0, 0);
super.onDraw(canvas);
_ln_paint.setColor(getPaint().getColor());
Rect clip_bounds = canvas.getClipBounds();
Layout layout = getLayout();
int offset = clip_bounds.left + (int)(digit_width / 2.f);
int line = layout.getLineForVertical(clip_bounds.top);
int skipped = line;
while (line < line_count)
{
int baseline = getLineBounds(line, null);
canvas.drawText(String.valueOf(line), offset, baseline, _ln_paint);
line++;
if (baseline >= clip_bounds.bottom)
break;
}
}
@Override
protected void onTextChanged(CharSequence text, int _start, int _lengthBefore, int _lengthAfter)
{
if (_on_change_throttler != null)
{
_on_change_throttler.removeCallbacks(_on_change_delayed);
_on_change_throttler.postDelayed(_on_change_delayed, 1000);
}
}
public static interface OnChangeListener
{
public void on_change();
}
}
}

View File

@@ -1,29 +0,0 @@
package juloo.keyboard2;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.Button;
public class EmojiKeyButton extends Button
implements View.OnClickListener
{
KeyValue _key;
public EmojiKeyButton(Context context, AttributeSet attrs)
{
super(context, attrs);
setOnClickListener(this);
String key_name = attrs.getAttributeValue(null, "key");
_key = (key_name == null) ? null : KeyValue.getKeyByName(key_name);
setText(_key.getString());
if (_key.hasFlags(KeyValue.FLAG_KEY_FONT))
setTypeface(Theme.getKeyFont(context));
}
public void onClick(View v)
{
Config config = Config.globalConfig();
config.handler.key_up(_key, Pointers.Modifiers.EMPTY);
}
}

View File

@@ -1,110 +0,0 @@
package juloo.keyboard2;
import android.content.Context;
import android.content.res.TypedArray;
import android.content.SharedPreferences;
import android.preference.CheckBoxPreference;
import android.util.AttributeSet;
import android.view.View;
import android.widget.TextView;
import java.util.HashSet;
import java.util.Set;
public class ExtraKeyCheckBoxPreference extends CheckBoxPreference
{
public static String[] extra_keys = new String[]
{
"alt",
"meta",
"voice_typing",
"accent_aigu",
"accent_grave",
"accent_double_aigu",
"accent_dot_above",
"accent_circonflexe",
"accent_tilde",
"accent_cedille",
"accent_trema",
"accent_ring",
"accent_caron",
"accent_macron",
"accent_ogonek",
"accent_breve",
"accent_slash",
"accent_bar",
"accent_dot_below",
"accent_hook_above",
"accent_horn",
"",
"ß",
"£",
"switch_greekmath",
"capslock",
"copy",
"paste",
"cut",
"selectAll",
"shareText",
"pasteAsPlainText",
"undo",
"redo",
"replaceText",
"textAssist",
"autofill",
};
public static boolean default_checked(String name)
{
switch (name)
{
case "voice_typing":
return true;
default:
return false;
}
}
boolean _key_font;
public ExtraKeyCheckBoxPreference(Context context, AttributeSet attrs)
{
super(context, attrs);
final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ExtraKeyCheckBoxPreference);
int index = a.getInteger(R.styleable.ExtraKeyCheckBoxPreference_index, 0);
a.recycle();
String key_name = extra_keys[index];
KeyValue kv = KeyValue.getKeyByName(key_name);
String title = kv.getString();
String descr = KeyValue.getKeyDescription(key_name);
if (descr != null)
title += " (" + descr + ")";
setKey(pref_key_of_key_name(key_name));
setDefaultValue(default_checked(key_name));
setTitle(title);
_key_font = kv.hasFlags(KeyValue.FLAG_KEY_FONT);
}
@Override
protected void onBindView(View view)
{
super.onBindView(view);
TextView title = (TextView)view.findViewById(android.R.id.title);
title.setTypeface(_key_font ? Theme.getKeyFont(getContext()) : null);
}
static String pref_key_of_key_name(String key_name)
{
return "extra_key_" + key_name;
}
public static Set<KeyValue> get_extra_keys(SharedPreferences prefs)
{
HashSet<KeyValue> ks = new HashSet<KeyValue>();
for (String key_name : extra_keys)
{
if (prefs.getBoolean(pref_key_of_key_name(key_name), default_checked(key_name)))
ks.add(KeyValue.getKeyByName(key_name));
}
return ks;
}
}

View File

@@ -1,57 +1,150 @@
package juloo.keyboard2; package juloo.keyboard2;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
class ExtraKeys public final class ExtraKeys
{ {
Map<String, List<KeyValue>> _keys_per_script; public static final ExtraKeys EMPTY = new ExtraKeys(Collections.EMPTY_LIST);
public ExtraKeys() Collection<ExtraKey> _ks;
public ExtraKeys(Collection<ExtraKey> ks)
{ {
_keys_per_script = new HashMap<String, List<KeyValue>>(); _ks = ks;
} }
public void add_keys_for_script(String script, List<KeyValue> kvs) /** Add the keys that should be added to the keyboard into [dst]. Keys
already added to [dst] might have an impact, see [ExtraKey.compute]. */
public void compute(Map<KeyValue, KeyboardData.PreferredPos> dst, Query q)
{ {
List<KeyValue> ks = _keys_per_script.get(script); for (ExtraKey k : _ks)
if (ks == null) ks = new ArrayList<KeyValue>(); k.compute(dst, q);
ks.addAll(kvs);
_keys_per_script.put(script, ks);
} }
/** Add the keys that should be added to the keyboard into [dst]. [null] is public static ExtraKeys parse(String script, String str)
a valid script. */
public void compute(Set<KeyValue> dst, String script)
{ {
if (script == null) Collection<ExtraKey> dst = new ArrayList<ExtraKey>();
{
for (String sc : _keys_per_script.keySet())
get_keys_of_script(dst, sc);
}
else
{
get_keys_of_script(dst, null);
get_keys_of_script(dst, script);
}
}
void get_keys_of_script(Set<KeyValue> dst, String script)
{
List<KeyValue> ks = _keys_per_script.get(script);
if (ks != null)
dst.addAll(ks);
}
public static List<KeyValue> parse_extra_keys(String str)
{
List<KeyValue> dst = new ArrayList<KeyValue>();
String[] ks = str.split("\\|"); String[] ks = str.split("\\|");
for (int i = 0; i < ks.length; i++) for (int i = 0; i < ks.length; i++)
dst.add(KeyValue.getKeyByName(ks[i])); dst.add(ExtraKey.parse(ks[i], script));
return dst; return new ExtraKeys(dst);
}
/** Merge identical keys. This is required to decide whether to add
alternatives. Script is generalized (set to null) on any conflict. */
public static ExtraKeys merge(List<ExtraKeys> kss)
{
Map<KeyValue, ExtraKey> merged_keys = new HashMap<KeyValue, ExtraKey>();
for (ExtraKeys ks : kss)
for (ExtraKey k : ks._ks)
{
ExtraKey k2 = merged_keys.get(k.kv);
if (k2 != null)
k = k.merge_with(k2);
merged_keys.put(k.kv, k);
}
return new ExtraKeys(merged_keys.values());
}
final static class ExtraKey
{
/** The key to add. */
final KeyValue kv;
/** The key will be added to layouts of the same script. If null, might be
added to layouts of any script. */
final String script;
/** The key will not be added to layout that already contain all the
alternatives. */
final List<KeyValue> alternatives;
/** The key next to which to add. Might be [null]. */
final KeyValue next_to;
ExtraKey(KeyValue kv_, String script_, List<KeyValue> alts_, KeyValue next_to_)
{
kv = kv_;
script = script_;
alternatives = alts_;
next_to = next_to_;
}
/** Whether the key should be added to the keyboard. */
public void compute(Map<KeyValue, KeyboardData.PreferredPos> dst, Query q)
{
// Add the alternative if it's the only one. The list of alternatives is
// enforced to be complete by the merging step. The same [kv] will not
// appear again in the list of extra keys with a different list of
// alternatives.
// Selecting the dead key in the "Add key to the keyboard" option would
// disable this behavior for a key.
boolean use_alternative = (alternatives.size() == 1 && !dst.containsKey(kv));
if
((q.script == null || script == null || q.script.equals(script))
&& (alternatives.size() == 0 || !q.present.containsAll(alternatives)))
{
KeyValue kv_ = use_alternative ? alternatives.get(0) : kv;
KeyboardData.PreferredPos pos = KeyboardData.PreferredPos.DEFAULT;
if (next_to != null)
{
pos = new KeyboardData.PreferredPos(pos);
pos.next_to = next_to;
}
dst.put(kv_, pos);
}
}
/** Return a new key from two. [kv] are expected to be equal. [script] is
generalized to [null] on any conflict. [alternatives] are concatenated.
*/
public ExtraKey merge_with(ExtraKey k2)
{
String script_ = one_or_none(script, k2.script);
List<KeyValue> alts = new ArrayList<KeyValue>(alternatives);
KeyValue next_to_ = one_or_none(next_to, k2.next_to);
alts.addAll(k2.alternatives);
return new ExtraKey(kv, script_, alts, next_to_);
}
/** If one of [a] or [b] is null, return the other. If [a] and [b] are
equal, return [a]. Otherwise, return null. */
<E> E one_or_none(E a, E b)
{
return (a == null) ? b : (b == null || a.equals(b)) ? a : null;
}
/** Extra keys are of the form "key name" or "key name:alt1:alt2@next_to". */
public static ExtraKey parse(String str, String script)
{
String[] split_on_at = str.split("@", 2);
String[] key_names = split_on_at[0].split(":");
KeyValue kv = KeyValue.getKeyByName(key_names[0]);
KeyValue[] alts = new KeyValue[key_names.length-1];
for (int i = 1; i < key_names.length; i++)
alts[i-1] = KeyValue.getKeyByName(key_names[i]);
KeyValue next_to = null;
if (split_on_at.length > 1)
next_to = KeyValue.getKeyByName(split_on_at[1]);
return new ExtraKey(kv, script, Arrays.asList(alts), next_to);
}
}
public final static class Query
{
/** Script of the current layout. Might be null. */
final String script;
/** Keys present on the layout. */
final Set<KeyValue> present;
public Query(String script_, Set<KeyValue> present_)
{
script = script_;
present = present_;
}
} }
} }

View File

@@ -1,26 +1,47 @@
package juloo.keyboard2; package juloo.keyboard2;
import android.os.Looper; import android.os.Looper;
import android.text.InputType;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.inputmethod.EditorInfo; import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.ExtractedText;
import android.view.inputmethod.ExtractedTextRequest;
import android.view.inputmethod.InputConnection; import android.view.inputmethod.InputConnection;
import java.util.Iterator;
class KeyEventHandler implements Config.IKeyEventHandler public final class KeyEventHandler implements Config.IKeyEventHandler
{ {
IReceiver _recv; IReceiver _recv;
Autocapitalisation _autocap; Autocapitalisation _autocap;
/** State of the system modifiers. It is updated whether a modifier is down
or up and a corresponding key event is sent. */
Pointers.Modifiers _mods;
/** Consistent with [_mods]. This is a mutable state rather than computed
from [_mods] to ensure that the meta state is correct while up and down
events are sent for the modifier keys. */
int _meta_state = 0;
/** Whether to force sending arrow keys to move the cursor when
[setSelection] could be used instead. */
boolean _move_cursor_force_fallback = false;
public KeyEventHandler(Looper looper, IReceiver recv) public KeyEventHandler(Looper looper, IReceiver recv)
{ {
_recv = recv; _recv = recv;
_autocap = new Autocapitalisation(looper, _autocap = new Autocapitalisation(looper,
this.new Autocapitalisation_callback()); this.new Autocapitalisation_callback());
_mods = Pointers.Modifiers.EMPTY;
} }
/** Editing just started. */ /** Editing just started. */
public void started(EditorInfo info) public void started(EditorInfo info)
{ {
_autocap.started(info, _recv.getCurrentInputConnection()); _autocap.started(info, _recv.getCurrentInputConnection());
// Workaround a bug in Acode, which answers to [getExtractedText] but do
// not react to [setSelection] while returning [true].
// Note: Using & to workaround a bug in Acode, which sets several
// variations at once.
_move_cursor_force_fallback = (info.inputType & InputType.TYPE_MASK_VARIATION &
InputType.TYPE_TEXT_VARIATION_PASSWORD) != 0;
} }
/** Selection has been updated. */ /** Selection has been updated. */
@@ -29,44 +50,69 @@ class KeyEventHandler implements Config.IKeyEventHandler
_autocap.selection_updated(oldSelStart, newSelStart); _autocap.selection_updated(oldSelStart, newSelStart);
} }
/** A key has been released. */ /** A key is being pressed. There will not necessarily be a corresponding
public void key_up(KeyValue key, Pointers.Modifiers mods) [key_up] event. */
@Override
public void key_down(KeyValue key, boolean isSwipe)
{ {
if (key == null) if (key == null)
return; return;
switch (key.getKind()) switch (key.getKind())
{ {
case Char: send_text(String.valueOf(key.getChar())); break;
case String: send_text(key.getString()); break;
case Event: _recv.handle_event_key(key.getEvent()); break;
case Keyevent:
handleKeyUpWithModifier(key.getKeyevent(), mods);
break;
case Modifier: case Modifier:
// Stop auto capitalisation when activating a system modifier
switch (key.getModifier())
{
case CTRL:
case ALT:
case META:
_autocap.stop();
break; break;
case Editing: }
send_context_menu_action(action_of_editing_key(key.getEditing()));
break; break;
default: break;
} }
} }
static int action_of_editing_key(KeyValue.Editing e) /** A key has been released. */
@Override
public void key_up(KeyValue key, Pointers.Modifiers mods)
{ {
switch (e) if (key == null)
return;
Pointers.Modifiers old_mods = _mods;
update_meta_state(mods);
switch (key.getKind())
{ {
case COPY: return android.R.id.copy; case Char: send_text(String.valueOf(key.getChar())); break;
case PASTE: return android.R.id.paste; case String: send_text(key.getString()); break;
case CUT: return android.R.id.cut; case Event: _recv.handle_event_key(key.getEvent()); break;
case SELECT_ALL: return android.R.id.selectAll; case Keyevent: send_key_down_up(key.getKeyevent()); break;
case SHARE: return android.R.id.shareText; case Modifier: break;
case PASTE_PLAIN: return android.R.id.pasteAsPlainText; case Editing: handle_editing_key(key.getEditing()); break;
case UNDO: return android.R.id.undo;
case REDO: return android.R.id.redo;
case REPLACE: return android.R.id.replaceText;
case ASSIST: return android.R.id.textAssist;
case AUTOFILL: return android.R.id.autofill;
default: return -1; // sad
} }
update_meta_state(old_mods);
}
@Override
public void mods_changed(Pointers.Modifiers mods)
{
update_meta_state(mods);
}
/** Update [_mods] to be consistent with the [mods], sending key events if
needed. */
void update_meta_state(Pointers.Modifiers mods)
{
// Released modifiers
Iterator<KeyValue.Modifier> it = _mods.diff(mods);
while (it.hasNext())
sendMetaKeyForModifier(it.next(), false);
// Activated modifiers
it = mods.diff(_mods);
while (it.hasNext())
sendMetaKeyForModifier(it.next(), true);
_mods = mods;
} }
// private void handleDelKey(int before, int after) // private void handleDelKey(int before, int after)
@@ -79,54 +125,58 @@ class KeyEventHandler implements Config.IKeyEventHandler
// getCurrentInputConnection().deleteSurroundingText(before, after); // getCurrentInputConnection().deleteSurroundingText(before, after);
// } // }
int sendMetaKey(int eventCode, int metaFlags, int metaState, boolean down) void sendMetaKey(int eventCode, int meta_flags, boolean down)
{ {
int action; if (down)
int updatedMetaState; {
if (down) { action = KeyEvent.ACTION_DOWN; updatedMetaState = metaState | metaFlags; } _meta_state = _meta_state | meta_flags;
else { action = KeyEvent.ACTION_UP; updatedMetaState = metaState & ~metaFlags; } send_keyevent(KeyEvent.ACTION_DOWN, eventCode);
send_keyevent(action, eventCode, metaState); }
return updatedMetaState; else
{
send_keyevent(KeyEvent.ACTION_UP, eventCode);
_meta_state = _meta_state & ~meta_flags;
}
} }
int sendMetaKeyForModifier(KeyValue.Modifier mod, int metaState, boolean down) void sendMetaKeyForModifier(KeyValue.Modifier mod, boolean down)
{ {
switch (mod) switch (mod)
{ {
case CTRL: case CTRL:
return sendMetaKey(KeyEvent.KEYCODE_CTRL_LEFT, KeyEvent.META_CTRL_LEFT_ON | KeyEvent.META_CTRL_ON, metaState, down); sendMetaKey(KeyEvent.KEYCODE_CTRL_LEFT, KeyEvent.META_CTRL_LEFT_ON | KeyEvent.META_CTRL_ON, down);
break;
case ALT: case ALT:
return sendMetaKey(KeyEvent.KEYCODE_ALT_LEFT, KeyEvent.META_ALT_LEFT_ON | KeyEvent.META_ALT_ON, metaState, down); sendMetaKey(KeyEvent.KEYCODE_ALT_LEFT, KeyEvent.META_ALT_LEFT_ON | KeyEvent.META_ALT_ON, down);
break;
case SHIFT: case SHIFT:
return sendMetaKey(KeyEvent.KEYCODE_SHIFT_LEFT, KeyEvent.META_SHIFT_LEFT_ON | KeyEvent.META_SHIFT_ON, metaState, down); sendMetaKey(KeyEvent.KEYCODE_SHIFT_LEFT, KeyEvent.META_SHIFT_LEFT_ON | KeyEvent.META_SHIFT_ON, down);
break;
case META: case META:
return sendMetaKey(KeyEvent.KEYCODE_META_LEFT, KeyEvent.META_META_LEFT_ON | KeyEvent.META_META_ON, metaState, down); sendMetaKey(KeyEvent.KEYCODE_META_LEFT, KeyEvent.META_META_LEFT_ON | KeyEvent.META_META_ON, down);
default: return metaState; break;
default:
break;
} }
} }
/* /*
* Don't set KeyEvent.FLAG_SOFT_KEYBOARD. * Don't set KeyEvent.FLAG_SOFT_KEYBOARD.
*/ */
void handleKeyUpWithModifier(int keyCode, Pointers.Modifiers mods) void send_key_down_up(int keyCode)
{ {
int metaState = 0; send_keyevent(KeyEvent.ACTION_DOWN, keyCode);
for (int i = 0; i < mods.size(); i++) send_keyevent(KeyEvent.ACTION_UP, keyCode);
metaState = sendMetaKeyForModifier(mods.get(i), metaState, true);
send_keyevent(KeyEvent.ACTION_DOWN, keyCode, metaState);
send_keyevent(KeyEvent.ACTION_UP, keyCode, metaState);
for (int i = mods.size() - 1; i >= 0; i--)
metaState = sendMetaKeyForModifier(mods.get(i), metaState, false);
} }
void send_keyevent(int eventAction, int eventCode, int meta) void send_keyevent(int eventAction, int eventCode)
{ {
InputConnection conn = _recv.getCurrentInputConnection(); InputConnection conn = _recv.getCurrentInputConnection();
if (conn == null) if (conn == null)
return; return;
conn.sendKeyEvent(new KeyEvent(1, 1, eventAction, eventCode, 0, meta)); conn.sendKeyEvent(new KeyEvent(1, 1, eventAction, eventCode, 0, _meta_state));
if (eventAction == KeyEvent.ACTION_UP) if (eventAction == KeyEvent.ACTION_UP)
_autocap.event_sent(eventCode, meta); _autocap.event_sent(eventCode, _meta_state);
} }
void send_text(CharSequence text) void send_text(CharSequence text)
@@ -147,6 +197,96 @@ class KeyEventHandler implements Config.IKeyEventHandler
conn.performContextMenuAction(id); conn.performContextMenuAction(id);
} }
void handle_editing_key(KeyValue.Editing ev)
{
switch (ev)
{
case COPY: send_context_menu_action(android.R.id.copy); break;
case PASTE: send_context_menu_action(android.R.id.paste); break;
case CUT: send_context_menu_action(android.R.id.cut); break;
case SELECT_ALL: send_context_menu_action(android.R.id.selectAll); break;
case SHARE: send_context_menu_action(android.R.id.shareText); break;
case PASTE_PLAIN: send_context_menu_action(android.R.id.pasteAsPlainText); break;
case UNDO: send_context_menu_action(android.R.id.undo); break;
case REDO: send_context_menu_action(android.R.id.redo); break;
case REPLACE: send_context_menu_action(android.R.id.replaceText); break;
case ASSIST: send_context_menu_action(android.R.id.textAssist); break;
case AUTOFILL: send_context_menu_action(android.R.id.autofill); break;
case CURSOR_LEFT: move_cursor(-1); break;
case CURSOR_RIGHT: move_cursor(1); break;
}
}
static ExtractedTextRequest _move_cursor_req = null;
/** Query the cursor position. The extracted text is empty. Returns [null] if
the editor doesn't support this operation. */
ExtractedText get_cursor_pos(InputConnection conn)
{
if (_move_cursor_req == null)
{
_move_cursor_req = new ExtractedTextRequest();
_move_cursor_req.hintMaxChars = 0;
}
return conn.getExtractedText(_move_cursor_req, 0);
}
/** Move the cursor right or left, if possible without sending key events.
Unlike arrow keys, the selection is not removed even if shift is not on.
Falls back to sending arrow keys events if the editor do not support
moving the cursor or a modifier other than shift is pressed. */
void move_cursor(int d)
{
InputConnection conn = _recv.getCurrentInputConnection();
if (conn == null)
return;
ExtractedText et = get_cursor_pos(conn);
// Fallback to sending key events
if (_move_cursor_force_fallback
|| et == null
|| _mods.has(KeyValue.Modifier.CTRL)
|| _mods.has(KeyValue.Modifier.ALT)
|| _mods.has(KeyValue.Modifier.META))
{
move_cursor_fallback(d);
return;
}
int sel_start = et.selectionStart;
int sel_end = et.selectionEnd;
// Continue expanding the selection even if shift is not pressed
if (sel_end != sel_start)
{
sel_end += d;
if (sel_end == sel_start) // Avoid making the selection empty
sel_end += d;
}
else
{
sel_end += d;
// Leave 'sel_start' where it is if shift is pressed
if (!_mods.has(KeyValue.Modifier.SHIFT))
sel_start = sel_end;
}
if (!conn.setSelection(sel_start, sel_end))
move_cursor_fallback(d);
}
/** Send arrow keys as a fallback for editors that do not support
[getExtractedText] like Termux. */
void move_cursor_fallback(int d)
{
while (d < 0)
{
send_key_down_up(KeyEvent.KEYCODE_DPAD_LEFT);
d++;
}
while (d > 0)
{
send_key_down_up(KeyEvent.KEYCODE_DPAD_RIGHT);
d--;
}
}
public static interface IReceiver public static interface IReceiver
{ {
public void handle_event_key(KeyValue.Event ev); public void handle_event_key(KeyValue.Event ev);

File diff suppressed because it is too large Load Diff

View File

@@ -3,7 +3,7 @@ package juloo.keyboard2;
import android.view.KeyEvent; import android.view.KeyEvent;
import java.util.HashMap; import java.util.HashMap;
final class KeyValue public final class KeyValue
{ {
public static enum Event public static enum Event
{ {
@@ -12,14 +12,15 @@ final class KeyValue
SWITCH_NUMERIC, SWITCH_NUMERIC,
SWITCH_EMOJI, SWITCH_EMOJI,
SWITCH_BACK_EMOJI, SWITCH_BACK_EMOJI,
CHANGE_METHOD, CHANGE_METHOD_PICKER,
CHANGE_METHOD_PREV, CHANGE_METHOD_AUTO,
ACTION, ACTION,
SWITCH_SECOND, SWITCH_FORWARD,
SWITCH_SECOND_BACK, SWITCH_BACKWARD,
SWITCH_GREEKMATH, SWITCH_GREEKMATH,
CAPS_LOCK, CAPS_LOCK,
SWITCH_VOICE_TYPING, SWITCH_VOICE_TYPING,
SWITCH_VOICE_TYPING_CHOOSER,
} }
// Must be evaluated in the reverse order of their values. // Must be evaluated in the reverse order of their values.
@@ -70,6 +71,8 @@ final class KeyValue
SHARE, SHARE,
ASSIST, ASSIST,
AUTOFILL, AUTOFILL,
CURSOR_LEFT,
CURSOR_RIGHT,
} }
public static enum Placeholder public static enum Placeholder
@@ -180,11 +183,6 @@ final class KeyValue
return new KeyValue(String.valueOf(c), Kind.Char, c, getFlags()); return new KeyValue(String.valueOf(c), Kind.Char, c, getFlags());
} }
public KeyValue withString(String s)
{
return new KeyValue(s, Kind.String, 0, getFlags());
}
public KeyValue withSymbol(String s) public KeyValue withSymbol(String s)
{ {
return new KeyValue(s, (_code & KIND_BITS), (_code & VALUE_BITS), getFlags()); return new KeyValue(s, (_code & KIND_BITS), (_code & VALUE_BITS), getFlags());
@@ -278,10 +276,20 @@ final class KeyValue
return keyeventKey(String.valueOf((char)symbol), code, flags | FLAG_KEY_FONT); return keyeventKey(String.valueOf((char)symbol), code, flags | FLAG_KEY_FONT);
} }
private static KeyValue editingKey(String symbol, Editing action) private static KeyValue editingKey(String symbol, Editing action, int flags)
{ {
return new KeyValue(symbol, Kind.Editing, action.ordinal(), return new KeyValue(symbol, Kind.Editing, action.ordinal(),
FLAG_SPECIAL | FLAG_SECONDARY | FLAG_SMALLER_FONT); flags | FLAG_SPECIAL | FLAG_SECONDARY);
}
private static KeyValue editingKey(String symbol, Editing action)
{
return editingKey(symbol, action, FLAG_SMALLER_FONT);
}
private static KeyValue editingKey(int symbol, Editing action)
{
return editingKey(String.valueOf((char)symbol), action, FLAG_KEY_FONT);
} }
/** A key that do nothing but has a unique ID. */ /** A key that do nothing but has a unique ID. */
@@ -290,48 +298,56 @@ final class KeyValue
return new KeyValue("", Kind.Placeholder, id.ordinal(), 0); return new KeyValue("", Kind.Placeholder, id.ordinal(), 0);
} }
private static KeyValue fallbackMakeKey(String name) public static KeyValue makeStringKey(String str)
{ {
if (name.length() == 1) return makeStringKey(str, 0);
return new KeyValue(name, Kind.Char, name.charAt(0), 0); }
/** Make a key that types a string. A char key is returned for a string of
length 1. */
public static KeyValue makeStringKey(String str, int flags)
{
if (str.length() == 1)
return new KeyValue(str, Kind.Char, str.charAt(0), flags);
else else
return new KeyValue(name, Kind.String, 0, 0); return new KeyValue(str, Kind.String, 0, flags | FLAG_SMALLER_FONT);
} }
public static KeyValue getKeyByName(String name) public static KeyValue getKeyByName(String name)
{ {
switch (name) switch (name)
{ {
/* These symbols have special meaning when in `res/xml` and are escaped in /* These symbols have special meaning when in `srcs/layouts` and are
standard layouts. The backslash is not stripped when parsed from the escaped in standard layouts. The backslash is not stripped when parsed
custom layout option. */ from the custom layout option. */
case "\\?": return fallbackMakeKey("?"); case "\\?": return makeStringKey("?");
case "\\#": return fallbackMakeKey("#"); case "\\#": return makeStringKey("#");
case "\\@": return fallbackMakeKey("@"); case "\\@": return makeStringKey("@");
case "\\\\": return fallbackMakeKey("\\"); case "\\\\": return makeStringKey("\\");
case "shift": return modifierKey(0x0A, Modifier.SHIFT, 0); /* Modifiers and dead-keys */
case "shift": return modifierKey(0xE00A, Modifier.SHIFT, 0);
case "ctrl": return modifierKey("Ctrl", Modifier.CTRL, 0); case "ctrl": return modifierKey("Ctrl", Modifier.CTRL, 0);
case "alt": return modifierKey("Alt", Modifier.ALT, 0); case "alt": return modifierKey("Alt", Modifier.ALT, 0);
case "accent_aigu": return diacritic(0x50, Modifier.AIGU); case "accent_aigu": return diacritic(0xE050, Modifier.AIGU);
case "accent_caron": return diacritic(0x51, Modifier.CARON); case "accent_caron": return diacritic(0xE051, Modifier.CARON);
case "accent_cedille": return diacritic(0x52, Modifier.CEDILLE); case "accent_cedille": return diacritic(0xE052, Modifier.CEDILLE);
case "accent_circonflexe": return diacritic(0x53, Modifier.CIRCONFLEXE); case "accent_circonflexe": return diacritic(0xE053, Modifier.CIRCONFLEXE);
case "accent_grave": return diacritic(0x54, Modifier.GRAVE); case "accent_grave": return diacritic(0xE054, Modifier.GRAVE);
case "accent_macron": return diacritic(0x55, Modifier.MACRON); case "accent_macron": return diacritic(0xE055, Modifier.MACRON);
case "accent_ring": return diacritic(0x56, Modifier.RING); case "accent_ring": return diacritic(0xE056, Modifier.RING);
case "accent_tilde": return diacritic(0x57, Modifier.TILDE); case "accent_tilde": return diacritic(0xE057, Modifier.TILDE);
case "accent_trema": return diacritic(0x58, Modifier.TREMA); case "accent_trema": return diacritic(0xE058, Modifier.TREMA);
case "accent_ogonek": return diacritic(0x59, Modifier.OGONEK); case "accent_ogonek": return diacritic(0xE059, Modifier.OGONEK);
case "accent_dot_above": return diacritic(0x5A, Modifier.DOT_ABOVE); case "accent_dot_above": return diacritic(0xE05A, Modifier.DOT_ABOVE);
case "accent_double_aigu": return diacritic(0x5B, Modifier.DOUBLE_AIGU); case "accent_double_aigu": return diacritic(0xE05B, Modifier.DOUBLE_AIGU);
case "accent_slash": return diacritic(0x5C, Modifier.SLASH); case "accent_slash": return diacritic(0xE05C, Modifier.SLASH);
case "accent_arrow_right": return diacritic(0x5D, Modifier.ARROW_RIGHT); case "accent_arrow_right": return diacritic(0xE05D, Modifier.ARROW_RIGHT);
case "accent_breve": return diacritic(0x5E, Modifier.BREVE); case "accent_breve": return diacritic(0xE05E, Modifier.BREVE);
case "accent_bar": return diacritic(0x5F, Modifier.BAR); case "accent_bar": return diacritic(0xE05F, Modifier.BAR);
case "accent_dot_below": return diacritic(0x60, Modifier.DOT_BELOW); case "accent_dot_below": return diacritic(0xE060, Modifier.DOT_BELOW);
case "accent_horn": return diacritic(0x61, Modifier.HORN); case "accent_horn": return diacritic(0xE061, Modifier.HORN);
case "accent_hook_above": return diacritic(0x62, Modifier.HOOK_ABOVE); case "accent_hook_above": return diacritic(0xE062, Modifier.HOOK_ABOVE);
case "superscript": return modifierKey("Sup", Modifier.SUPERSCRIPT, 0); case "superscript": return modifierKey("Sup", Modifier.SUPERSCRIPT, 0);
case "subscript": return modifierKey("Sub", Modifier.SUBSCRIPT, 0); case "subscript": return modifierKey("Sub", Modifier.SUBSCRIPT, 0);
case "ordinal": return modifierKey("Ord", Modifier.ORDINAL, 0); case "ordinal": return modifierKey("Ord", Modifier.ORDINAL, 0);
@@ -340,32 +356,35 @@ final class KeyValue
case "fn": return modifierKey("Fn", Modifier.FN, 0); case "fn": return modifierKey("Fn", Modifier.FN, 0);
case "meta": return modifierKey("Meta", Modifier.META, 0); case "meta": return modifierKey("Meta", Modifier.META, 0);
case "config": return eventKey(0x04, Event.CONFIG, FLAG_SMALLER_FONT); /* Special event keys */
case "config": return eventKey(0xE004, Event.CONFIG, FLAG_SMALLER_FONT);
case "switch_text": return eventKey("ABC", Event.SWITCH_TEXT, FLAG_SMALLER_FONT); case "switch_text": return eventKey("ABC", Event.SWITCH_TEXT, FLAG_SMALLER_FONT);
case "switch_numeric": return eventKey("123+", Event.SWITCH_NUMERIC, FLAG_SMALLER_FONT); case "switch_numeric": return eventKey("123+", Event.SWITCH_NUMERIC, FLAG_SMALLER_FONT);
case "switch_emoji": return eventKey(0x01, Event.SWITCH_EMOJI, FLAG_SMALLER_FONT); case "switch_emoji": return eventKey(0xE001, Event.SWITCH_EMOJI, FLAG_SMALLER_FONT);
case "switch_back_emoji": return eventKey("ABC", Event.SWITCH_BACK_EMOJI, 0); case "switch_back_emoji": return eventKey("ABC", Event.SWITCH_BACK_EMOJI, 0);
case "switch_second": return eventKey(0x13, Event.SWITCH_SECOND, FLAG_SMALLER_FONT); case "switch_forward": return eventKey(0xE013, Event.SWITCH_FORWARD, FLAG_SMALLER_FONT);
case "switch_second_back": return eventKey(0x14, Event.SWITCH_SECOND_BACK, FLAG_SMALLER_FONT); case "switch_backward": return eventKey(0xE014, Event.SWITCH_BACKWARD, FLAG_SMALLER_FONT);
case "switch_greekmath": return eventKey("πλ∇¬", Event.SWITCH_GREEKMATH, FLAG_SMALLER_FONT); case "switch_greekmath": return eventKey("πλ∇¬", Event.SWITCH_GREEKMATH, FLAG_SMALLER_FONT);
case "change_method": return eventKey(0x09, Event.CHANGE_METHOD, FLAG_SMALLER_FONT); case "change_method": return eventKey(0xE009, Event.CHANGE_METHOD_PICKER, FLAG_SMALLER_FONT);
case "change_method_prev": return eventKey(0x09, Event.CHANGE_METHOD_PREV, FLAG_SMALLER_FONT); case "change_method_prev": return eventKey(0xE009, Event.CHANGE_METHOD_AUTO, FLAG_SMALLER_FONT);
case "action": return eventKey("Action", Event.ACTION, FLAG_SMALLER_FONT); // Will always be replaced case "action": return eventKey("Action", Event.ACTION, FLAG_SMALLER_FONT); // Will always be replaced
case "capslock": return eventKey(0x12, Event.CAPS_LOCK, 0); case "capslock": return eventKey(0xE012, Event.CAPS_LOCK, 0);
case "voice_typing": return eventKey(0x15, Event.SWITCH_VOICE_TYPING, FLAG_SMALLER_FONT); case "voice_typing": return eventKey(0xE015, Event.SWITCH_VOICE_TYPING, FLAG_SMALLER_FONT);
case "voice_typing_chooser": return eventKey(0xE015, Event.SWITCH_VOICE_TYPING_CHOOSER, FLAG_SMALLER_FONT);
/* Key events */
case "esc": return keyeventKey("Esc", KeyEvent.KEYCODE_ESCAPE, FLAG_SMALLER_FONT); case "esc": return keyeventKey("Esc", KeyEvent.KEYCODE_ESCAPE, FLAG_SMALLER_FONT);
case "enter": return keyeventKey(0x0E, KeyEvent.KEYCODE_ENTER, 0); case "enter": return keyeventKey(0xE00E, KeyEvent.KEYCODE_ENTER, 0);
case "up": return keyeventKey(0x05, KeyEvent.KEYCODE_DPAD_UP, 0); case "up": return keyeventKey(0xE005, KeyEvent.KEYCODE_DPAD_UP, 0);
case "right": return keyeventKey(0x06, KeyEvent.KEYCODE_DPAD_RIGHT, 0); case "right": return keyeventKey(0xE006, KeyEvent.KEYCODE_DPAD_RIGHT, 0);
case "down": return keyeventKey(0x07, KeyEvent.KEYCODE_DPAD_DOWN, 0); case "down": return keyeventKey(0xE007, KeyEvent.KEYCODE_DPAD_DOWN, 0);
case "left": return keyeventKey(0x08, KeyEvent.KEYCODE_DPAD_LEFT, 0); case "left": return keyeventKey(0xE008, KeyEvent.KEYCODE_DPAD_LEFT, 0);
case "page_up": return keyeventKey(0x02, KeyEvent.KEYCODE_PAGE_UP, 0); case "page_up": return keyeventKey(0xE002, KeyEvent.KEYCODE_PAGE_UP, 0);
case "page_down": return keyeventKey(0x03, KeyEvent.KEYCODE_PAGE_DOWN, 0); case "page_down": return keyeventKey(0xE003, KeyEvent.KEYCODE_PAGE_DOWN, 0);
case "home": return keyeventKey(0x0B, KeyEvent.KEYCODE_MOVE_HOME, 0); case "home": return keyeventKey(0xE00B, KeyEvent.KEYCODE_MOVE_HOME, 0);
case "end": return keyeventKey(0x0C, KeyEvent.KEYCODE_MOVE_END, 0); case "end": return keyeventKey(0xE00C, KeyEvent.KEYCODE_MOVE_END, 0);
case "backspace": return keyeventKey(0x11, KeyEvent.KEYCODE_DEL, 0); case "backspace": return keyeventKey(0xE011, KeyEvent.KEYCODE_DEL, 0);
case "delete": return keyeventKey(0x10, KeyEvent.KEYCODE_FORWARD_DEL, 0); case "delete": return keyeventKey(0xE010, KeyEvent.KEYCODE_FORWARD_DEL, 0);
case "insert": return keyeventKey("Ins", KeyEvent.KEYCODE_INSERT, FLAG_SMALLER_FONT); case "insert": return keyeventKey("Ins", KeyEvent.KEYCODE_INSERT, FLAG_SMALLER_FONT);
case "f1": return keyeventKey("F1", KeyEvent.KEYCODE_F1, 0); case "f1": return keyeventKey("F1", KeyEvent.KEYCODE_F1, 0);
case "f2": return keyeventKey("F2", KeyEvent.KEYCODE_F2, 0); case "f2": return keyeventKey("F2", KeyEvent.KEYCODE_F2, 0);
@@ -379,8 +398,9 @@ final class KeyValue
case "f10": return keyeventKey("F10", KeyEvent.KEYCODE_F10, 0); case "f10": return keyeventKey("F10", KeyEvent.KEYCODE_F10, 0);
case "f11": return keyeventKey("F11", KeyEvent.KEYCODE_F11, FLAG_SMALLER_FONT); case "f11": return keyeventKey("F11", KeyEvent.KEYCODE_F11, FLAG_SMALLER_FONT);
case "f12": return keyeventKey("F12", KeyEvent.KEYCODE_F12, FLAG_SMALLER_FONT); case "f12": return keyeventKey("F12", KeyEvent.KEYCODE_F12, FLAG_SMALLER_FONT);
case "tab": return keyeventKey(0x0F, KeyEvent.KEYCODE_TAB, FLAG_SMALLER_FONT); case "tab": return keyeventKey(0xE00F, KeyEvent.KEYCODE_TAB, FLAG_SMALLER_FONT);
/* Spaces */
case "\\t": return charKey("\\t", '\t', 0); // Send the tab character case "\\t": return charKey("\\t", '\t', 0); // Send the tab character
case "space": return charKey("\r", ' ', FLAG_KEY_FONT | FLAG_SECONDARY); case "space": return charKey("\r", ' ', FLAG_KEY_FONT | FLAG_SECONDARY);
case "nbsp": return charKey("\u237d", '\u00a0', FLAG_SMALLER_FONT); case "nbsp": return charKey("\u237d", '\u00a0', FLAG_SMALLER_FONT);
@@ -397,10 +417,6 @@ final class KeyValue
case "blt": return charKey("<", '>', 0); case "blt": return charKey("<", '>', 0);
case "bgt": return charKey(">", '<', 0); case "bgt": return charKey(">", '<', 0);
case "removed": return placeholderKey(Placeholder.REMOVED);
case "f11_placeholder": return placeholderKey(Placeholder.F11);
case "f12_placeholder": return placeholderKey(Placeholder.F12);
/* hebrew niqqud */ /* hebrew niqqud */
case "qamats": return charKey("\u05E7\u05B8", '\u05B8', 0); // kamatz case "qamats": return charKey("\u05E7\u05B8", '\u05B8', 0); // kamatz
case "patah": return charKey("\u05E4\u05B7", '\u05B7', 0); // patach case "patah": return charKey("\u05E4\u05B7", '\u05B7', 0); // patach
@@ -432,39 +448,30 @@ final class KeyValue
case "zwj": return charKey("zwj", '\u200D', 0); // zero-width joiner (provides ligature) case "zwj": return charKey("zwj", '\u200D', 0); // zero-width joiner (provides ligature)
case "zwnj": return charKey("zwnj", '\u200C', 0); // zero-width non joiner (prevents unintended ligature) case "zwnj": return charKey("zwnj", '\u200C', 0); // zero-width non joiner (prevents unintended ligature)
case "copy": return editingKey("copy", Editing.COPY); /* Editing keys */
case "paste": return editingKey("paste", Editing.PASTE); case "copy": return editingKey(0xE030, Editing.COPY);
case "cut": return editingKey("cut", Editing.CUT); case "paste": return editingKey(0xE032, Editing.PASTE);
case "selectAll": return editingKey("s. all", Editing.SELECT_ALL); case "cut": return editingKey(0xE031, Editing.CUT);
case "shareText": return editingKey("share", Editing.SHARE); case "selectAll": return editingKey(0xE033, Editing.SELECT_ALL);
case "pasteAsPlainText": return editingKey("<paste>", Editing.PASTE_PLAIN); case "shareText": return editingKey(0xE034, Editing.SHARE);
case "undo": return editingKey("undo", Editing.UNDO); case "pasteAsPlainText": return editingKey(0xE035, Editing.PASTE_PLAIN);
case "redo": return editingKey("redo", Editing.REDO); case "undo": return editingKey(0xE036, Editing.UNDO);
case "replaceText": return editingKey("repl.", Editing.REPLACE); case "redo": return editingKey(0xE037, Editing.REDO);
case "textAssist": return editingKey("assist", Editing.ASSIST); case "cursor_left": return editingKey(0xE008, Editing.CURSOR_LEFT);
case "autofill": return editingKey("auto.", Editing.AUTOFILL); case "cursor_right": return editingKey(0xE006, Editing.CURSOR_RIGHT);
default: return fallbackMakeKey(name); // These keys are not used
} case "replaceText": return editingKey("repl", Editing.REPLACE);
} case "textAssist": return editingKey(0xE038, Editing.ASSIST);
case "autofill": return editingKey("auto", Editing.AUTOFILL);
static final HashMap<String, String> keys_descr = new HashMap<String, String>(); /* Placeholder keys */
case "removed": return placeholderKey(Placeholder.REMOVED);
case "f11_placeholder": return placeholderKey(Placeholder.F11);
case "f12_placeholder": return placeholderKey(Placeholder.F12);
/* Some keys have a description attached. Return [null] if otherwise. */ /* Fallback to a string key that types its name */
public static String getKeyDescription(String name) default: return makeStringKey(name);
{
return keys_descr.get(name);
} }
static void addKeyDescr(String name, String descr)
{
keys_descr.put(name, descr);
}
static {
/* Keys description is shown in the settings. */
addKeyDescr("capslock", "Caps lock");
addKeyDescr("switch_greekmath", "Greek & math symbols");
addKeyDescr("voice_typing", "Voice typing");
} }
// Substitute for [assert], which has no effect on Android. // Substitute for [assert], which has no effect on Android.

View File

@@ -18,52 +18,64 @@ import android.view.inputmethod.InputMethodSubtype;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import java.util.AbstractMap.SimpleEntry; import java.util.AbstractMap.SimpleEntry;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import juloo.keyboard2.prefs.LayoutsPreference;
public class Keyboard2 extends InputMethodService public class Keyboard2 extends InputMethodService
implements SharedPreferences.OnSharedPreferenceChangeListener implements SharedPreferences.OnSharedPreferenceChangeListener
{ {
static private final String TAG = "Keyboard2";
private Keyboard2View _keyboardView; private Keyboard2View _keyboardView;
private KeyEventHandler _keyeventhandler; private KeyEventHandler _keyeventhandler;
// If not 'null', the layout to use instead of [_currentTextLayout]. /** If not 'null', the layout to use instead of [_config.current_layout]. */
private KeyboardData _currentSpecialLayout; private KeyboardData _currentSpecialLayout;
private Current_text_layout _currentTextLayout; /** Layout associated with the currently selected locale. Not 'null'. */
// Layout associated with the currently selected locale. Not 'null'.
private KeyboardData _localeTextLayout; private KeyboardData _localeTextLayout;
private ViewGroup _emojiPane = null; private ViewGroup _emojiPane = null;
public int actionId; // Action performed by the Action key. public int actionId; // Action performed by the Action key.
private Config _config; private Config _config;
private boolean _debug_logs = false; /** Layout currently visible before it has been modified. */
KeyboardData current_layout_unmodified()
{
if (_currentSpecialLayout != null)
return _currentSpecialLayout;
KeyboardData layout = null;
int layout_i = _config.get_current_layout();
if (layout_i >= _config.layouts.size())
layout_i = 0;
if (layout_i < _config.layouts.size())
layout = _config.layouts.get(layout_i);
if (layout == null)
layout = _localeTextLayout;
return layout;
}
/** Layout currently visible. */ /** Layout currently visible. */
KeyboardData current_layout() KeyboardData current_layout()
{ {
if (_currentSpecialLayout != null) if (_currentSpecialLayout != null)
return _currentSpecialLayout; return _currentSpecialLayout;
KeyboardData layout; return _config.modify_layout(current_layout_unmodified());
if (_currentTextLayout == Current_text_layout.SECONDARY)
layout = _config.second_layout;
else if (_config.layout == null)
layout = _localeTextLayout;
else
layout = _config.layout;
return _config.modify_layout(layout);
} }
void setTextLayout(Current_text_layout layout) void setTextLayout(int l)
{ {
_currentTextLayout = layout; _config.set_current_layout(l);
_currentSpecialLayout = null; _currentSpecialLayout = null;
_keyboardView.setKeyboard(current_layout()); _keyboardView.setKeyboard(current_layout());
} }
void incrTextLayout(int delta)
{
int s = _config.layouts.size();
setTextLayout((_config.get_current_layout() + delta + s) % s);
}
void setSpecialLayout(KeyboardData l) void setSpecialLayout(KeyboardData l)
{ {
_currentSpecialLayout = l; _currentSpecialLayout = l;
@@ -75,19 +87,26 @@ public class Keyboard2 extends InputMethodService
return KeyboardData.load(getResources(), layout_id); return KeyboardData.load(getResources(), layout_id);
} }
/** Load a layout that contains a numpad (eg. the pin entry). */
KeyboardData loadNumpad(int layout_id)
{
return _config.modify_numpad(KeyboardData.load(getResources(), layout_id),
current_layout_unmodified());
}
@Override @Override
public void onCreate() public void onCreate()
{ {
super.onCreate(); super.onCreate();
KeyboardData.init(getResources()); KeyboardData.init(getResources());
SharedPreferences prefs = DirectBootAwarePreferences.get_shared_preferences(this); SharedPreferences prefs = DirectBootAwarePreferences.get_shared_preferences(this);
prefs.registerOnSharedPreferenceChangeListener(this);
_keyeventhandler = new KeyEventHandler(getMainLooper(), this.new Receiver()); _keyeventhandler = new KeyEventHandler(getMainLooper(), this.new Receiver());
Config.initGlobalConfig(prefs, getResources(), _keyeventhandler); Config.initGlobalConfig(prefs, getResources(), _keyeventhandler);
prefs.registerOnSharedPreferenceChangeListener(this);
_config = Config.globalConfig(); _config = Config.globalConfig();
_keyboardView = (Keyboard2View)inflate_view(R.layout.keyboard); _keyboardView = (Keyboard2View)inflate_view(R.layout.keyboard);
_keyboardView.reset(); _keyboardView.reset();
_debug_logs = getResources().getBoolean(R.bool.debug_logs); Logs.set_debug_logs(getResources().getBoolean(R.bool.debug_logs));
} }
private List<InputMethodSubtype> getEnabledSubtypes(InputMethodManager imm) private List<InputMethodSubtype> getEnabledSubtypes(InputMethodManager imm)
@@ -99,36 +118,24 @@ public class Keyboard2 extends InputMethodService
return Arrays.asList(); return Arrays.asList();
} }
private void extra_keys_of_subtype(ExtraKeys dst, InputMethodSubtype subtype) private ExtraKeys extra_keys_of_subtype(InputMethodSubtype subtype)
{ {
String extra_keys = subtype.getExtraValueOf("extra_keys"); String extra_keys = subtype.getExtraValueOf("extra_keys");
String script = subtype.getExtraValueOf("script"); String script = subtype.getExtraValueOf("script");
if (extra_keys == null) if (extra_keys != null)
return; return ExtraKeys.parse(script, extra_keys);
dst.add_keys_for_script(script, ExtraKeys.parse_extra_keys(extra_keys)); return ExtraKeys.EMPTY;
} }
private void refreshAccentsOption(InputMethodManager imm, InputMethodSubtype subtype) private void refreshAccentsOption(InputMethodManager imm, InputMethodSubtype subtype)
{ {
ExtraKeys extra_keys = new ExtraKeys();
List<InputMethodSubtype> enabled_subtypes = getEnabledSubtypes(imm); List<InputMethodSubtype> enabled_subtypes = getEnabledSubtypes(imm);
switch (_config.accents) List<ExtraKeys> extra_keys = new ArrayList<ExtraKeys>();
{ // Gather extra keys from all enabled subtypes
// '3' was "all accents", now unused extra_keys.add(extra_keys_of_subtype(subtype));
case 1: case 3:
extra_keys_of_subtype(extra_keys, subtype);
for (InputMethodSubtype s : enabled_subtypes) for (InputMethodSubtype s : enabled_subtypes)
extra_keys_of_subtype(extra_keys, s); extra_keys.add(extra_keys_of_subtype(s));
break; _config.extra_keys_subtype = ExtraKeys.merge(extra_keys);
case 2:
extra_keys_of_subtype(extra_keys, subtype);
break;
case 4: break;
default: throw new IllegalArgumentException();
}
_config.extra_keys_subtype = extra_keys;
if (enabled_subtypes.size() > 1)
_config.shouldOfferSwitchingToNextInputMethod = true;
} }
InputMethodManager get_imm() InputMethodManager get_imm()
@@ -139,11 +146,7 @@ public class Keyboard2 extends InputMethodService
private void refreshSubtypeImm() private void refreshSubtypeImm()
{ {
InputMethodManager imm = get_imm(); InputMethodManager imm = get_imm();
if (VERSION.SDK_INT < 28) _config.shouldOfferVoiceTyping = true;
_config.shouldOfferSwitchingToNextInputMethod = true;
else
_config.shouldOfferSwitchingToNextInputMethod = shouldOfferSwitchingToNextInputMethod();
_config.shouldOfferVoiceTyping = (get_voice_typing_im(imm) != null);
KeyboardData default_layout = null; KeyboardData default_layout = null;
_config.extra_keys_subtype = null; _config.extra_keys_subtype = null;
if (VERSION.SDK_INT >= 12) if (VERSION.SDK_INT >= 12)
@@ -153,22 +156,13 @@ public class Keyboard2 extends InputMethodService
{ {
String s = subtype.getExtraValueOf("default_layout"); String s = subtype.getExtraValueOf("default_layout");
if (s != null) if (s != null)
default_layout = _config.layout_of_string(getResources(), s); default_layout = LayoutsPreference.layout_of_string(getResources(), s);
refreshAccentsOption(imm, subtype); refreshAccentsOption(imm, subtype);
} }
} }
if (default_layout == null) if (default_layout == null)
default_layout = KeyboardData.load(getResources(), R.xml.latn_qwerty_us); default_layout = loadLayout(R.xml.latn_qwerty_us);
_localeTextLayout = default_layout; _localeTextLayout = default_layout;
if (_config.second_layout == null)
{
_config.shouldOfferSwitchingToSecond = false;
_currentTextLayout = Current_text_layout.PRIMARY;
}
else
{
_config.shouldOfferSwitchingToSecond = true;
}
} }
private String actionLabel_of_imeAction(int action) private String actionLabel_of_imeAction(int action)
@@ -225,44 +219,21 @@ public class Keyboard2 extends InputMethodService
_keyboardView.reset(); _keyboardView.reset();
} }
/** Returns the id and subtype of the voice typing IM. Returns [null] if none private KeyboardData refresh_special_layout(EditorInfo info)
is installed or if the feature is unsupported. */
SimpleEntry<String, InputMethodSubtype> get_voice_typing_im(InputMethodManager imm)
{
if (VERSION.SDK_INT < 11) // Due to InputMethodSubtype
return null;
for (InputMethodInfo im : imm.getEnabledInputMethodList())
for (InputMethodSubtype imst : imm.getEnabledInputMethodSubtypeList(im, true))
// Switch to the first IM that has a subtype of this mode
if (imst.getMode().equals("voice"))
return new SimpleEntry(im.getId(), imst);
return null;
}
private void log_editor_info(EditorInfo info)
{
LogPrinter p = new LogPrinter(Log.DEBUG, TAG);
info.dump(p, "");
if (info.extras != null)
Log.d(TAG, "extras: "+info.extras.toString());
Log.d(TAG, "swapEnterActionKey: "+_config.swapEnterActionKey);
Log.d(TAG, "actionLabel: "+_config.actionLabel);
}
private void refresh_special_layout(EditorInfo info)
{ {
switch (info.inputType & InputType.TYPE_MASK_CLASS) switch (info.inputType & InputType.TYPE_MASK_CLASS)
{ {
case InputType.TYPE_CLASS_NUMBER: case InputType.TYPE_CLASS_NUMBER:
case InputType.TYPE_CLASS_PHONE: case InputType.TYPE_CLASS_PHONE:
case InputType.TYPE_CLASS_DATETIME: case InputType.TYPE_CLASS_DATETIME:
_currentSpecialLayout = if (_config.pin_entry_enabled)
_config.modify_numpad(KeyboardData.load(getResources(), R.xml.pin)); return loadNumpad(R.xml.pin);
break; else
return loadNumpad(R.xml.numeric);
default: default:
_currentSpecialLayout = null;
break; break;
} }
return null;
} }
@Override @Override
@@ -270,12 +241,11 @@ public class Keyboard2 extends InputMethodService
{ {
refresh_config(); refresh_config();
refresh_action_label(info); refresh_action_label(info);
refresh_special_layout(info); _currentSpecialLayout = refresh_special_layout(info);
_keyboardView.setKeyboard(current_layout()); _keyboardView.setKeyboard(current_layout());
_keyeventhandler.started(info); _keyeventhandler.started(info);
setInputView(_keyboardView); setInputView(_keyboardView);
if (_debug_logs) Logs.debug_startup_input_view(info, _config);
log_editor_info(info);
} }
@Override @Override
@@ -397,7 +367,7 @@ public class Keyboard2 extends InputMethodService
break; break;
case SWITCH_NUMERIC: case SWITCH_NUMERIC:
setSpecialLayout(_config.modify_numpad(loadLayout(R.xml.numeric))); setSpecialLayout(loadNumpad(R.xml.numeric));
break; break;
case SWITCH_EMOJI: case SWITCH_EMOJI:
@@ -410,15 +380,15 @@ public class Keyboard2 extends InputMethodService
setInputView(_keyboardView); setInputView(_keyboardView);
break; break;
case CHANGE_METHOD: case CHANGE_METHOD_PICKER:
get_imm().showInputMethodPicker(); get_imm().showInputMethodPicker();
break; break;
case CHANGE_METHOD_PREV: case CHANGE_METHOD_AUTO:
if (VERSION.SDK_INT < 28) if (VERSION.SDK_INT < 28)
get_imm().switchToLastInputMethod(getConnectionToken()); get_imm().switchToLastInputMethod(getConnectionToken());
else else
switchToPreviousInputMethod(); switchToNextInputMethod(false);
break; break;
case ACTION: case ACTION:
@@ -427,17 +397,16 @@ public class Keyboard2 extends InputMethodService
conn.performEditorAction(actionId); conn.performEditorAction(actionId);
break; break;
case SWITCH_SECOND: case SWITCH_FORWARD:
if (_config.second_layout != null) incrTextLayout(1);
setTextLayout(Current_text_layout.SECONDARY);
break; break;
case SWITCH_SECOND_BACK: case SWITCH_BACKWARD:
setTextLayout(Current_text_layout.PRIMARY); incrTextLayout(-1);
break; break;
case SWITCH_GREEKMATH: case SWITCH_GREEKMATH:
setSpecialLayout(_config.modify_numpad(loadLayout(R.xml.greekmath))); setSpecialLayout(loadNumpad(R.xml.greekmath));
break; break;
case CAPS_LOCK: case CAPS_LOCK:
@@ -445,14 +414,14 @@ public class Keyboard2 extends InputMethodService
break; break;
case SWITCH_VOICE_TYPING: case SWITCH_VOICE_TYPING:
SimpleEntry<String, InputMethodSubtype> im = get_voice_typing_im(get_imm()); if (!VoiceImeSwitcher.switch_to_voice_ime(Keyboard2.this, get_imm(),
if (im == null) Config.globalPrefs()))
return; _config.shouldOfferVoiceTyping = false;
// Best-effort. Good enough for triggering Google's voice typing. break;
if (VERSION.SDK_INT < 28)
switchInputMethod(im.getKey()); case SWITCH_VOICE_TYPING_CHOOSER:
else VoiceImeSwitcher.choose_voice_ime(Keyboard2.this, get_imm(),
switchInputMethod(im.getKey(), im.getValue()); Config.globalPrefs());
break; break;
} }
} }
@@ -477,10 +446,4 @@ public class Keyboard2 extends InputMethodService
{ {
return View.inflate(new ContextThemeWrapper(this, _config.theme), layout, null); return View.inflate(new ContextThemeWrapper(this, _config.theme), layout, null);
} }
private static enum Current_text_layout
{
PRIMARY,
SECONDARY
}
} }

View File

@@ -19,6 +19,9 @@ public class Keyboard2View extends View
implements View.OnTouchListener, Pointers.IPointerEventHandler implements View.OnTouchListener, Pointers.IPointerEventHandler
{ {
private KeyboardData _keyboard; private KeyboardData _keyboard;
/** The key holding the shift key is used to set shift state from
autocapitalisation. */
private KeyValue _shift_kv; private KeyValue _shift_kv;
private KeyboardData.Key _shift_key; private KeyboardData.Key _shift_key;
@@ -51,7 +54,12 @@ public class Keyboard2View extends View
_pointers = new Pointers(this, _config); _pointers = new Pointers(this, _config);
refresh_navigation_bar(context); refresh_navigation_bar(context);
setOnTouchListener(this); setOnTouchListener(this);
int layout_id = (attrs == null) ? 0 :
attrs.getAttributeResourceValue(null, "layout", 0);
if (layout_id == 0)
reset(); reset();
else
setKeyboard(KeyboardData.load(getResources(), layout_id));
} }
private Window getParentWindow(Context context) private Window getParentWindow(Context context)
@@ -113,11 +121,10 @@ public class Keyboard2View extends View
} }
else else
{ {
if ((flags & KeyValue.FLAG_FAKE_PTR) != 0) if ((flags & KeyValue.FLAG_FAKE_PTR) == 0)
return; // Don't remove locked pointers return; // Don't remove locked pointers
_pointers.remove_fake_pointer(_shift_kv, _shift_key); _pointers.remove_fake_pointer(_shift_kv, _shift_key);
} }
invalidate();
} }
public KeyValue modifyKey(KeyValue k, Pointers.Modifiers mods) public KeyValue modifyKey(KeyValue k, Pointers.Modifiers mods)
@@ -134,25 +141,32 @@ public class Keyboard2View extends View
return KeyModifier.modify(k, mods); return KeyModifier.modify(k, mods);
} }
public void onPointerDown(boolean isSwipe) public void onPointerDown(KeyValue k, boolean isSwipe)
{ {
updateFlags();
_config.handler.key_down(k, isSwipe);
invalidate(); invalidate();
vibrate(); vibrate();
} }
public void onPointerUp(KeyValue k, Pointers.Modifiers mods) public void onPointerUp(KeyValue k, Pointers.Modifiers mods)
{ {
// [key_up] must be called before [updateFlags]. The latter might disable
// flags.
_config.handler.key_up(k, mods); _config.handler.key_up(k, mods);
updateFlags();
invalidate(); invalidate();
} }
public void onPointerHold(KeyValue k, Pointers.Modifiers mods) public void onPointerHold(KeyValue k, Pointers.Modifiers mods)
{ {
_config.handler.key_up(k, mods); _config.handler.key_up(k, mods);
updateFlags();
} }
public void onPointerFlagsChanged(boolean shouldVibrate) public void onPointerFlagsChanged(boolean shouldVibrate)
{ {
updateFlags();
invalidate(); invalidate();
if (shouldVibrate) if (shouldVibrate)
vibrate(); vibrate();
@@ -161,6 +175,7 @@ public class Keyboard2View extends View
private void updateFlags() private void updateFlags()
{ {
_mods = _pointers.getModifiers(); _mods = _pointers.getModifiers();
_config.handler.mods_changed(_mods);
} }
@Override @Override
@@ -230,7 +245,7 @@ public class Keyboard2View extends View
private void vibrate() private void vibrate()
{ {
VibratorCompat.vibrate(this, _config.vibration_behavior); VibratorCompat.vibrate(this, _config);
} }
@Override @Override
@@ -278,23 +293,26 @@ public class Keyboard2View extends View
@Override @Override
protected void onDraw(Canvas canvas) protected void onDraw(Canvas canvas)
{ {
updateFlags();
// Set keyboard background opacity // Set keyboard background opacity
getBackground().setAlpha(_config.keyboardOpacity); getBackground().setAlpha(_config.keyboardOpacity);
// Set keys opacity // Set keys opacity
_theme.keyBgPaint.setAlpha(_config.keyOpacity); _theme.keyBgPaint.setAlpha(_config.keyOpacity);
_theme.keyDownBgPaint.setAlpha(_config.keyActivatedOpacity); _theme.keyDownBgPaint.setAlpha(_config.keyActivatedOpacity);
_theme.keyBorderPaint.setAlpha(_config.keyOpacity); _theme.keyBorderPaint.setAlpha(_config.keyOpacity);
float y = _config.marginTop + _config.keyVerticalInterval / 2; float key_vertical_margin = _config.key_vertical_margin * _config.keyHeight;
float key_horizontal_margin = _config.key_horizontal_margin * _keyWidth;
// Add half of the key margin on the left and on the top as it's then added
// on the right and on the bottom of every keys.
float y = _config.marginTop + key_vertical_margin / 2;
for (KeyboardData.Row row : _keyboard.rows) for (KeyboardData.Row row : _keyboard.rows)
{ {
y += row.shift * _config.keyHeight; y += row.shift * _config.keyHeight;
float x = _config.horizontal_margin + _config.keyHorizontalInterval / 2; float x = _config.horizontal_margin + key_horizontal_margin / 2;
float keyH = row.height * _config.keyHeight - _config.keyVerticalInterval; float keyH = row.height * _config.keyHeight - key_vertical_margin;
for (KeyboardData.Key k : row.keys) for (KeyboardData.Key k : row.keys)
{ {
x += k.shift * _keyWidth; x += k.shift * _keyWidth;
float keyW = _keyWidth * k.width - _config.keyHorizontalInterval; float keyW = _keyWidth * k.width - key_horizontal_margin;
boolean isKeyDown = _pointers.isKeyDown(k); boolean isKeyDown = _pointers.isKeyDown(k);
drawKeyFrame(canvas, x, y, keyW, keyH, isKeyDown); drawKeyFrame(canvas, x, y, keyW, keyH, isKeyDown);
if (k.keys[0] != null) if (k.keys[0] != null)
@@ -407,7 +425,12 @@ public class Keyboard2View extends View
x += keyW / 2f; x += keyW / 2f;
else else
x += (a == Paint.Align.LEFT) ? subPadding : keyW - subPadding; x += (a == Paint.Align.LEFT) ? subPadding : keyW - subPadding;
canvas.drawText(kv.getString(), x, y, p); String label = kv.getString();
int label_len = label.length();
// Limit the label of string keys to 3 characters
if (label_len > 3 && kv.getKind() == KeyValue.Kind.String)
label_len = 3;
canvas.drawText(label, 0, label_len, x, y, p);
} }
private void drawIndication(Canvas canvas, String indication, float x, private void drawIndication(Canvas canvas, String indication, float x,

View File

@@ -14,7 +14,7 @@ import java.util.Set;
import java.util.function.Function; import java.util.function.Function;
import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParser;
class KeyboardData public final class KeyboardData
{ {
public final List<Row> rows; public final List<Row> rows;
/** Total width of the keyboard. */ /** Total width of the keyboard. */
@@ -25,36 +25,91 @@ class KeyboardData
public final Modmap modmap; public final Modmap modmap;
/** Might be null. */ /** Might be null. */
public final String script; public final String script;
/** Might be different from [script]. Might be null. */
public final String numpad_script;
/** The [name] attribute. Might be null. */
public final String name;
/** Position of every keys on the layout, see [getKeys()]. */
private Map<KeyValue, KeyPos> _key_pos = null;
public KeyboardData mapKeys(MapKey f) public KeyboardData mapKeys(MapKey f)
{ {
ArrayList<Row> rows_ = new ArrayList<Row>(); ArrayList<Row> rows_ = new ArrayList<Row>();
for (Row r : rows) for (Row r : rows)
rows_.add(r.mapKeys(f)); rows_.add(r.mapKeys(f));
return new KeyboardData(rows_, keysWidth, modmap, script); return new KeyboardData(this, rows_);
} }
/** Add keys from the given iterator into the keyboard. Extra keys are added /** Add keys from the given iterator into the keyboard. Preferred position is
* on the empty key4 corner of the second row, from right to left. If there's specified via [PreferredPos]. */
* not enough room, key3 of the second row is tried then key2 and key1 of the public KeyboardData addExtraKeys(Iterator<Map.Entry<KeyValue, PreferredPos>> extra_keys)
* third row. */
public KeyboardData addExtraKeys(Iterator<KeyValue> k)
{ {
/* Keys that couldn't be placed at their preferred position. */
ArrayList<KeyValue> unplaced_keys = new ArrayList<KeyValue>();
ArrayList<Row> rows = new ArrayList<Row>(this.rows); ArrayList<Row> rows = new ArrayList<Row>(this.rows);
addExtraKeys_to_row(rows, k, 1, 4); while (extra_keys.hasNext())
addExtraKeys_to_row(rows, k, 1, 3);
addExtraKeys_to_row(rows, k, 2, 2);
addExtraKeys_to_row(rows, k, 2, 1);
if (k.hasNext())
{ {
for (int r = 0; r < rows.size(); r++) Map.Entry<KeyValue, PreferredPos> kp = extra_keys.next();
for (int c = 1; c <= 4; c++) if (!add_key_to_preferred_pos(rows, kp.getKey(), kp.getValue()))
addExtraKeys_to_row(rows, k, r, c); unplaced_keys.add(kp.getKey());
} }
return new KeyboardData(rows, keysWidth, modmap, script); for (KeyValue kv : unplaced_keys)
add_key_to_preferred_pos(rows, kv, PreferredPos.ANYWHERE);
return new KeyboardData(this, rows);
} }
public KeyboardData addNumPad() /** Place a key on the keyboard according to its preferred position. Mutates
[rows]. Returns [false] if it couldn't be placed. */
boolean add_key_to_preferred_pos(List<Row> rows, KeyValue kv, PreferredPos pos)
{
if (pos.next_to != null)
{
KeyPos next_to_pos = getKeys().get(pos.next_to);
if (next_to_pos != null
&& add_key_to_pos(rows, kv, next_to_pos.with_dir(-1)))
return true;
}
for (KeyPos p : pos.positions)
if (add_key_to_pos(rows, kv, p))
return true;
return false;
}
/** Place a key on the keyboard. A value of [-1] in one of the coordinate
means that the key can be placed anywhere in that coordinate, see
[PreferredPos]. Mutates [rows]. Returns [false] if it couldn't be placed.
*/
boolean add_key_to_pos(List<Row> rows, KeyValue kv, KeyPos p)
{
int i_row = p.row;
int i_row_end = p.row;
if (p.row == -1) { i_row = 0; i_row_end = rows.size() - 1; }
for (; i_row <= i_row_end; i_row++)
{
Row row = rows.get(i_row);
int i_col = p.col;
int i_col_end = p.col;
if (p.col == -1) { i_col = 0; i_col_end = row.keys.size() - 1; }
for (; i_col <= i_col_end; i_col++)
{
Key col = row.keys.get(i_col);
int i_dir = p.dir;
int i_dir_end = p.dir;
if (p.dir == -1) { i_dir = 1; i_dir_end = 4; }
for (; i_dir <= i_dir_end; i_dir++)
{
if (col.getKeyValue(i_dir) == null)
{
row.keys.set(i_col, col.withKeyValue(i_dir, kv));
return true;
}
}
}
}
return false;
}
public KeyboardData addNumPad(KeyboardData num_pad)
{ {
ArrayList<Row> extendedRows = new ArrayList<Row>(); ArrayList<Row> extendedRows = new ArrayList<Row>();
Iterator<Row> iterNumPadRows = num_pad.rows.iterator(); Iterator<Row> iterNumPadRows = num_pad.rows.iterator();
@@ -74,46 +129,34 @@ class KeyboardData
} }
extendedRows.add(new Row(keys, row.height, row.shift)); extendedRows.add(new Row(keys, row.height, row.shift));
} }
return new return new KeyboardData(this, extendedRows);
KeyboardData(extendedRows, compute_max_width(extendedRows), modmap, script);
} }
public KeyboardData addNumberRow() public KeyboardData addNumberRow()
{ {
ArrayList<Row> rows_ = new ArrayList<Row>(this.rows); ArrayList<Row> rows_ = new ArrayList<Row>(this.rows);
rows_.add(0, number_row.updateWidth(keysWidth)); rows_.add(0, number_row.updateWidth(keysWidth));
return new KeyboardData(rows_, keysWidth, modmap, script); return new KeyboardData(this, rows_);
} }
public Key findKeyWithValue(KeyValue kv) public Key findKeyWithValue(KeyValue kv)
{ {
for (Row r : rows) KeyPos pos = getKeys().get(kv);
{ if (pos == null || pos.row >= rows.size())
Key k = r.findKeyWithValue(kv);
if (k != null)
return k;
}
return null; return null;
return rows.get(pos.row).get_key_at_pos(pos);
} }
public void getKeys(Set<KeyValue> dst) /** This is computed once and cached. */
public Map<KeyValue, KeyPos> getKeys()
{ {
for (Row r : rows) if (_key_pos == null)
r.getKeys(dst);
}
private static void addExtraKeys_to_row(ArrayList<Row> rows, final Iterator<KeyValue> extra_keys, int row_i, final int d)
{ {
if (!extra_keys.hasNext() || row_i >= rows.size()) _key_pos = new HashMap<KeyValue, KeyPos>();
return; for (int r = 0; r < rows.size(); r++)
rows.set(row_i, rows.get(row_i).mapKeys(new MapKey(){ rows.get(r).getKeys(_key_pos, r);
public Key apply(Key k) {
if (k.getKeyValue(d) == null && extra_keys.hasNext())
return k.withKeyValue(d, extra_keys.next());
else
return k;
} }
})); return _key_pos;
} }
public static Row bottom_row; public static Row bottom_row;
@@ -161,9 +204,7 @@ class KeyboardData
{ {
try try
{ {
XmlPullParser parser = Xml.newPullParser(); return load_string_exn(src);
parser.setInput(new StringReader(src));
return parse_keyboard(parser);
} }
catch (Exception e) catch (Exception e)
{ {
@@ -171,13 +212,26 @@ class KeyboardData
} }
} }
/** Like [load_string] but throws an exception on error and do not return
[null]. */
public static KeyboardData load_string_exn(String src) throws Exception
{
XmlPullParser parser = Xml.newPullParser();
parser.setInput(new StringReader(src));
return parse_keyboard(parser);
}
private static KeyboardData parse_keyboard(XmlPullParser parser) throws Exception private static KeyboardData parse_keyboard(XmlPullParser parser) throws Exception
{ {
if (!expect_tag(parser, "keyboard")) if (!expect_tag(parser, "keyboard"))
throw new Exception("Empty layout file"); throw error(parser, "Expected tag <keyboard>");
boolean add_bottom_row = attribute_bool(parser, "bottom_row", true); boolean add_bottom_row = attribute_bool(parser, "bottom_row", true);
float specified_kw = attribute_float(parser, "width", 0f); float specified_kw = attribute_float(parser, "width", 0f);
String script = parser.getAttributeValue(null, "script"); String script = parser.getAttributeValue(null, "script");
String numpad_script = parser.getAttributeValue(null, "numpad_script");
if (numpad_script == null)
numpad_script = script;
String name = parser.getAttributeValue(null, "name");
ArrayList<Row> rows = new ArrayList<Row>(); ArrayList<Row> rows = new ArrayList<Row>();
Modmap modmap = null; Modmap modmap = null;
while (next_tag(parser)) while (next_tag(parser))
@@ -191,13 +245,13 @@ class KeyboardData
modmap = Modmap.parse(parser); modmap = Modmap.parse(parser);
break; break;
default: default:
throw new Exception("Unknown tag: " + parser.getName()); throw error(parser, "Expecting tag <row>, got <" + parser.getName() + ">");
} }
} }
float kw = (specified_kw != 0f) ? specified_kw : compute_max_width(rows); float kw = (specified_kw != 0f) ? specified_kw : compute_max_width(rows);
if (add_bottom_row) if (add_bottom_row)
rows.add(bottom_row.updateWidth(kw)); rows.add(bottom_row.updateWidth(kw));
return new KeyboardData(rows, kw, modmap, script); return new KeyboardData(rows, kw, modmap, script, numpad_script, name);
} }
private static float compute_max_width(List<Row> rows) private static float compute_max_width(List<Row> rows)
@@ -211,11 +265,12 @@ class KeyboardData
private static Row parse_row(XmlPullParser parser) throws Exception private static Row parse_row(XmlPullParser parser) throws Exception
{ {
if (!expect_tag(parser, "row")) if (!expect_tag(parser, "row"))
throw new Exception("Failed to parse row"); throw error(parser, "Expected tag <row>");
return Row.parse(parser); return Row.parse(parser);
} }
protected KeyboardData(List<Row> rows_, float kw, Modmap mm, String sc) protected KeyboardData(List<Row> rows_, float kw, Modmap mm, String sc,
String npsc, String name_)
{ {
float kh = 0.f; float kh = 0.f;
for (Row r : rows_) for (Row r : rows_)
@@ -223,10 +278,19 @@ class KeyboardData
rows = rows_; rows = rows_;
modmap = mm; modmap = mm;
script = sc; script = sc;
numpad_script = npsc;
name = name_;
keysWidth = kw; keysWidth = kw;
keysHeight = kh; keysHeight = kh;
} }
/** Copies the fields of an other keyboard, with rows changed. */
protected KeyboardData(KeyboardData src, List<Row> rows)
{
this(rows, compute_max_width(rows), src.modmap, src.script,
src.numpad_script, src.name);
}
public static class Row public static class Row
{ {
public final List<Key> keys; public final List<Key> keys;
@@ -258,10 +322,22 @@ class KeyboardData
return new Row(keys, h, shift); return new Row(keys, h, shift);
} }
public void getKeys(Set<KeyValue> dst) public Row copy()
{ {
for (Key k : keys) return new Row(new ArrayList<Key>(keys), height, shift);
k.getKeys(dst); }
public void getKeys(Map<KeyValue, KeyPos> dst, int row)
{
for (int c = 0; c < keys.size(); c++)
keys.get(c).getKeys(dst, row, c);
}
public Map<KeyValue, KeyPos> getKeys(int row)
{
Map<KeyValue, KeyPos> dst = new HashMap<KeyValue, KeyPos>();
getKeys(dst, row);
return dst;
} }
public Row mapKeys(MapKey f) public Row mapKeys(MapKey f)
@@ -281,12 +357,11 @@ class KeyboardData
}); });
} }
public Key findKeyWithValue(KeyValue kv) public Key get_key_at_pos(KeyPos pos)
{ {
for (Key k : keys) if (pos.col >= keys.size())
if (k.hasValue(kv))
return k;
return null; return null;
return keys.get(pos.col);
} }
} }
@@ -384,11 +459,11 @@ class KeyboardData
return new Key(keys, keysflags, width * s, shift, slider, indication); return new Key(keys, keysflags, width * s, shift, slider, indication);
} }
public void getKeys(Set<KeyValue> dst) public void getKeys(Map<KeyValue, KeyPos> dst, int row, int col)
{ {
for (int i = 0; i < keys.length; i++) for (int i = 0; i < keys.length; i++)
if (keys[i] != null) if (keys[i] != null)
dst.add(keys[i]); dst.put(keys[i], new KeyPos(row, col, i));
} }
public KeyValue getKeyValue(int i) public KeyValue getKeyValue(int i)
@@ -398,7 +473,8 @@ class KeyboardData
public Key withKeyValue(int i, KeyValue kv) public Key withKeyValue(int i, KeyValue kv)
{ {
KeyValue[] ks = Arrays.copyOf(keys, keys.length); KeyValue[] ks = new KeyValue[keys.length];
for (int j = 0; j < keys.length; j++) ks[j] = keys[j];
ks[i] = kv; ks[i] = kv;
int flags = (keysflags & ~(ALL_FLAGS << i)); int flags = (keysflags & ~(ALL_FLAGS << i));
return new Key(ks, flags, width, shift, slider, indication); return new Key(ks, flags, width, shift, slider, indication);
@@ -463,6 +539,66 @@ class KeyboardData
} }
} }
/** Position of a key on the layout. */
public final static class KeyPos
{
public final int row;
public final int col;
public final int dir;
public KeyPos(int r, int c, int d)
{
row = r;
col = c;
dir = d;
}
public KeyPos with_dir(int d)
{
return new KeyPos(row, col, d);
}
}
/** See [addExtraKeys()]. */
public final static class PreferredPos
{
public static final PreferredPos DEFAULT;
public static final PreferredPos ANYWHERE;
/** Prefer the free position on the same keyboard key as the specified key.
Considered before [positions]. Might be [null]. */
public KeyValue next_to = null;
/** Array of positions to try in order. The special value [-1] as [row],
[col] or [dir] means that the field is unspecified. Every possible
values are tried for unspecified fields. Unspecified fields are
searched in this order: [dir], [col], [row]. */
public KeyPos[] positions = ANYWHERE_POSITIONS;
public PreferredPos() {}
public PreferredPos(PreferredPos src)
{
next_to = src.next_to;
positions = src.positions;
}
static final KeyPos[] ANYWHERE_POSITIONS =
new KeyPos[]{ new KeyPos(-1, -1, -1) };
static
{
DEFAULT = new PreferredPos();
DEFAULT.positions = new KeyPos[]{
new KeyPos(1, -1, 4),
new KeyPos(1, -1, 3),
new KeyPos(2, -1, 2),
new KeyPos(2, -1, 1)
};
ANYWHERE = new PreferredPos();
}
}
/** Parsing utils */ /** Parsing utils */
/** Returns [false] on [END_DOCUMENT] or [END_TAG], [true] otherwise. */ /** Returns [false] on [END_DOCUMENT] or [END_TAG], [true] otherwise. */
@@ -485,7 +621,8 @@ class KeyboardData
if (!next_tag(parser)) if (!next_tag(parser))
return false; return false;
if (!parser.getName().equals(name)) if (!parser.getName().equals(name))
throw new Exception("Unknown tag: " + parser.getName()); throw error(parser, "Expecting tag <" + name + ">, got <" +
parser.getName() + ">");
return true; return true;
} }
@@ -504,4 +641,10 @@ class KeyboardData
return default_val; return default_val;
return Float.parseFloat(val); return Float.parseFloat(val);
} }
/** Construct a parsing error. */
private static Exception error(XmlPullParser parser, String message)
{
return new Exception(message + " " + parser.getPositionDescription());
}
} }

View File

@@ -2,30 +2,39 @@ package juloo.keyboard2;
import android.app.Activity; import android.app.Activity;
import android.content.Intent; import android.content.Intent;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Build.VERSION; import android.os.Build.VERSION;
import android.os.Bundle; import android.os.Bundle;
import android.provider.Settings; import android.provider.Settings;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText; import android.widget.EditText;
import android.widget.TextView; import android.widget.TextView;
import android.widget.VideoView;
public class LauncherActivity extends Activity public class LauncherActivity extends Activity
{ {
/** Text is replaced when receiving key events. */ /** Text is replaced when receiving key events. */
VideoView _intro_video;
TextView _tryhere_text; TextView _tryhere_text;
EditText _tryhere_area; EditText _tryhere_area;
@Override @Override
public void onCreate(Bundle savedInstanceState) public void onCreate(Bundle savedInstanceState)
{ {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.launcher_activity); setContentView(R.layout.launcher_activity);
_intro_video = (VideoView)findViewById(R.id.launcher_intro_video);
_tryhere_text = (TextView)findViewById(R.id.launcher_tryhere_text); _tryhere_text = (TextView)findViewById(R.id.launcher_tryhere_text);
_tryhere_area = (EditText)findViewById(R.id.launcher_tryhere_area); _tryhere_area = (EditText)findViewById(R.id.launcher_tryhere_area);
if (VERSION.SDK_INT > 28) if (VERSION.SDK_INT > 28)
_tryhere_area.addOnUnhandledKeyEventListener( _tryhere_area.addOnUnhandledKeyEventListener(
this.new Tryhere_OnUnhandledKeyEventListener()); this.new Tryhere_OnUnhandledKeyEventListener());
setup_intro_video(_intro_video);
} }
public void launch_imesettings(View _btn) public void launch_imesettings(View _btn)
@@ -33,6 +42,40 @@ public class LauncherActivity extends Activity
startActivity(new Intent(Settings.ACTION_INPUT_METHOD_SETTINGS)); startActivity(new Intent(Settings.ACTION_INPUT_METHOD_SETTINGS));
} }
public void launch_imepicker(View v)
{
InputMethodManager imm =
(InputMethodManager)getSystemService(INPUT_METHOD_SERVICE);
imm.showInputMethodPicker();
}
static void setup_intro_video(final VideoView v)
{
if (VERSION.SDK_INT >= 26)
v.setAudioFocusRequest(AudioManager.AUDIOFOCUS_NONE);
v.setVideoURI(Uri.parse("android.resource://" +
v.getContext().getPackageName() + "/" + R.raw.intro_video));
v.setOnPreparedListener(new MediaPlayer.OnPreparedListener()
{
@Override
public void onPrepared(MediaPlayer mp)
{
mp.setLooping(true);
}
});
v.setOnErrorListener(new MediaPlayer.OnErrorListener()
{
@Override
public boolean onError(MediaPlayer mp, int what, int extra)
{
v.stopPlayback();
v.setVisibility(View.GONE);
return true;
}
});
v.start();
}
final class Tryhere_OnUnhandledKeyEventListener implements View.OnUnhandledKeyEventListener final class Tryhere_OnUnhandledKeyEventListener implements View.OnUnhandledKeyEventListener
{ {
public boolean onUnhandledKeyEvent(View v, KeyEvent ev) public boolean onUnhandledKeyEvent(View v, KeyEvent ev)

View File

@@ -1,25 +0,0 @@
package juloo.keyboard2;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.preference.ListPreference;
import android.util.AttributeSet;
public class LayoutListPreference extends ListPreference
{
public LayoutListPreference(Context context, AttributeSet attrs)
{
super(context, attrs);
final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.LayoutListPreference);
String defaultString = a.getString(R.styleable.LayoutListPreference_defaultString);
a.recycle();
Resources res = context.getResources();
String[] entries = res.getStringArray(R.array.pref_layout_entries);
entries[0] = defaultString;
setEntries(entries);
setEntryValues(res.getStringArray(R.array.pref_layout_values));
setSummary("%s");
setDefaultValue("none");
}
}

View File

@@ -0,0 +1,51 @@
package juloo.keyboard2;
import android.util.Log;
import android.util.LogPrinter;
import android.view.inputmethod.EditorInfo;
import org.json.JSONException;
public final class Logs
{
static final String TAG = "juloo.keyboard2";
static LogPrinter _debug_logs = null;
public static void set_debug_logs(boolean d)
{
_debug_logs = d ? new LogPrinter(Log.DEBUG, TAG) : null;
}
public static void debug_startup_input_view(EditorInfo info, Config conf)
{
if (_debug_logs == null)
return;
info.dump(_debug_logs, "");
if (info.extras != null)
_debug_logs.println("extras: "+info.extras.toString());
_debug_logs.println("swapEnterActionKey: "+conf.swapEnterActionKey);
_debug_logs.println("actionLabel: "+conf.actionLabel);
}
public static void debug_config_migration(int from_version, int to_version)
{
debug("Migrating config version from " + from_version + " to " + to_version);
}
public static void debug(String s)
{
if (_debug_logs != null)
_debug_logs.println(s);
}
public static void exn(String msg, Exception e)
{
Log.e(TAG, msg, e);
}
public static void trace()
{
if (_debug_logs != null)
_debug_logs.println(Log.getStackTraceString(new Exception()));
}
}

View File

@@ -2,8 +2,10 @@ package juloo.keyboard2;
import android.os.Handler; import android.os.Handler;
import android.os.Message; import android.os.Message;
import java.util.Arrays;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.NoSuchElementException;
/** /**
* Manage pointers (fingers) on the screen and long presses. * Manage pointers (fingers) on the screen and long presses.
@@ -95,6 +97,7 @@ public final class Pointers implements Handler.Callback
if (locked) if (locked)
ptr.flags |= KeyValue.FLAG_LOCKED; ptr.flags |= KeyValue.FLAG_LOCKED;
_ptrs.add(ptr); _ptrs.add(ptr);
_handler.onPointerFlagsChanged(false);
} }
public void remove_fake_pointer(KeyValue kv, KeyboardData.Key key) public void remove_fake_pointer(KeyValue kv, KeyboardData.Key key)
@@ -102,6 +105,7 @@ public final class Pointers implements Handler.Callback
Pointer ptr = getLatched(key, kv); Pointer ptr = getLatched(key, kv);
if (ptr != null && (ptr.flags & KeyValue.FLAG_FAKE_PTR) != 0) if (ptr != null && (ptr.flags & KeyValue.FLAG_FAKE_PTR) != 0)
removePtr(ptr); removePtr(ptr);
_handler.onPointerFlagsChanged(false);
} }
// Receiving events // Receiving events
@@ -172,7 +176,7 @@ public final class Pointers implements Handler.Callback
Pointer ptr = new Pointer(pointerId, key, value, x, y, mods); Pointer ptr = new Pointer(pointerId, key, value, x, y, mods);
_ptrs.add(ptr); _ptrs.add(ptr);
startKeyRepeat(ptr); startKeyRepeat(ptr);
_handler.onPointerDown(false); _handler.onPointerDown(value, false);
} }
static final int[] DIRECTION_TO_INDEX = new int[]{ static final int[] DIRECTION_TO_INDEX = new int[]{
@@ -263,7 +267,7 @@ public final class Pointers implements Handler.Callback
{ {
startSliding(ptr, dy); startSliding(ptr, dy);
} }
_handler.onPointerDown(true); _handler.onPointerDown(newValue, true);
} }
} }
} }
@@ -383,7 +387,7 @@ public final class Pointers implements Handler.Callback
{ {
ptr.value = kv; ptr.value = kv;
ptr.flags = kv.getFlags(); ptr.flags = kv.getFlags();
_handler.onPointerDown(true); _handler.onPointerDown(kv, true);
return true; return true;
} }
// Stop repeating: Special keys // Stop repeating: Special keys
@@ -483,6 +487,12 @@ public final class Pointers implements Handler.Callback
return (Arrays.binarySearch(_mods, 0, _size, m) >= 0); return (Arrays.binarySearch(_mods, 0, _size, m) >= 0);
} }
/** Returns the activated modifiers that are not in [m2]. */
public Iterator<KeyValue.Modifier> diff(Modifiers m2)
{
return new ModifiersDiffIterator(this, m2);
}
@Override @Override
public int hashCode() { return Arrays.hashCode(_mods); } public int hashCode() { return Arrays.hashCode(_mods); }
@Override @Override
@@ -514,6 +524,60 @@ public final class Pointers implements Handler.Callback
} }
return new Modifiers(mods, size); return new Modifiers(mods, size);
} }
/** Returns modifiers that are in [m1_] but not in [m2_]. */
static final class ModifiersDiffIterator
implements Iterator<KeyValue.Modifier>
{
Modifiers m1;
int i1 = 0;
Modifiers m2;
int i2 = 0;
public ModifiersDiffIterator(Modifiers m1_, Modifiers m2_)
{
m1 = m1_;
m2 = m2_;
advance();
}
public boolean hasNext()
{
return i1 < m1._size;
}
public KeyValue.Modifier next()
{
if (i1 >= m1._size)
throw new NoSuchElementException();
KeyValue.Modifier m = m1._mods[i1];
i1++;
advance();
return m;
}
/** Advance to the next element if [i1] is not a valid element. The end
is reached when [i1 = m1.size()]. */
void advance()
{
while (i1 < m1.size())
{
KeyValue.Modifier m = m1._mods[i1];
while (true)
{
if (i2 >= m2._size)
return;
int d = m.compareTo(m2._mods[i2]);
if (d < 0)
return;
i2++;
if (d == 0)
break;
}
i1++;
}
}
}
} }
public interface IPointerEventHandler public interface IPointerEventHandler
@@ -522,8 +586,9 @@ public final class Pointers implements Handler.Callback
public KeyValue modifyKey(KeyValue k, Modifiers flags); public KeyValue modifyKey(KeyValue k, Modifiers flags);
/** A key is pressed. [getModifiers()] is uptodate. Might be called after a /** A key is pressed. [getModifiers()] is uptodate. Might be called after a
press or a swipe to a different value. */ press or a swipe to a different value. Down events are not paired with
public void onPointerDown(boolean isSwipe); up events. */
public void onPointerDown(KeyValue k, boolean isSwipe);
/** Key is released. [k] is the key that was returned by /** Key is released. [k] is the key that was returned by
[modifySelectedKey] or [modifySelectedKey]. */ [modifySelectedKey] or [modifySelectedKey]. */

View File

@@ -12,27 +12,19 @@ public class SettingsActivity extends PreferenceActivity
@Override @Override
public void onCreate(Bundle savedInstanceState) public void onCreate(Bundle savedInstanceState)
{ {
detectSystemTheme();
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
// The preferences can't be read when in direct-boot mode. Avoid crashing // The preferences can't be read when in direct-boot mode. Avoid crashing
// and don't allow changing the settings. // and don't allow changing the settings.
try { getPreferenceManager().getSharedPreferences(); } // Run the config migration on this prefs as it might be different from the
// one used by the keyboard, which have been migrated.
try
{
Config.migrate(getPreferenceManager().getSharedPreferences());
}
catch (Exception _e) { fallbackEncrypted(); return; } catch (Exception _e) { fallbackEncrypted(); return; }
addPreferencesFromResource(R.xml.settings); addPreferencesFromResource(R.xml.settings);
} }
/** The default theme is [Theme.DeviceDefault], which is dark. Detect if the
system is using light theme. */
void detectSystemTheme()
{
if (Build.VERSION.SDK_INT >= 14)
{
int ui_mode = getResources().getConfiguration().uiMode;
if ((ui_mode & Configuration.UI_MODE_NIGHT_NO) != 0)
setTheme(android.R.style.Theme_DeviceDefault_Light);
}
}
void fallbackEncrypted() void fallbackEncrypted()
{ {
// Can't communicate with the user here. // Can't communicate with the user here.

View File

@@ -1,7 +1,6 @@
package juloo.keyboard2; package juloo.keyboard2;
import android.content.Context; import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray; import android.content.res.TypedArray;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.Paint; import android.graphics.Paint;

View File

@@ -0,0 +1,46 @@
package juloo.keyboard2;
import android.app.AlertDialog;
import android.os.IBinder;
import android.view.Window;
import android.view.WindowManager;
import java.io.InputStream;
import java.io.InputStreamReader;
public final class Utils
{
/** Turn the first letter of a string uppercase. */
public static String capitalize_string(String s)
{
if (s.length() < 1)
return s;
// Make sure not to cut a code point in half
int i = s.offsetByCodePoints(0, 1);
return s.substring(0, i).toUpperCase() + s.substring(i);
}
/** Like [dialog.show()] but properly configure layout params when called
from an IME. [token] is the input view's [getWindowToken()]. */
public static void show_dialog_on_ime(AlertDialog dialog, IBinder token)
{
Window win = dialog.getWindow();
WindowManager.LayoutParams lp = win.getAttributes();
lp.token = token;
lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
win.setAttributes(lp);
win.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
dialog.show();
}
public static String read_all_utf8(InputStream inp) throws Exception
{
InputStreamReader reader = new InputStreamReader(inp, "UTF-8");
StringBuilder out = new StringBuilder();
int buff_length = 8000;
char[] buff = new char[buff_length];
int l;
while ((l = reader.read(buff, 0, buff_length)) != -1)
out.append(buff, 0, l);
return out.toString();
}
}

View File

@@ -8,32 +8,24 @@ import android.view.View;
public final class VibratorCompat public final class VibratorCompat
{ {
public static void vibrate(View v, VibrationBehavior b) public static void vibrate(View v, Config config)
{ {
switch (b) if (config.vibrate_custom)
{
if (config.vibrate_duration > 0)
vibrator_vibrate(v, config.vibrate_duration);
}
else
{ {
case DISABLED:
break;
case SYSTEM:
if (VERSION.SDK_INT >= 8) if (VERSION.SDK_INT >= 8)
v.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP, v.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP,
HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING); HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
break;
case STRONG:
vibrator_vibrate(v, 60);
break;
case MEDIUM:
vibrator_vibrate(v, 30);
break;
case LIGHT:
vibrator_vibrate(v, 15);
break;
} }
} }
/** Use the older [Vibrator] when the newer API is not available or the user /** Use the older [Vibrator] when the newer API is not available or the user
wants more control. */ wants more control. */
static void vibrator_vibrate(View v, int duration) static void vibrator_vibrate(View v, long duration)
{ {
try try
{ {
@@ -53,29 +45,4 @@ public final class VibratorCompat
} }
return vibrator_service; return vibrator_service;
} }
public static enum VibrationBehavior
{
DISABLED,
SYSTEM,
STRONG,
MEDIUM,
LIGHT;
VibrationBehavior() {}
/** Defaults [SYSTEM] for unrecognized strings. */
public static VibrationBehavior of_string(String s)
{
switch (s)
{
case "disabled": return DISABLED;
case "system": return SYSTEM;
case "strong": return STRONG;
case "medium": return MEDIUM;
case "light": return LIGHT;
default: return SYSTEM;
}
}
}
} }

View File

@@ -0,0 +1,153 @@
package juloo.keyboard2;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.inputmethodservice.InputMethodService;
import android.os.Build.VERSION;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodManager;
import android.view.inputmethod.InputMethodSubtype;
import android.widget.ArrayAdapter;
import java.util.AbstractMap.SimpleEntry;
import java.util.ArrayList;
import java.util.List;
class VoiceImeSwitcher
{
static final String PREF_LAST_USED = "voice_ime_last_used";
static final String PREF_KNOWN_IMES = "voice_ime_known";
/** Switch to the voice ime. This might open a chooser popup. Preferences are
used to store the last selected voice ime and to detect whether the
chooser popup must be shown. Returns [false] if the detection failed and
is unlikely to succeed. */
public static boolean switch_to_voice_ime(InputMethodService ims,
InputMethodManager imm, SharedPreferences prefs)
{
if (VERSION.SDK_INT < 11) // Due to InputMethodSubtype
return false;
List<IME> imes = get_voice_ime_list(imm);
String last_used = prefs.getString(PREF_LAST_USED, null);
String last_known_imes = prefs.getString(PREF_KNOWN_IMES, null);
IME last_used_ime = get_ime_by_id(imes, last_used);
if (imes.size() == 0)
return false;
if (last_used == null || last_known_imes == null || last_used_ime == null
|| !last_known_imes.equals(serialize_ime_ids(imes)))
choose_voice_ime_and_update_prefs(ims, prefs, imes);
else
switch_input_method(ims, last_used_ime);
return true;
}
public static boolean choose_voice_ime(InputMethodService ims,
InputMethodManager imm, SharedPreferences prefs)
{
if (VERSION.SDK_INT < 11) // Due to InputMethodSubtype
return false;
List<IME> imes = get_voice_ime_list(imm);
choose_voice_ime_and_update_prefs(ims, prefs, imes);
return true;
}
/** Show the voice IME chooser popup and switch to the selected IME.
Preferences are updated so that future calls to [switch_to_voice_ime]
switch to the newly selected IME. */
static void choose_voice_ime_and_update_prefs(final InputMethodService ims,
final SharedPreferences prefs, final List<IME> imes)
{
List<String> ime_display_names = get_ime_display_names(ims, imes);
ArrayAdapter layouts = new ArrayAdapter(ims, android.R.layout.simple_list_item_1, ime_display_names);
AlertDialog dialog = new AlertDialog.Builder(ims)
.setAdapter(layouts, new DialogInterface.OnClickListener(){
public void onClick(DialogInterface _dialog, int which)
{
IME selected = imes.get(which);
prefs.edit()
.putString(PREF_LAST_USED, selected.get_id())
.putString(PREF_KNOWN_IMES, serialize_ime_ids(imes))
.commit();
switch_input_method(ims, selected);
}
})
.create();
Utils.show_dialog_on_ime(dialog, ims.getWindow().getWindow().getDecorView().getWindowToken());
}
static void switch_input_method(InputMethodService ims, IME ime)
{
if (VERSION.SDK_INT < 28)
ims.switchInputMethod(ime.get_id());
else
ims.switchInputMethod(ime.get_id(), ime.subtype);
}
static IME get_ime_by_id(List<IME> imes, String id)
{
if (id != null)
for (IME ime : imes)
if (ime.get_id().equals(id))
return ime;
return null;
}
static List<String> get_ime_display_names(InputMethodService ims, List<IME> imes)
{
List<String> names = new ArrayList<String>();
for (IME ime : imes)
names.add(ime.get_display_name(ims));
return names;
}
static List<IME> get_voice_ime_list(InputMethodManager imm)
{
List<IME> imes = new ArrayList<IME>();
for (InputMethodInfo im : imm.getEnabledInputMethodList())
for (InputMethodSubtype imst : imm.getEnabledInputMethodSubtypeList(im, true))
if (imst.getMode().equals("voice"))
imes.add(new IME(im, imst));
return imes;
}
/** The chooser popup is shown whether this string changes. */
static String serialize_ime_ids(List<IME> imes)
{
StringBuilder b = new StringBuilder();
for (IME ime : imes)
{
b.append(ime.get_id());
b.append(',');
}
return b.toString();
}
static class IME
{
public final InputMethodInfo im;
public final InputMethodSubtype subtype;
IME(InputMethodInfo im_, InputMethodSubtype st)
{
im = im_;
subtype = st;
}
String get_id() { return im.getId(); }
/** Localised display name. */
String get_display_name(Context ctx)
{
String subtype_name = "";
if (VERSION.SDK_INT >= 14)
{
subtype_name = subtype.getDisplayName(ctx, im.getPackageName(), null).toString();
if (!subtype_name.equals(""))
subtype_name = " - " + subtype_name;
}
return im.loadLabel(ctx.getPackageManager()).toString() + subtype_name;
}
}
}

View File

@@ -0,0 +1,70 @@
package juloo.keyboard2.prefs;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.preference.Preference;
import android.preference.PreferenceCategory;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import juloo.keyboard2.*;
import org.json.JSONArray;
import org.json.JSONException;
/** Allows to enter custom keys to be added to the keyboard. This shows up at
the top of the "Add keys to the keyboard" option. */
public class CustomExtraKeysPreference extends ListGroupPreference<String>
{
/** This pref stores a list of strings encoded as JSON. */
static final String KEY = "custom_extra_keys";
static final ListGroupPreference.Serializer<String> SERIALIZER =
new ListGroupPreference.StringSerializer();
public CustomExtraKeysPreference(Context context, AttributeSet attrs)
{
super(context, attrs);
setKey(KEY);
}
public static Map<KeyValue, KeyboardData.PreferredPos> get(SharedPreferences prefs)
{
Map<KeyValue, KeyboardData.PreferredPos> kvs =
new HashMap<KeyValue, KeyboardData.PreferredPos>();
List<String> key_names = load_from_preferences(KEY, prefs, null, SERIALIZER);
if (key_names != null)
{
for (String key_name : key_names)
kvs.put(KeyValue.makeStringKey(key_name), KeyboardData.PreferredPos.DEFAULT);
}
return kvs;
}
String label_of_value(String value, int i) { return value; }
@Override
void select(final SelectionCallback<String> callback)
{
new AlertDialog.Builder(getContext())
.setView(R.layout.dialog_edit_text)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int which)
{
EditText input = (EditText)((AlertDialog)dialog).findViewById(R.id.text);
final String k = input.getText().toString();
if (!k.equals(""))
callback.select(k);
}
})
.setNegativeButton(android.R.string.cancel, null)
.show();
}
@Override
Serializer<String> get_serializer() { return SERIALIZER; }
}

View File

@@ -0,0 +1,180 @@
package juloo.keyboard2.prefs;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.preference.CheckBoxPreference;
import android.preference.PreferenceCategory;
import android.util.AttributeSet;
import android.view.View;
import android.widget.TextView;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import juloo.keyboard2.*;
/** This class implements the "extra keys" preference but also defines the
possible extra keys. */
public class ExtraKeysPreference extends PreferenceCategory
{
/** Array of the keys that can be selected. */
public static String[] extra_keys = new String[]
{
"alt",
"meta",
"voice_typing",
"accent_aigu",
"accent_grave",
"accent_double_aigu",
"accent_dot_above",
"accent_circonflexe",
"accent_tilde",
"accent_cedille",
"accent_trema",
"accent_ring",
"accent_caron",
"accent_macron",
"accent_ogonek",
"accent_breve",
"accent_slash",
"accent_bar",
"accent_dot_below",
"accent_hook_above",
"accent_horn",
"",
"ß",
"£",
"§",
"",
"ª",
"º",
"page_up",
"page_down",
"home",
"end",
"switch_greekmath",
"change_method",
"capslock",
"copy",
"paste",
"cut",
"selectAll",
"shareText",
"pasteAsPlainText",
"undo",
"redo",
"superscript",
"subscript",
};
/** Whether an extra key is enabled by default. */
public static boolean default_checked(String name)
{
switch (name)
{
case "voice_typing":
case "change_method":
return true;
default:
return false;
}
}
/** Text that describe a key. Might be null. */
static String key_description(Resources res, String name)
{
int id = 0;
switch (name)
{
case "capslock": id = R.string.key_descr_capslock; break;
case "switch_greekmath": id = R.string.key_descr_switch_greekmath; break;
case "change_method": id = R.string.key_descr_change_method; break;
case "voice_typing": id = R.string.key_descr_voice_typing; break;
case "copy": id = R.string.key_descr_copy; break;
case "paste": id = R.string.key_descr_paste; break;
case "cut": id = R.string.key_descr_cut; break;
case "selectAll": id = R.string.key_descr_selectAll; break;
case "shareText": id = R.string.key_descr_shareText; break;
case "pasteAsPlainText": id = R.string.key_descr_pasteAsPlainText; break;
case "undo": id = R.string.key_descr_undo; break;
case "redo": id = R.string.key_descr_redo; break;
case "ª": id = R.string.key_descr_ª; break;
case "º": id = R.string.key_descr_º; break;
case "superscript": id = R.string.key_descr_superscript; break;
case "subscript": id = R.string.key_descr_subscript; break;
case "page_up": id = R.string.key_descr_page_up; break;
case "page_down": id = R.string.key_descr_page_down; break;
case "home": id = R.string.key_descr_home; break;
case "end": id = R.string.key_descr_end; break;
}
if (id == 0)
return null;
return res.getString(id);
}
/** Get the set of enabled extra keys. */
public static Map<KeyValue, KeyboardData.PreferredPos> get_extra_keys(SharedPreferences prefs)
{
Map<KeyValue, KeyboardData.PreferredPos> ks =
new HashMap<KeyValue, KeyboardData.PreferredPos>();
for (String key_name : extra_keys)
{
if (prefs.getBoolean(pref_key_of_key_name(key_name),
default_checked(key_name)))
ks.put(KeyValue.getKeyByName(key_name), KeyboardData.PreferredPos.DEFAULT);
}
return ks;
}
boolean _attached = false; /** Whether it has already been attached. */
public ExtraKeysPreference(Context context, AttributeSet attrs)
{
super(context, attrs);
setOrderingAsAdded(true);
}
@Override
protected void onAttachedToActivity()
{
if (_attached)
return;
_attached = true;
for (String key_name : extra_keys)
addPreference(new ExtraKeyCheckBoxPreference(getContext(), key_name,
default_checked(key_name)));
}
public static String pref_key_of_key_name(String key_name)
{
return "extra_key_" + key_name;
}
static class ExtraKeyCheckBoxPreference extends CheckBoxPreference
{
boolean _key_font;
public ExtraKeyCheckBoxPreference(Context ctx, String key_name,
boolean default_checked)
{
super(ctx);
KeyValue kv = KeyValue.getKeyByName(key_name);
String title = kv.getString();
String descr = key_description(ctx.getResources(), key_name);
if (descr != null)
title += " (" + descr + ")";
setKey(pref_key_of_key_name(key_name));
setDefaultValue(default_checked);
setTitle(title);
_key_font = kv.hasFlags(KeyValue.FLAG_KEY_FONT);
}
@Override
protected void onBindView(View view)
{
super.onBindView(view);
TextView title = (TextView)view.findViewById(android.R.id.title);
title.setTypeface(_key_font ? Theme.getKeyFont(getContext()) : null);
}
}
}

View File

@@ -1,4 +1,4 @@
package juloo.common; package juloo.keyboard2.prefs;
import android.content.Context; import android.content.Context;
import android.content.res.TypedArray; import android.content.res.TypedArray;

View File

@@ -0,0 +1,302 @@
package juloo.keyboard2.prefs;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.widget.ArrayAdapter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import juloo.keyboard2.*;
import org.json.JSONException;
import org.json.JSONObject;
public class LayoutsPreference extends ListGroupPreference<LayoutsPreference.Layout>
{
static final String KEY = "layouts";
static final List<Layout> DEFAULT =
Collections.singletonList((Layout)new SystemLayout());
static final ListGroupPreference.Serializer<Layout> SERIALIZER =
new Serializer();
/** Text displayed for each layout in the dialog list. */
String[] _layout_display_names;
public LayoutsPreference(Context ctx, AttributeSet attrs)
{
super(ctx, attrs);
setKey(KEY);
Resources res = ctx.getResources();
_layout_display_names = res.getStringArray(R.array.pref_layout_entries);
}
/** Obtained from [res/values/layouts.xml]. */
static List<String> _unsafe_layout_ids_str = null;
static TypedArray _unsafe_layout_ids_res = null;
/** Layout internal names. Contains "system" and "custom". */
public static List<String> get_layout_names(Resources res)
{
if (_unsafe_layout_ids_str == null)
_unsafe_layout_ids_str = Arrays.asList(
res.getStringArray(R.array.pref_layout_values));
return _unsafe_layout_ids_str;
}
/** Layout resource id for a layout name. [-1] if not found. */
public static int layout_id_of_name(Resources res, String name)
{
if (_unsafe_layout_ids_res == null)
_unsafe_layout_ids_res = res.obtainTypedArray(R.array.layout_ids);
int i = get_layout_names(res).indexOf(name);
if (i >= 0)
return _unsafe_layout_ids_res.getResourceId(i, 0);
return -1;
}
/** [null] for the "system" layout. */
public static List<KeyboardData> load_from_preferences(Resources res, SharedPreferences prefs)
{
List<KeyboardData> layouts = new ArrayList<KeyboardData>();
for (Layout l : load_from_preferences(KEY, prefs, DEFAULT, SERIALIZER))
{
if (l instanceof NamedLayout)
layouts.add(layout_of_string(res, ((NamedLayout)l).name));
else if (l instanceof CustomLayout)
layouts.add(((CustomLayout)l).parsed);
else // instanceof SystemLayout
layouts.add(null);
}
return layouts;
}
/** Does not call [prefs.commit()]. */
public static void save_to_preferences(SharedPreferences.Editor prefs, List<Layout> items)
{
save_to_preferences(KEY, prefs, items, SERIALIZER);
}
public static KeyboardData layout_of_string(Resources res, String name)
{
int id = layout_id_of_name(res, name);
if (id > 0)
return KeyboardData.load(res, id);
// Might happen when the app is downgraded, return the system layout.
return null;
}
@Override
protected void onSetInitialValue(boolean restoreValue, Object defaultValue)
{
super.onSetInitialValue(restoreValue, defaultValue);
if (_values.size() == 0)
set_values(new ArrayList<Layout>(DEFAULT), false);
}
String label_of_layout(Layout l)
{
if (l instanceof NamedLayout)
{
String lname = ((NamedLayout)l).name;
int value_i = get_layout_names(getContext().getResources()).indexOf(lname);
return value_i < 0 ? lname : _layout_display_names[value_i];
}
else if (l instanceof CustomLayout)
{
// Use the layout's name if possible
CustomLayout cl = (CustomLayout)l;
if (cl.parsed != null && cl.parsed.name != null
&& !cl.parsed.name.equals(""))
return cl.parsed.name;
else
return getContext().getString(R.string.pref_layout_e_custom);
}
else // instanceof SystemLayout
return getContext().getString(R.string.pref_layout_e_system);
}
@Override
String label_of_value(Layout value, int i)
{
return getContext().getString(R.string.pref_layouts_item, i + 1,
label_of_layout(value));
}
@Override
AddButton on_attach_add_button(AddButton prev_btn)
{
if (prev_btn == null)
return new LayoutsAddButton(getContext());
return prev_btn;
}
@Override
boolean should_allow_remove_item(Layout value)
{
return (_values.size() > 1 && !(value instanceof CustomLayout));
}
@Override
ListGroupPreference.Serializer<Layout> get_serializer() { return SERIALIZER; }
@Override
void select(final SelectionCallback callback)
{
ArrayAdapter layouts = new ArrayAdapter(getContext(), android.R.layout.simple_list_item_1, _layout_display_names);
new AlertDialog.Builder(getContext())
.setView(R.layout.dialog_edit_text)
.setAdapter(layouts, new DialogInterface.OnClickListener(){
public void onClick(DialogInterface _dialog, int which)
{
String name = get_layout_names(getContext().getResources()).get(which);
switch (name)
{
case "system":
callback.select(new SystemLayout());
break;
case "custom":
select_custom(callback, read_initial_custom_layout());
break;
default:
callback.select(new NamedLayout(name));
break;
}
}
})
.show();
}
/** Dialog for specifying a custom layout. [initial_text] is the layout
description when modifying a layout. */
void select_custom(final SelectionCallback callback, String initial_text)
{
boolean allow_remove = callback.allow_remove() && _values.size() > 1;
CustomLayoutEditDialog.show(getContext(), initial_text, allow_remove,
new CustomLayoutEditDialog.Callback()
{
public void select(String text)
{
if (text == null)
callback.select(null);
else
callback.select(CustomLayout.parse(text));
}
public String validate(String text)
{
try
{
KeyboardData.load_string_exn(text);
return null; // Validation passed
}
catch (Exception e)
{
return e.getMessage();
}
}
});
}
/** Called when modifying a layout. Custom layouts behave differently. */
@Override
void select(final SelectionCallback callback, Layout prev_layout)
{
if (prev_layout instanceof CustomLayout)
select_custom(callback, ((CustomLayout)prev_layout).xml);
else
select(callback);
}
/** The initial text for the custom layout entry box. The qwerty_us layout is
a good default and contains a bit of documentation. */
String read_initial_custom_layout()
{
try
{
Resources res = getContext().getResources();
return Utils.read_all_utf8(res.openRawResource(R.raw.latn_qwerty_us));
}
catch (Exception _e)
{
return "";
}
}
class LayoutsAddButton extends AddButton
{
public LayoutsAddButton(Context ctx)
{
super(ctx);
setLayoutResource(R.layout.pref_layouts_add_btn);
}
}
/** A layout selected by the user. The only implementations are
[NamedLayout], [SystemLayout] and [CustomLayout]. */
public interface Layout {}
public static final class SystemLayout implements Layout
{
public SystemLayout() {}
}
/** The name of a layout defined in [srcs/layouts]. */
public static final class NamedLayout implements Layout
{
public final String name;
public NamedLayout(String n) { name = n; }
}
/** The XML description of a custom layout. */
public static final class CustomLayout implements Layout
{
public final String xml;
/** Might be null. */
public final KeyboardData parsed;
public CustomLayout(String xml_, KeyboardData k) { xml = xml_; parsed = k; }
public static CustomLayout parse(String xml)
{
KeyboardData parsed = null;
try { parsed = KeyboardData.load_string_exn(xml); }
catch (Exception e) {}
return new CustomLayout(xml, parsed);
}
}
/** Named layouts are serialized to strings and custom layouts to JSON
objects with a [kind] field. */
public static class Serializer implements ListGroupPreference.Serializer<Layout>
{
public Layout load_item(Object obj) throws JSONException
{
if (obj instanceof String)
{
String name = (String)obj;
if (name.equals("system"))
return new SystemLayout();
return new NamedLayout(name);
}
JSONObject obj_ = (JSONObject)obj;
switch (obj_.getString("kind"))
{
case "custom": return CustomLayout.parse(obj_.getString("xml"));
case "system": default: return new SystemLayout();
}
}
public Object save_item(Layout v) throws JSONException
{
if (v instanceof NamedLayout)
return ((NamedLayout)v).name;
if (v instanceof CustomLayout)
return new JSONObject().put("kind", "custom")
.put("xml", ((CustomLayout)v).xml);
return new JSONObject().put("kind", "system");
}
}
}

Some files were not shown because too many files have changed in this diff Show More