forked from extern/Unexpected-Keyboard
Compare commits
24 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
e22fc226a1 | ||
|
076177ab45 | ||
|
26ce238435 | ||
|
618aac254a | ||
|
32ae63341d | ||
|
caa397dd70 | ||
|
318d979f14 | ||
|
f7cd55e965 | ||
|
9b00e33c44 | ||
|
a3bf491c9a | ||
|
1b401e55c4 | ||
|
100e1574d5 | ||
|
dcfda35cee | ||
|
143718b1de | ||
|
2f8a2917a2 | ||
|
8d29d80fce | ||
|
700b7e9d19 | ||
|
59d2d05c50 | ||
|
d5f36885c4 | ||
|
461f966e6e | ||
|
3b2fad8996 | ||
|
d657d51c2b | ||
|
3d95af5806 | ||
|
58cb6ca232 |
Binary file not shown.
@ -63,7 +63,7 @@ Layout includes some ASCII punctuation but not all, missing: (, ), <, >, [, ], {
|
|||||||
0 warnings
|
0 warnings
|
||||||
# latn_bone
|
# 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 compose, loc end, loc home, loc page_down, loc page_up, loc switch_greekmath, loc voice_typing, switch_backward
|
Layout redefines the bottom row but some important keys are missing, missing: cursor_left, cursor_right, loc compose, loc end, loc home, loc page_down, loc page_up, loc switch_clipboard, loc switch_greekmath, loc voice_typing, switch_backward
|
||||||
2 warnings
|
2 warnings
|
||||||
# latn_colemak
|
# latn_colemak
|
||||||
Some keys contain whitespaces, unexpected: ́
|
Some keys contain whitespaces, unexpected: ́
|
||||||
@ -71,7 +71,8 @@ Some keys contain whitespaces, unexpected: ́
|
|||||||
# latn_dvorak
|
# latn_dvorak
|
||||||
0 warnings
|
0 warnings
|
||||||
# latn_neo2
|
# latn_neo2
|
||||||
0 warnings
|
Layout redefines the bottom row but some important keys are missing, missing: loc switch_clipboard
|
||||||
|
1 warnings
|
||||||
# latn_qwerty_br
|
# latn_qwerty_br
|
||||||
0 warnings
|
0 warnings
|
||||||
# latn_qwerty_cz
|
# latn_qwerty_cz
|
||||||
|
@ -6,7 +6,8 @@ warning_count = 0
|
|||||||
KNOWN_NOT_LAYOUT = set([
|
KNOWN_NOT_LAYOUT = set([
|
||||||
"number_row", "numpad", "pin",
|
"number_row", "numpad", "pin",
|
||||||
"bottom_row", "settings", "method",
|
"bottom_row", "settings", "method",
|
||||||
"greekmath", "numeric", "emoji_bottom_row" ])
|
"greekmath", "numeric", "emoji_bottom_row",
|
||||||
|
"clipboard_bottom_row" ])
|
||||||
|
|
||||||
def warn(msg):
|
def warn(msg):
|
||||||
global warning_count
|
global warning_count
|
||||||
|
1
res/drawable/ic_clipboard_paste.xml
Normal file
1
res/drawable/ic_clipboard_paste.xml
Normal file
@ -0,0 +1 @@
|
|||||||
|
<!-- drawable/file_send.xml --><vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:width="24dp" android:viewportWidth="24" android:viewportHeight="24"><path android:fillColor="#000000" android:pathData="M14,2H6C4.89,2 4,2.89 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2M12.54,19.37V17.37H8.54V15.38H12.54V13.38L15.54,16.38L12.54,19.37M13,9V3.5L18.5,9H13Z" /></vector>
|
1
res/drawable/ic_clipboard_save.xml
Normal file
1
res/drawable/ic_clipboard_save.xml
Normal file
@ -0,0 +1 @@
|
|||||||
|
<!-- drawable/bookmark_plus.xml --><vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:width="24dp" android:viewportWidth="24" android:viewportHeight="24"><path android:fillColor="#000000" android:pathData="M17,3A2,2 0 0,1 19,5V21L12,18L5,21V5C5,3.89 5.9,3 7,3H17M11,7V9H9V11H11V13H13V11H15V9H13V7H11Z" /></vector>
|
1
res/drawable/ic_delete.xml
Normal file
1
res/drawable/ic_delete.xml
Normal file
@ -0,0 +1 @@
|
|||||||
|
<!-- drawable/delete.xml --><vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:width="24dp" android:viewportWidth="24" android:viewportHeight="24"><path android:fillColor="#000000" android:pathData="M19,4H15.5L14.5,3H9.5L8.5,4H5V6H19M6,19A2,2 0 0,0 8,21H16A2,2 0 0,0 18,19V7H6V19Z" /></vector>
|
8
res/layout/clipboard_history_entry.xml
Normal file
8
res/layout/clipboard_history_entry.xml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content">
|
||||||
|
<TextView android:id="@+id/clipboard_entry_text" style="@style/clipboardEntry"/>
|
||||||
|
<LinearLayout style="@style/clipboardEntryButtons">
|
||||||
|
<View android:id="@+id/clipboard_entry_paste" style="@style/clipboardEntryButton" android:background="@drawable/ic_clipboard_paste"/>
|
||||||
|
<View android:id="@+id/clipboard_entry_addpin" style="@style/clipboardEntryButton" android:background="@drawable/ic_clipboard_save"/>
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
12
res/layout/clipboard_pane.xml
Normal file
12
res/layout/clipboard_pane.xml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:background="?attr/colorKeyboard" android:hardwareAccelerated="false">
|
||||||
|
<ScrollView android:layout_width="fill_parent" android:layout_height="@dimen/clipboard_view_height">
|
||||||
|
<LinearLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="wrap_content">
|
||||||
|
<juloo.keyboard2.ClipboardHistoryCheckBox android:text="@string/clipboard_history_heading" style="@style/clipboardHeading" android:layout_width="fill_parent" android:layout_height="wrap_content"/>
|
||||||
|
<juloo.keyboard2.ClipboardHistoryView android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="wrap_content" android:divider="?attr/clipboard_divider_color" android:dividerHeight="?attr/clipboard_divider_height"/>
|
||||||
|
<TextView android:text="@string/clipboard_pin_heading" style="@style/clipboardHeading" android:layout_width="fill_parent" android:layout_height="wrap_content"/>
|
||||||
|
<juloo.keyboard2.ClipboardPinView android:id="@+id/clipboard_pin_view" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="wrap_content" android:divider="?attr/clipboard_divider_color" android:dividerHeight="?attr/clipboard_divider_height"/>
|
||||||
|
</LinearLayout>
|
||||||
|
</ScrollView>
|
||||||
|
<juloo.keyboard2.Keyboard2View layout="@xml/clipboard_bottom_row" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="?attr/colorKeyboard"/>
|
||||||
|
</LinearLayout>
|
8
res/layout/clipboard_pin_entry.xml
Normal file
8
res/layout/clipboard_pin_entry.xml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content">
|
||||||
|
<TextView android:id="@+id/clipboard_pin_text" style="@style/clipboardEntry" android:maxLines="3"/>
|
||||||
|
<LinearLayout style="@style/clipboardEntryButtons">
|
||||||
|
<View android:id="@+id/clipboard_pin_paste" style="@style/clipboardEntryButton" android:background="@drawable/ic_clipboard_paste"/>
|
||||||
|
<View android:id="@+id/clipboard_pin_remove" style="@style/clipboardEntryButton" android:background="@drawable/ic_delete"/>
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
@ -116,4 +116,9 @@ Tato aplikace neobsahuje žádné reklamy, nevyužívá připojení k síti a je
|
|||||||
<string name="key_descr_page_down">Page Down</string>
|
<string name="key_descr_page_down">Page Down</string>
|
||||||
<string name="key_descr_home">Home</string>
|
<string name="key_descr_home">Home</string>
|
||||||
<string name="key_descr_end">End</string>
|
<string name="key_descr_end">End</string>
|
||||||
|
<!-- <string name="key_descr_clipboard">Clipboard manager</string> -->
|
||||||
|
<!-- <string name="clipboard_history_heading">Recently copied text</string> -->
|
||||||
|
<!-- <string name="clipboard_pin_heading">Pinned</string> -->
|
||||||
|
<!-- <string name="clipboard_remove_confirm">Remove this clipboard?</string> -->
|
||||||
|
<!-- <string name="clipboard_remove_confirmed">Yes</string> -->
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -116,4 +116,9 @@ Diese App enthält keine Werbung, benötigt keinen Netzwerkzugriff und ist quell
|
|||||||
<string name="key_descr_page_down">Bild ab</string>
|
<string name="key_descr_page_down">Bild ab</string>
|
||||||
<string name="key_descr_home">Pos1</string>
|
<string name="key_descr_home">Pos1</string>
|
||||||
<string name="key_descr_end">Ende</string>
|
<string name="key_descr_end">Ende</string>
|
||||||
|
<!-- <string name="key_descr_clipboard">Clipboard manager</string> -->
|
||||||
|
<!-- <string name="clipboard_history_heading">Recently copied text</string> -->
|
||||||
|
<!-- <string name="clipboard_pin_heading">Pinned</string> -->
|
||||||
|
<!-- <string name="clipboard_remove_confirm">Remove this clipboard?</string> -->
|
||||||
|
<!-- <string name="clipboard_remove_confirmed">Yes</string> -->
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -116,4 +116,9 @@ La misma no contiene ningún anuncio/publicidad, no realiza peticiones de red y
|
|||||||
<string name="key_descr_page_down">Re Pág</string>
|
<string name="key_descr_page_down">Re Pág</string>
|
||||||
<string name="key_descr_home">Inicio</string>
|
<string name="key_descr_home">Inicio</string>
|
||||||
<string name="key_descr_end">Fin</string>
|
<string name="key_descr_end">Fin</string>
|
||||||
|
<!-- <string name="key_descr_clipboard">Clipboard manager</string> -->
|
||||||
|
<!-- <string name="clipboard_history_heading">Recently copied text</string> -->
|
||||||
|
<!-- <string name="clipboard_pin_heading">Pinned</string> -->
|
||||||
|
<!-- <string name="clipboard_remove_confirm">Remove this clipboard?</string> -->
|
||||||
|
<!-- <string name="clipboard_remove_confirmed">Yes</string> -->
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -116,4 +116,9 @@ This application contains no ads, doesn't make any network requests and is Open
|
|||||||
<!-- <string name="key_descr_page_down">Page Down</string> -->
|
<!-- <string name="key_descr_page_down">Page Down</string> -->
|
||||||
<!-- <string name="key_descr_home">Home</string> -->
|
<!-- <string name="key_descr_home">Home</string> -->
|
||||||
<!-- <string name="key_descr_end">End</string> -->
|
<!-- <string name="key_descr_end">End</string> -->
|
||||||
|
<!-- <string name="key_descr_clipboard">Clipboard manager</string> -->
|
||||||
|
<!-- <string name="clipboard_history_heading">Recently copied text</string> -->
|
||||||
|
<!-- <string name="clipboard_pin_heading">Pinned</string> -->
|
||||||
|
<!-- <string name="clipboard_remove_confirm">Remove this clipboard?</string> -->
|
||||||
|
<!-- <string name="clipboard_remove_confirmed">Yes</string> -->
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -116,4 +116,9 @@ Cette application ne contient pas de publicité, n'accède pas au réseau et est
|
|||||||
<string name="key_descr_page_down">Page suivante</string>
|
<string name="key_descr_page_down">Page suivante</string>
|
||||||
<string name="key_descr_home">Début</string>
|
<string name="key_descr_home">Début</string>
|
||||||
<string name="key_descr_end">Fin</string>
|
<string name="key_descr_end">Fin</string>
|
||||||
|
<!-- <string name="key_descr_clipboard">Clipboard manager</string> -->
|
||||||
|
<!-- <string name="clipboard_history_heading">Recently copied text</string> -->
|
||||||
|
<!-- <string name="clipboard_pin_heading">Pinned</string> -->
|
||||||
|
<!-- <string name="clipboard_remove_confirm">Remove this clipboard?</string> -->
|
||||||
|
<!-- <string name="clipboard_remove_confirmed">Yes</string> -->
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -116,4 +116,9 @@ This application contains no ads, doesn't make any network requests and is Open
|
|||||||
<!-- <string name="key_descr_page_down">Page Down</string> -->
|
<!-- <string name="key_descr_page_down">Page Down</string> -->
|
||||||
<!-- <string name="key_descr_home">Home</string> -->
|
<!-- <string name="key_descr_home">Home</string> -->
|
||||||
<!-- <string name="key_descr_end">End</string> -->
|
<!-- <string name="key_descr_end">End</string> -->
|
||||||
|
<!-- <string name="key_descr_clipboard">Clipboard manager</string> -->
|
||||||
|
<!-- <string name="clipboard_history_heading">Recently copied text</string> -->
|
||||||
|
<!-- <string name="clipboard_pin_heading">Pinned</string> -->
|
||||||
|
<!-- <string name="clipboard_remove_confirm">Remove this clipboard?</string> -->
|
||||||
|
<!-- <string name="clipboard_remove_confirmed">Yes</string> -->
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -116,4 +116,9 @@ This application contains no ads, doesn't make any network requests and is Open
|
|||||||
<!-- <string name="key_descr_page_down">Page Down</string> -->
|
<!-- <string name="key_descr_page_down">Page Down</string> -->
|
||||||
<!-- <string name="key_descr_home">Home</string> -->
|
<!-- <string name="key_descr_home">Home</string> -->
|
||||||
<!-- <string name="key_descr_end">End</string> -->
|
<!-- <string name="key_descr_end">End</string> -->
|
||||||
|
<!-- <string name="key_descr_clipboard">Clipboard manager</string> -->
|
||||||
|
<!-- <string name="clipboard_history_heading">Recently copied text</string> -->
|
||||||
|
<!-- <string name="clipboard_pin_heading">Pinned</string> -->
|
||||||
|
<!-- <string name="clipboard_remove_confirm">Remove this clipboard?</string> -->
|
||||||
|
<!-- <string name="clipboard_remove_confirmed">Yes</string> -->
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -118,4 +118,9 @@ Tagad lieliski piemērota izmantošanai ikdienā.
|
|||||||
<string name="key_descr_page_down">Lejupšķirt</string>
|
<string name="key_descr_page_down">Lejupšķirt</string>
|
||||||
<string name="key_descr_home">Sākums</string>
|
<string name="key_descr_home">Sākums</string>
|
||||||
<string name="key_descr_end">Beigas</string>
|
<string name="key_descr_end">Beigas</string>
|
||||||
|
<!-- <string name="key_descr_clipboard">Clipboard manager</string> -->
|
||||||
|
<!-- <string name="clipboard_history_heading">Recently copied text</string> -->
|
||||||
|
<!-- <string name="clipboard_pin_heading">Pinned</string> -->
|
||||||
|
<!-- <string name="clipboard_remove_confirm">Remove this clipboard?</string> -->
|
||||||
|
<!-- <string name="clipboard_remove_confirmed">Yes</string> -->
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -116,4 +116,9 @@ Aplikacja nie zawiera reklam, nie żąda dostępu do internetu, a jej kod źród
|
|||||||
<string name="key_descr_page_down">Page Down</string>
|
<string name="key_descr_page_down">Page Down</string>
|
||||||
<string name="key_descr_home">Home</string>
|
<string name="key_descr_home">Home</string>
|
||||||
<string name="key_descr_end">End</string>
|
<string name="key_descr_end">End</string>
|
||||||
|
<!-- <string name="key_descr_clipboard">Clipboard manager</string> -->
|
||||||
|
<!-- <string name="clipboard_history_heading">Recently copied text</string> -->
|
||||||
|
<!-- <string name="clipboard_pin_heading">Pinned</string> -->
|
||||||
|
<!-- <string name="clipboard_remove_confirm">Remove this clipboard?</string> -->
|
||||||
|
<!-- <string name="clipboard_remove_confirmed">Yes</string> -->
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -116,4 +116,9 @@ Este aplicativo não contém anúncios, não faz nenhuma solicitação de rede e
|
|||||||
<string name="key_descr_page_down">Page Down</string>
|
<string name="key_descr_page_down">Page Down</string>
|
||||||
<string name="key_descr_home">Home</string>
|
<string name="key_descr_home">Home</string>
|
||||||
<string name="key_descr_end">End</string>
|
<string name="key_descr_end">End</string>
|
||||||
|
<!-- <string name="key_descr_clipboard">Clipboard manager</string> -->
|
||||||
|
<!-- <string name="clipboard_history_heading">Recently copied text</string> -->
|
||||||
|
<!-- <string name="clipboard_pin_heading">Pinned</string> -->
|
||||||
|
<!-- <string name="clipboard_remove_confirm">Remove this clipboard?</string> -->
|
||||||
|
<!-- <string name="clipboard_remove_confirmed">Yes</string> -->
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -116,4 +116,9 @@ Această aplicație nu conține publicitate, nu folosește rețeaua deloc și e
|
|||||||
<!-- <string name="key_descr_page_down">Page Down</string> -->
|
<!-- <string name="key_descr_page_down">Page Down</string> -->
|
||||||
<!-- <string name="key_descr_home">Home</string> -->
|
<!-- <string name="key_descr_home">Home</string> -->
|
||||||
<!-- <string name="key_descr_end">End</string> -->
|
<!-- <string name="key_descr_end">End</string> -->
|
||||||
|
<!-- <string name="key_descr_clipboard">Clipboard manager</string> -->
|
||||||
|
<!-- <string name="clipboard_history_heading">Recently copied text</string> -->
|
||||||
|
<!-- <string name="clipboard_pin_heading">Pinned</string> -->
|
||||||
|
<!-- <string name="clipboard_remove_confirm">Remove this clipboard?</string> -->
|
||||||
|
<!-- <string name="clipboard_remove_confirmed">Yes</string> -->
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -116,4 +116,9 @@
|
|||||||
<string name="key_descr_page_down">Страница вниз</string>
|
<string name="key_descr_page_down">Страница вниз</string>
|
||||||
<string name="key_descr_home">Home</string>
|
<string name="key_descr_home">Home</string>
|
||||||
<string name="key_descr_end">End</string>
|
<string name="key_descr_end">End</string>
|
||||||
|
<!-- <string name="key_descr_clipboard">Clipboard manager</string> -->
|
||||||
|
<!-- <string name="clipboard_history_heading">Recently copied text</string> -->
|
||||||
|
<!-- <string name="clipboard_pin_heading">Pinned</string> -->
|
||||||
|
<!-- <string name="clipboard_remove_confirm">Remove this clipboard?</string> -->
|
||||||
|
<!-- <string name="clipboard_remove_confirmed">Yes</string> -->
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -116,4 +116,9 @@ Bu uygulama açık kaynaklıdır. Reklam içermez ve internete bağlanmaz."</str
|
|||||||
<string name="key_descr_page_down">Aşağı</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_home">BAŞ(Sol yön tuşu)</string>
|
||||||
<string name="key_descr_end">SON(Sağ yön tuşu)</string>
|
<string name="key_descr_end">SON(Sağ yön tuşu)</string>
|
||||||
|
<!-- <string name="key_descr_clipboard">Clipboard manager</string> -->
|
||||||
|
<!-- <string name="clipboard_history_heading">Recently copied text</string> -->
|
||||||
|
<!-- <string name="clipboard_pin_heading">Pinned</string> -->
|
||||||
|
<!-- <string name="clipboard_remove_confirm">Remove this clipboard?</string> -->
|
||||||
|
<!-- <string name="clipboard_remove_confirmed">Yes</string> -->
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -116,4 +116,9 @@
|
|||||||
<string name="key_descr_page_down">Page Down</string>
|
<string name="key_descr_page_down">Page Down</string>
|
||||||
<string name="key_descr_home">Home</string>
|
<string name="key_descr_home">Home</string>
|
||||||
<string name="key_descr_end">End</string>
|
<string name="key_descr_end">End</string>
|
||||||
|
<!-- <string name="key_descr_clipboard">Clipboard manager</string> -->
|
||||||
|
<!-- <string name="clipboard_history_heading">Recently copied text</string> -->
|
||||||
|
<!-- <string name="clipboard_pin_heading">Pinned</string> -->
|
||||||
|
<!-- <string name="clipboard_remove_confirm">Remove this clipboard?</string> -->
|
||||||
|
<!-- <string name="clipboard_remove_confirmed">Yes</string> -->
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -116,4 +116,9 @@ Bây giờ đã hoàn hảo cho việc sử dụng hàng ngày.
|
|||||||
<!-- <string name="key_descr_page_down">Page Down</string> -->
|
<!-- <string name="key_descr_page_down">Page Down</string> -->
|
||||||
<!-- <string name="key_descr_home">Home</string> -->
|
<!-- <string name="key_descr_home">Home</string> -->
|
||||||
<!-- <string name="key_descr_end">End</string> -->
|
<!-- <string name="key_descr_end">End</string> -->
|
||||||
|
<!-- <string name="key_descr_clipboard">Clipboard manager</string> -->
|
||||||
|
<!-- <string name="clipboard_history_heading">Recently copied text</string> -->
|
||||||
|
<!-- <string name="clipboard_pin_heading">Pinned</string> -->
|
||||||
|
<!-- <string name="clipboard_remove_confirm">Remove this clipboard?</string> -->
|
||||||
|
<!-- <string name="clipboard_remove_confirmed">Yes</string> -->
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -116,4 +116,9 @@
|
|||||||
<string name="key_descr_page_down">下一页</string>
|
<string name="key_descr_page_down">下一页</string>
|
||||||
<string name="key_descr_home">Home</string>
|
<string name="key_descr_home">Home</string>
|
||||||
<string name="key_descr_end">End</string>
|
<string name="key_descr_end">End</string>
|
||||||
|
<!-- <string name="key_descr_clipboard">Clipboard manager</string> -->
|
||||||
|
<!-- <string name="clipboard_history_heading">Recently copied text</string> -->
|
||||||
|
<!-- <string name="clipboard_pin_heading">Pinned</string> -->
|
||||||
|
<!-- <string name="clipboard_remove_confirm">Remove this clipboard?</string> -->
|
||||||
|
<!-- <string name="clipboard_remove_confirmed">Yes</string> -->
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -116,4 +116,9 @@ This application contains no ads, doesn't make any network requests and is Open
|
|||||||
<string name="key_descr_page_down">Page Down</string>
|
<string name="key_descr_page_down">Page Down</string>
|
||||||
<string name="key_descr_home">Home</string>
|
<string name="key_descr_home">Home</string>
|
||||||
<string name="key_descr_end">End</string>
|
<string name="key_descr_end">End</string>
|
||||||
|
<string name="key_descr_clipboard">Clipboard manager</string>
|
||||||
|
<string name="clipboard_history_heading">Recently copied text</string>
|
||||||
|
<string name="clipboard_pin_heading">Pinned</string>
|
||||||
|
<string name="clipboard_remove_confirm">Remove this clipboard?</string>
|
||||||
|
<string name="clipboard_remove_confirmed">Yes</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
|
<!-- Emoji pane -->
|
||||||
<style name="emojiTypeButton">
|
<style name="emojiTypeButton">
|
||||||
<item name="android:padding">1px</item>
|
<item name="android:padding">1px</item>
|
||||||
<item name="android:gravity">center</item>
|
<item name="android:gravity">center</item>
|
||||||
@ -15,6 +16,39 @@
|
|||||||
<item name="android:textSize">@dimen/emoji_text_size</item>
|
<item name="android:textSize">@dimen/emoji_text_size</item>
|
||||||
<item name="android:textColor">?attr/emoji_color</item>
|
<item name="android:textColor">?attr/emoji_color</item>
|
||||||
</style>
|
</style>
|
||||||
|
<!-- Clipboard pane -->
|
||||||
|
<style name="clipboardEntry">
|
||||||
|
<item name="android:layout_weight">1</item>
|
||||||
|
<item name="android:layout_width">fill_parent</item>
|
||||||
|
<item name="android:layout_height">wrap_content</item>
|
||||||
|
<item name="android:layout_marginHorizontal">14dp</item>
|
||||||
|
<item name="android:layout_marginVertical">14dp</item>
|
||||||
|
<item name="android:textSize">16dp</item>
|
||||||
|
<item name="android:textColor">?attr/colorLabel</item>
|
||||||
|
</style>
|
||||||
|
<style name="clipboardHeading">
|
||||||
|
<item name="android:layout_marginHorizontal">6dp</item>
|
||||||
|
<item name="android:layout_marginTop">14dp</item>
|
||||||
|
<item name="android:layout_marginBottom">0dp</item>
|
||||||
|
<item name="android:textSize">14dp</item>
|
||||||
|
<item name="android:fontWeight">700</item>
|
||||||
|
<item name="android:textColor">?attr/colorSubLabel</item>
|
||||||
|
</style>
|
||||||
|
<style name="clipboardEntryButtons">
|
||||||
|
<item name="android:orientation">horizontal</item>
|
||||||
|
<item name="android:layout_width">wrap_content</item>
|
||||||
|
<item name="android:layout_height">wrap_content</item>
|
||||||
|
<item name="android:layout_gravity">center_vertical</item>
|
||||||
|
<item name="android:layout_marginRight">12dp</item>
|
||||||
|
</style>
|
||||||
|
<style name="clipboardEntryButton">
|
||||||
|
<item name="android:layout_width">24dp</item>
|
||||||
|
<item name="android:layout_height">24dp</item>
|
||||||
|
<item name="android:layout_marginHorizontal">2dp</item>
|
||||||
|
<item name="android:backgroundTint">?attr/colorLabel</item>
|
||||||
|
<item name="android:backgroundTintMode">src_in</item>
|
||||||
|
</style>
|
||||||
|
<!-- Launcher activity -->
|
||||||
<style name="paragraph">
|
<style name="paragraph">
|
||||||
<item name="android:layout_width">fill_parent</item>
|
<item name="android:layout_width">fill_parent</item>
|
||||||
<item name="android:layout_height">wrap_content</item>
|
<item name="android:layout_height">wrap_content</item>
|
||||||
|
@ -23,11 +23,14 @@
|
|||||||
<attr name="keyBorderColorTop" format="color"/>
|
<attr name="keyBorderColorTop" format="color"/>
|
||||||
<attr name="keyBorderColorRight" format="color"/>
|
<attr name="keyBorderColorRight" format="color"/>
|
||||||
<attr name="keyBorderColorBottom" format="color"/>
|
<attr name="keyBorderColorBottom" format="color"/>
|
||||||
<!-- Emoji panel -->
|
<!-- Emoji pane -->
|
||||||
<attr name="emoji_button_bg" type="color" format="color"/>
|
<attr name="emoji_button_bg" type="color" format="color"/>
|
||||||
<attr name="emoji_color" type="color" format="color"/>
|
<attr name="emoji_color" type="color" format="color"/>
|
||||||
<attr name="emoji_key_bg" type="color" format="color"/>
|
<attr name="emoji_key_bg" type="color" format="color"/>
|
||||||
<attr name="emoji_key_text" type="color" format="color"/>
|
<attr name="emoji_key_text" type="color" format="color"/>
|
||||||
|
<!-- Clipboard pane -->
|
||||||
|
<attr name="clipboard_divider_color" type="color" format="color"/>
|
||||||
|
<attr name="clipboard_divider_height" format="dimension"/>
|
||||||
<!-- System integration -->
|
<!-- System integration -->
|
||||||
<attr name="navigationBarColor" format="color"/>
|
<attr name="navigationBarColor" format="color"/>
|
||||||
<attr name="windowLightNavigationBar" format="boolean"/>
|
<attr name="windowLightNavigationBar" format="boolean"/>
|
||||||
@ -43,6 +46,8 @@
|
|||||||
<item name="greyedDimming">0.5</item>
|
<item name="greyedDimming">0.5</item>
|
||||||
<item name="emoji_key_bg" type="color">?attr/emoji_button_bg</item>
|
<item name="emoji_key_bg" type="color">?attr/emoji_button_bg</item>
|
||||||
<item name="emoji_key_text" type="color">?attr/colorLabel</item>
|
<item name="emoji_key_text" type="color">?attr/colorLabel</item>
|
||||||
|
<item name="clipboard_divider_color" type="color">?attr/colorKey</item>
|
||||||
|
<item name="clipboard_divider_height">1px</item>
|
||||||
</style>
|
</style>
|
||||||
<style name="Dark" parent="BaseTheme">
|
<style name="Dark" parent="BaseTheme">
|
||||||
<item name="android:isLightTheme">false</item>
|
<item name="android:isLightTheme">false</item>
|
||||||
@ -116,6 +121,7 @@
|
|||||||
<item name="colorSubLabel">#333333</item>
|
<item name="colorSubLabel">#333333</item>
|
||||||
<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>
|
||||||
|
<item name="clipboard_divider_color" type="color">#eeeeee</item>
|
||||||
</style>
|
</style>
|
||||||
<style name="ePaper" parent="BaseTheme">
|
<style name="ePaper" parent="BaseTheme">
|
||||||
<item name="android:isLightTheme">true</item>
|
<item name="android:isLightTheme">true</item>
|
||||||
@ -134,6 +140,8 @@
|
|||||||
<item name="colorSubLabel">#333333</item>
|
<item name="colorSubLabel">#333333</item>
|
||||||
<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>
|
||||||
|
<item name="clipboard_divider_color" type="color">#000000</item>
|
||||||
|
<item name="clipboard_divider_height">2dp</item>
|
||||||
</style>
|
</style>
|
||||||
<style name="Desert" parent="@style/BaseTheme">
|
<style name="Desert" parent="@style/BaseTheme">
|
||||||
<item name="android:isLightTheme">true</item>
|
<item name="android:isLightTheme">true</item>
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
<dimen name="key_padding">2dp</dimen>
|
<dimen name="key_padding">2dp</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>
|
||||||
|
<dimen name="clipboard_view_height">300dp</dimen>
|
||||||
<dimen name="pref_button_size">28dp</dimen>
|
<dimen name="pref_button_size">28dp</dimen>
|
||||||
<bool name="debug_logs">false</bool> <!-- Will be overwritten automatically by Gradle for the debug build variant -->
|
<bool name="debug_logs">false</bool> <!-- Will be overwritten automatically by Gradle for the debug build variant -->
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?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" key3="loc switch_clipboard" key4="switch_numeric"/>
|
||||||
<key width="1.1" key0="fn" key1="loc alt" key2="loc 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_forward" key8="switch_backward" key5="cursor_left" key6="cursor_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 compose" 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.1" key0="loc compose" key7="up" key6="right" key5="left" key8="down" key1="loc home" key2="loc page_up" key3="loc end" key4="loc page_down"/>
|
||||||
|
10
res/xml/clipboard_bottom_row.xml
Normal file
10
res/xml/clipboard_bottom_row.xml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- The bottom row used in the clipboard history pane. -->
|
||||||
|
<keyboard bottom_row="false">
|
||||||
|
<row height="0.95">
|
||||||
|
<key key0="switch_back_clipboard"/>
|
||||||
|
<key width="3" key0="space" key5="cursor_left" key6="cursor_right" slider="true"/>
|
||||||
|
<key key0="backspace" key2="delete"/>
|
||||||
|
<key key0="enter" key2="action"/>
|
||||||
|
</row>
|
||||||
|
</keyboard>
|
22
srcs/juloo.keyboard2/ClipboardHistoryCheckBox.java
Normal file
22
srcs/juloo.keyboard2/ClipboardHistoryCheckBox.java
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package juloo.keyboard2;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.widget.CheckBox;
|
||||||
|
import android.widget.CompoundButton;
|
||||||
|
|
||||||
|
final class ClipboardHistoryCheckBox extends CheckBox
|
||||||
|
implements CompoundButton.OnCheckedChangeListener
|
||||||
|
{
|
||||||
|
public ClipboardHistoryCheckBox(Context ctx, AttributeSet attrs)
|
||||||
|
{
|
||||||
|
super(ctx, attrs);
|
||||||
|
setOnCheckedChangeListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCheckedChanged(CompoundButton _v, boolean isChecked)
|
||||||
|
{
|
||||||
|
ClipboardHistoryService.set_history_enabled(isChecked);
|
||||||
|
}
|
||||||
|
}
|
180
srcs/juloo.keyboard2/ClipboardHistoryService.java
Normal file
180
srcs/juloo.keyboard2/ClipboardHistoryService.java
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
package juloo.keyboard2;
|
||||||
|
|
||||||
|
import android.content.ClipData;
|
||||||
|
import android.content.ClipboardManager;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Build.VERSION;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public final class ClipboardHistoryService
|
||||||
|
{
|
||||||
|
/** Start the service on startup and start listening to clipboard changes. */
|
||||||
|
public static void on_startup(Context ctx, ClipboardPasteCallback cb)
|
||||||
|
{
|
||||||
|
get_service(ctx);
|
||||||
|
_paste_callback = cb;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Start the service if it hasn't been started before. Returns [null] if the
|
||||||
|
feature is unsupported. */
|
||||||
|
public static ClipboardHistoryService get_service(Context ctx)
|
||||||
|
{
|
||||||
|
if (VERSION.SDK_INT <= 11)
|
||||||
|
return null;
|
||||||
|
if (_service == null)
|
||||||
|
_service = new ClipboardHistoryService(ctx);
|
||||||
|
return _service;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void set_history_enabled(boolean e)
|
||||||
|
{
|
||||||
|
if (_service == null)
|
||||||
|
return;
|
||||||
|
Config.globalPrefs().edit()
|
||||||
|
.putBoolean("clipboard_history_enabled", e)
|
||||||
|
.commit();
|
||||||
|
if (e)
|
||||||
|
_service.add_current_clip();
|
||||||
|
else
|
||||||
|
_service.clear_history();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Send the given string to the editor. */
|
||||||
|
public static void paste(String clip)
|
||||||
|
{
|
||||||
|
if (_paste_callback != null)
|
||||||
|
_paste_callback.paste_from_clipboard_pane(clip);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The maximum size limits the amount of user data stored in memory but also
|
||||||
|
gives a sense to the user that the history is not persisted and can be
|
||||||
|
forgotten as soon as the app stops. */
|
||||||
|
public static final int MAX_HISTORY_SIZE = 3;
|
||||||
|
/** Time in ms until history entries expire. */
|
||||||
|
public static final long HISTORY_TTL_MS = 5 * 60 * 1000;
|
||||||
|
|
||||||
|
static ClipboardHistoryService _service = null;
|
||||||
|
static ClipboardPasteCallback _paste_callback = null;
|
||||||
|
|
||||||
|
ClipboardManager _cm;
|
||||||
|
List<HistoryEntry> _history;
|
||||||
|
OnClipboardHistoryChange _listener = null;
|
||||||
|
|
||||||
|
ClipboardHistoryService(Context ctx)
|
||||||
|
{
|
||||||
|
_history = new ArrayList<HistoryEntry>();
|
||||||
|
_cm = (ClipboardManager)ctx.getSystemService(Context.CLIPBOARD_SERVICE);
|
||||||
|
_cm.addPrimaryClipChangedListener(this.new SystemListener());
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> clear_expired_and_get_history()
|
||||||
|
{
|
||||||
|
long now_ms = System.currentTimeMillis();
|
||||||
|
List<String> dst = new ArrayList<String>();
|
||||||
|
Iterator<HistoryEntry> it = _history.iterator();
|
||||||
|
while (it.hasNext())
|
||||||
|
{
|
||||||
|
HistoryEntry ent = it.next();
|
||||||
|
if (ent.expiry_timestamp <= now_ms)
|
||||||
|
it.remove();
|
||||||
|
else
|
||||||
|
dst.add(ent.content);
|
||||||
|
}
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** This will call [on_clipboard_history_change]. */
|
||||||
|
public void remove_history_entry(String clip)
|
||||||
|
{
|
||||||
|
int last_pos = _history.size() - 1;
|
||||||
|
for (int pos = last_pos; pos >= 0; pos--)
|
||||||
|
{
|
||||||
|
if (!_history.get(pos).content.equals(clip))
|
||||||
|
continue;
|
||||||
|
// Removing the current clipboard, clear the system clipboard.
|
||||||
|
if (pos == last_pos)
|
||||||
|
{
|
||||||
|
if (VERSION.SDK_INT >= 28)
|
||||||
|
_cm.clearPrimaryClip();
|
||||||
|
else
|
||||||
|
_cm.setText("");
|
||||||
|
}
|
||||||
|
_history.remove(pos);
|
||||||
|
if (_listener != null)
|
||||||
|
_listener.on_clipboard_history_change();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Add clipboard entries to the history, skipping consecutive duplicates and
|
||||||
|
empty strings. */
|
||||||
|
public void add_clip(String clip)
|
||||||
|
{
|
||||||
|
if (!Config.globalConfig().clipboard_history_enabled)
|
||||||
|
return;
|
||||||
|
int size = _history.size();
|
||||||
|
if (clip.equals("") || (size > 0 && _history.get(size - 1).content.equals(clip)))
|
||||||
|
return;
|
||||||
|
if (size >= MAX_HISTORY_SIZE)
|
||||||
|
_history.remove(0);
|
||||||
|
_history.add(new HistoryEntry(clip));
|
||||||
|
if (_listener != null)
|
||||||
|
_listener.on_clipboard_history_change();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear_history()
|
||||||
|
{
|
||||||
|
_history.clear();
|
||||||
|
if (_listener != null)
|
||||||
|
_listener.on_clipboard_history_change();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set_on_clipboard_history_change(OnClipboardHistoryChange l) { _listener = l; }
|
||||||
|
|
||||||
|
public static interface OnClipboardHistoryChange
|
||||||
|
{
|
||||||
|
public void on_clipboard_history_change();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Add what is currently in the system clipboard into the history. */
|
||||||
|
void add_current_clip()
|
||||||
|
{
|
||||||
|
ClipData clip = _cm.getPrimaryClip();
|
||||||
|
if (clip == null)
|
||||||
|
return;
|
||||||
|
int count = clip.getItemCount();
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
add_clip(clip.getItemAt(i).getText().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
final class SystemListener implements ClipboardManager.OnPrimaryClipChangedListener
|
||||||
|
{
|
||||||
|
public SystemListener() {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPrimaryClipChanged()
|
||||||
|
{
|
||||||
|
add_current_clip();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static final class HistoryEntry
|
||||||
|
{
|
||||||
|
public final String content;
|
||||||
|
|
||||||
|
/** Time at which the entry expires. */
|
||||||
|
public final long expiry_timestamp;
|
||||||
|
|
||||||
|
public HistoryEntry(String c)
|
||||||
|
{
|
||||||
|
content = c;
|
||||||
|
expiry_timestamp = System.currentTimeMillis() + HISTORY_TTL_MS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface ClipboardPasteCallback
|
||||||
|
{
|
||||||
|
public void paste_from_clipboard_pane(String content);
|
||||||
|
}
|
||||||
|
}
|
125
srcs/juloo.keyboard2/ClipboardHistoryView.java
Normal file
125
srcs/juloo.keyboard2/ClipboardHistoryView.java
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
package juloo.keyboard2;
|
||||||
|
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.BaseAdapter;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public final class ClipboardHistoryView extends NonScrollListView
|
||||||
|
implements ClipboardHistoryService.OnClipboardHistoryChange
|
||||||
|
{
|
||||||
|
List<String> _history;
|
||||||
|
ClipboardHistoryService _service;
|
||||||
|
ClipboardEntriesAdapter _adapter;
|
||||||
|
|
||||||
|
public ClipboardHistoryView(Context ctx, AttributeSet attrs)
|
||||||
|
{
|
||||||
|
super(ctx, attrs);
|
||||||
|
_history = Collections.EMPTY_LIST;
|
||||||
|
_adapter = this.new ClipboardEntriesAdapter();
|
||||||
|
_service = ClipboardHistoryService.get_service(ctx);
|
||||||
|
if (_service != null)
|
||||||
|
{
|
||||||
|
_service.set_on_clipboard_history_change(this);
|
||||||
|
_history = _service.clear_expired_and_get_history();
|
||||||
|
}
|
||||||
|
setAdapter(_adapter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The history entry at index [pos] is removed from the history and added to
|
||||||
|
the list of pinned clipboards. */
|
||||||
|
public void pin_entry(int pos)
|
||||||
|
{
|
||||||
|
ClipboardPinView v = (ClipboardPinView)((ViewGroup)getParent().getParent()).findViewById(R.id.clipboard_pin_view);
|
||||||
|
String clip = _history.get(pos);
|
||||||
|
v.add_entry(clip);
|
||||||
|
_service.remove_history_entry(clip);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Send the specified entry to the editor. */
|
||||||
|
public void paste_entry(int pos)
|
||||||
|
{
|
||||||
|
ClipboardHistoryService.paste(_history.get(pos));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void on_clipboard_history_change()
|
||||||
|
{
|
||||||
|
update_data();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onWindowVisibilityChanged(int visibility)
|
||||||
|
{
|
||||||
|
if (visibility == View.VISIBLE)
|
||||||
|
update_data();
|
||||||
|
}
|
||||||
|
|
||||||
|
void update_data()
|
||||||
|
{
|
||||||
|
_history = _service.clear_expired_and_get_history();
|
||||||
|
_adapter.notifyDataSetChanged();
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
class ClipboardEntriesAdapter extends BaseAdapter
|
||||||
|
{
|
||||||
|
public ClipboardEntriesAdapter() {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCount() { return _history.size(); }
|
||||||
|
@Override
|
||||||
|
public Object getItem(int pos) { return _history.get(pos); }
|
||||||
|
@Override
|
||||||
|
public long getItemId(int pos) { return _history.get(pos).hashCode(); }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View getView(final int pos, View v, ViewGroup _parent)
|
||||||
|
{
|
||||||
|
if (v == null)
|
||||||
|
v = View.inflate(getContext(), R.layout.clipboard_history_entry, null);
|
||||||
|
((TextView)v.findViewById(R.id.clipboard_entry_text))
|
||||||
|
.setText(_history.get(pos));
|
||||||
|
v.findViewById(R.id.clipboard_entry_addpin).setOnClickListener(
|
||||||
|
new View.OnClickListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) { pin_entry(pos); }
|
||||||
|
});
|
||||||
|
v.findViewById(R.id.clipboard_entry_paste).setOnClickListener(
|
||||||
|
new View.OnClickListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) { paste_entry(pos); }
|
||||||
|
});
|
||||||
|
// v.findViewById(R.id.clipboard_entry_removehist).setOnClickListener(
|
||||||
|
// new View.OnClickListener()
|
||||||
|
// {
|
||||||
|
// @Override
|
||||||
|
// public void onClick(View v)
|
||||||
|
// {
|
||||||
|
// AlertDialog d = new AlertDialog.Builder(getContext())
|
||||||
|
// .setTitle(R.string.clipboard_remove_confirm)
|
||||||
|
// .setPositiveButton(R.string.clipboard_remove_confirmed,
|
||||||
|
// new DialogInterface.OnClickListener(){
|
||||||
|
// public void onClick(DialogInterface _dialog, int _which)
|
||||||
|
// {
|
||||||
|
// _service.remove_history_entry(_history.get(pos));
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// .setNegativeButton(android.R.string.cancel, null)
|
||||||
|
// .create();
|
||||||
|
// Utils.show_dialog_on_ime(d, v.getWindowToken());
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
139
srcs/juloo.keyboard2/ClipboardPinView.java
Normal file
139
srcs/juloo.keyboard2/ClipboardPinView.java
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
package juloo.keyboard2;
|
||||||
|
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.BaseAdapter;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
|
||||||
|
public final class ClipboardPinView extends NonScrollListView
|
||||||
|
{
|
||||||
|
/** Preference file name that store pinned clipboards. */
|
||||||
|
static final String PERSIST_FILE_NAME = "clipboards";
|
||||||
|
/** Preference name for pinned clipboards. */
|
||||||
|
static final String PERSIST_PREF = "pinned";
|
||||||
|
|
||||||
|
List<String> _entries;
|
||||||
|
ClipboardPinEntriesAdapter _adapter;
|
||||||
|
SharedPreferences _persist_store;
|
||||||
|
|
||||||
|
public ClipboardPinView(Context ctx, AttributeSet attrs)
|
||||||
|
{
|
||||||
|
super(ctx, attrs);
|
||||||
|
_entries = new ArrayList<String>();
|
||||||
|
_persist_store =
|
||||||
|
ctx.getSharedPreferences("pinned_clipboards", Context.MODE_PRIVATE);
|
||||||
|
load_from_prefs(_persist_store, _entries);
|
||||||
|
_adapter = this.new ClipboardPinEntriesAdapter();
|
||||||
|
setAdapter(_adapter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Pin a clipboard and persist the change. */
|
||||||
|
public void add_entry(String text)
|
||||||
|
{
|
||||||
|
_entries.add(text);
|
||||||
|
_adapter.notifyDataSetChanged();
|
||||||
|
persist();
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Remove the entry at index [pos] and persist the change. */
|
||||||
|
public void remove_entry(int pos)
|
||||||
|
{
|
||||||
|
if (pos < 0 || pos >= _entries.size())
|
||||||
|
return;
|
||||||
|
_entries.remove(pos);
|
||||||
|
_adapter.notifyDataSetChanged();
|
||||||
|
persist();
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Send the specified entry to the editor. */
|
||||||
|
public void paste_entry(int pos)
|
||||||
|
{
|
||||||
|
ClipboardHistoryService.paste(_entries.get(pos));
|
||||||
|
}
|
||||||
|
|
||||||
|
void persist() { save_to_prefs(_persist_store, _entries); }
|
||||||
|
|
||||||
|
static void load_from_prefs(SharedPreferences store, List<String> dst)
|
||||||
|
{
|
||||||
|
String arr_s = store.getString(PERSIST_PREF, null);
|
||||||
|
if (arr_s == null)
|
||||||
|
return;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
JSONArray arr = new JSONArray(arr_s);
|
||||||
|
for (int i = 0; i < arr.length(); i++)
|
||||||
|
dst.add(arr.getString(i));
|
||||||
|
}
|
||||||
|
catch (JSONException _e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void save_to_prefs(SharedPreferences store, List<String> entries)
|
||||||
|
{
|
||||||
|
JSONArray arr = new JSONArray();
|
||||||
|
for (int i = 0; i < entries.size(); i++)
|
||||||
|
arr.put(entries.get(i));
|
||||||
|
store.edit()
|
||||||
|
.putString(PERSIST_PREF, arr.toString())
|
||||||
|
.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
class ClipboardPinEntriesAdapter extends BaseAdapter
|
||||||
|
{
|
||||||
|
public ClipboardPinEntriesAdapter() {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCount() { return _entries.size(); }
|
||||||
|
@Override
|
||||||
|
public Object getItem(int pos) { return _entries.get(pos); }
|
||||||
|
@Override
|
||||||
|
public long getItemId(int pos) { return _entries.get(pos).hashCode(); }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View getView(final int pos, View v, ViewGroup _parent)
|
||||||
|
{
|
||||||
|
if (v == null)
|
||||||
|
v = View.inflate(getContext(), R.layout.clipboard_pin_entry, null);
|
||||||
|
((TextView)v.findViewById(R.id.clipboard_pin_text))
|
||||||
|
.setText(_entries.get(pos));
|
||||||
|
v.findViewById(R.id.clipboard_pin_paste).setOnClickListener(
|
||||||
|
new View.OnClickListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) { paste_entry(pos); }
|
||||||
|
});
|
||||||
|
v.findViewById(R.id.clipboard_pin_remove).setOnClickListener(
|
||||||
|
new View.OnClickListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onClick(View v)
|
||||||
|
{
|
||||||
|
AlertDialog d = new AlertDialog.Builder(getContext())
|
||||||
|
.setTitle(R.string.clipboard_remove_confirm)
|
||||||
|
.setPositiveButton(R.string.clipboard_remove_confirmed,
|
||||||
|
new DialogInterface.OnClickListener(){
|
||||||
|
public void onClick(DialogInterface _dialog, int _which)
|
||||||
|
{
|
||||||
|
remove_entry(pos);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.setNegativeButton(android.R.string.cancel, null)
|
||||||
|
.create();
|
||||||
|
Utils.show_dialog_on_ime(d, v.getWindowToken());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -67,6 +67,7 @@ public final class Config
|
|||||||
public boolean pin_entry_enabled;
|
public boolean pin_entry_enabled;
|
||||||
public boolean borderConfig;
|
public boolean borderConfig;
|
||||||
public int circle_sensitivity;
|
public int circle_sensitivity;
|
||||||
|
public boolean clipboard_history_enabled;
|
||||||
|
|
||||||
// Dynamically set
|
// Dynamically set
|
||||||
public boolean shouldOfferVoiceTyping;
|
public boolean shouldOfferVoiceTyping;
|
||||||
@ -185,6 +186,7 @@ public final class Config
|
|||||||
current_layout_portrait = _prefs.getInt("current_layout_portrait", 0);
|
current_layout_portrait = _prefs.getInt("current_layout_portrait", 0);
|
||||||
current_layout_landscape = _prefs.getInt("current_layout_landscape", 0);
|
current_layout_landscape = _prefs.getInt("current_layout_landscape", 0);
|
||||||
circle_sensitivity = Integer.valueOf(_prefs.getString("circle_sensitivity", "2"));
|
circle_sensitivity = Integer.valueOf(_prefs.getString("circle_sensitivity", "2"));
|
||||||
|
clipboard_history_enabled = _prefs.getBoolean("clipboard_history_enabled", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int get_current_layout()
|
public int get_current_layout()
|
||||||
|
@ -10,7 +10,9 @@ import android.view.inputmethod.ExtractedTextRequest;
|
|||||||
import android.view.inputmethod.InputConnection;
|
import android.view.inputmethod.InputConnection;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
public final class KeyEventHandler implements Config.IKeyEventHandler
|
public final class KeyEventHandler
|
||||||
|
implements Config.IKeyEventHandler,
|
||||||
|
ClipboardHistoryService.ClipboardPasteCallback
|
||||||
{
|
{
|
||||||
IReceiver _recv;
|
IReceiver _recv;
|
||||||
Autocapitalisation _autocap;
|
Autocapitalisation _autocap;
|
||||||
@ -105,6 +107,12 @@ public final class KeyEventHandler implements Config.IKeyEventHandler
|
|||||||
update_meta_state(mods);
|
update_meta_state(mods);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void paste_from_clipboard_pane(String content)
|
||||||
|
{
|
||||||
|
send_text(content);
|
||||||
|
}
|
||||||
|
|
||||||
/** Update [_mods] to be consistent with the [mods], sending key events if
|
/** Update [_mods] to be consistent with the [mods], sending key events if
|
||||||
needed. */
|
needed. */
|
||||||
void update_meta_state(Pointers.Modifiers mods)
|
void update_meta_state(Pointers.Modifiers mods)
|
||||||
|
@ -12,6 +12,8 @@ public final class KeyValue implements Comparable<KeyValue>
|
|||||||
SWITCH_NUMERIC,
|
SWITCH_NUMERIC,
|
||||||
SWITCH_EMOJI,
|
SWITCH_EMOJI,
|
||||||
SWITCH_BACK_EMOJI,
|
SWITCH_BACK_EMOJI,
|
||||||
|
SWITCH_CLIPBOARD,
|
||||||
|
SWITCH_BACK_CLIPBOARD,
|
||||||
CHANGE_METHOD_PICKER,
|
CHANGE_METHOD_PICKER,
|
||||||
CHANGE_METHOD_AUTO,
|
CHANGE_METHOD_AUTO,
|
||||||
ACTION,
|
ACTION,
|
||||||
@ -460,6 +462,8 @@ public final class KeyValue implements Comparable<KeyValue>
|
|||||||
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(0xE001, 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_clipboard": return eventKey(0xE017, Event.SWITCH_CLIPBOARD, 0);
|
||||||
|
case "switch_back_clipboard": return eventKey("ABC", Event.SWITCH_BACK_CLIPBOARD, 0);
|
||||||
case "switch_forward": return eventKey(0xE013, Event.SWITCH_FORWARD, FLAG_SMALLER_FONT);
|
case "switch_forward": return eventKey(0xE013, Event.SWITCH_FORWARD, FLAG_SMALLER_FONT);
|
||||||
case "switch_backward": return eventKey(0xE014, Event.SWITCH_BACKWARD, 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);
|
||||||
|
@ -36,6 +36,7 @@ public class Keyboard2 extends InputMethodService
|
|||||||
/** 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;
|
||||||
|
private ViewGroup _clipboard_pane = 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;
|
||||||
@ -113,6 +114,7 @@ public class Keyboard2 extends InputMethodService
|
|||||||
_keyboardView = (Keyboard2View)inflate_view(R.layout.keyboard);
|
_keyboardView = (Keyboard2View)inflate_view(R.layout.keyboard);
|
||||||
_keyboardView.reset();
|
_keyboardView.reset();
|
||||||
Logs.set_debug_logs(getResources().getBoolean(R.bool.debug_logs));
|
Logs.set_debug_logs(getResources().getBoolean(R.bool.debug_logs));
|
||||||
|
ClipboardHistoryService.on_startup(this, _keyeventhandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<InputMethodSubtype> getEnabledSubtypes(InputMethodManager imm)
|
private List<InputMethodSubtype> getEnabledSubtypes(InputMethodManager imm)
|
||||||
@ -223,6 +225,7 @@ public class Keyboard2 extends InputMethodService
|
|||||||
{
|
{
|
||||||
_keyboardView = (Keyboard2View)inflate_view(R.layout.keyboard);
|
_keyboardView = (Keyboard2View)inflate_view(R.layout.keyboard);
|
||||||
_emojiPane = null;
|
_emojiPane = null;
|
||||||
|
_clipboard_pane = null;
|
||||||
setInputView(_keyboardView);
|
setInputView(_keyboardView);
|
||||||
}
|
}
|
||||||
_keyboardView.reset();
|
_keyboardView.reset();
|
||||||
@ -384,7 +387,14 @@ public class Keyboard2 extends InputMethodService
|
|||||||
setInputView(_emojiPane);
|
setInputView(_emojiPane);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SWITCH_CLIPBOARD:
|
||||||
|
if (_clipboard_pane == null)
|
||||||
|
_clipboard_pane = (ViewGroup)inflate_view(R.layout.clipboard_pane);
|
||||||
|
setInputView(_clipboard_pane);
|
||||||
|
break;
|
||||||
|
|
||||||
case SWITCH_BACK_EMOJI:
|
case SWITCH_BACK_EMOJI:
|
||||||
|
case SWITCH_BACK_CLIPBOARD:
|
||||||
setInputView(_keyboardView);
|
setInputView(_keyboardView);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
38
srcs/juloo.keyboard2/NonScrollListView.java
Normal file
38
srcs/juloo.keyboard2/NonScrollListView.java
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
package juloo.keyboard2;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.View.MeasureSpec;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.ListView;
|
||||||
|
|
||||||
|
/** A non-scrollable list view that can be embedded in a bigger ScrollView.
|
||||||
|
Credits to Dedaniya HirenKumar in
|
||||||
|
https://stackoverflow.com/questions/18813296/non-scrollable-listview-inside-scrollview */
|
||||||
|
public class NonScrollListView extends ListView
|
||||||
|
{
|
||||||
|
public NonScrollListView(Context context)
|
||||||
|
{
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NonScrollListView(Context context, AttributeSet attrs)
|
||||||
|
{
|
||||||
|
super(context, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NonScrollListView(Context context, AttributeSet attrs, int defStyle)
|
||||||
|
{
|
||||||
|
super(context, attrs, defStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
|
||||||
|
{
|
||||||
|
int heightMeasureSpec_custom = MeasureSpec.makeMeasureSpec(
|
||||||
|
Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
|
||||||
|
super.onMeasure(widthMeasureSpec, heightMeasureSpec_custom);
|
||||||
|
ViewGroup.LayoutParams params = getLayoutParams();
|
||||||
|
params.height = getMeasuredHeight();
|
||||||
|
}
|
||||||
|
}
|
@ -24,6 +24,7 @@ public class ExtraKeysPreference extends PreferenceCategory
|
|||||||
"meta",
|
"meta",
|
||||||
"compose",
|
"compose",
|
||||||
"voice_typing",
|
"voice_typing",
|
||||||
|
"switch_clipboard",
|
||||||
"accent_aigu",
|
"accent_aigu",
|
||||||
"accent_grave",
|
"accent_grave",
|
||||||
"accent_double_aigu",
|
"accent_double_aigu",
|
||||||
@ -79,6 +80,7 @@ public class ExtraKeysPreference extends PreferenceCategory
|
|||||||
{
|
{
|
||||||
case "voice_typing":
|
case "voice_typing":
|
||||||
case "change_method":
|
case "change_method":
|
||||||
|
case "switch_clipboard":
|
||||||
case "compose":
|
case "compose":
|
||||||
case "tab":
|
case "tab":
|
||||||
case "esc":
|
case "esc":
|
||||||
@ -117,6 +119,7 @@ public class ExtraKeysPreference extends PreferenceCategory
|
|||||||
case "voice_typing": id = R.string.key_descr_voice_typing; break;
|
case "voice_typing": id = R.string.key_descr_voice_typing; break;
|
||||||
case "ª": id = R.string.key_descr_ª; break;
|
case "ª": id = R.string.key_descr_ª; break;
|
||||||
case "º": id = R.string.key_descr_º; break;
|
case "º": id = R.string.key_descr_º; break;
|
||||||
|
case "switch_clipboard": id = R.string.key_descr_clipboard; break;
|
||||||
}
|
}
|
||||||
if (id == 0)
|
if (id == 0)
|
||||||
return null;
|
return null;
|
||||||
|
2
srcs/special_font/17.svg
Normal file
2
srcs/special_font/17.svg
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
<!-- Material Design Icons -->
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>clipboard-text-multiple-outline</title><path d="M4 7V21H18V23H4C2.9 23 2 22.1 2 21V7H4M20 3C21.1 3 22 3.9 22 5V17C22 18.1 21.1 19 20 19H8C6.9 19 6 18.1 6 17V5C6 3.9 6.9 3 8 3H11.18C11.6 1.84 12.7 1 14 1C15.3 1 16.4 1.84 16.82 3H20M14 3C13.45 3 13 3.45 13 4C13 4.55 13.45 5 14 5C14.55 5 15 4.55 15 4C15 3.45 14.55 3 14 3M10 7V5H8V17H20V5H18V7M15 15H10V13H15M18 11H10V9H18V11Z" /></svg>
|
After Width: | Height: | Size: 483 B |
@ -1,2 +1,2 @@
|
|||||||
<!-- Material Design Icons -->
|
<!-- Material Design Icons -->
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>clipboard-multiple-outline</title><path d="M4 7V21H18V23H4C2.9 23 2 22.1 2 21V7H4M20 3C21.1 3 22 3.9 22 5V17C22 18.1 21.1 19 20 19H8C6.9 19 6 18.1 6 17V5C6 3.9 6.9 3 8 3H11.18C11.6 1.84 12.7 1 14 1C15.3 1 16.4 1.84 16.82 3H20M14 3C13.45 3 13 3.45 13 4C13 4.55 13.45 5 14 5C14.55 5 15 4.55 15 4C15 3.45 14.55 3 14 3M10 7V5H8V17H20V5H18V7H10Z" /></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>content-paste (modified)</title><path d="M19,20H5V4H7V7H17V4H19M12,2A1,1 0 0,1 13,3A1,1 0 0,1 12,4A1,1 0 0,1 11,3A1,1 0 0,1 12,2M19,2H14.82C14.4,0.84 13.3,0 12,0C10.7,0 9.6,0.84 9.18,2H5A2,2 0 0,0 3,4V20A2,2 0 0,0 5,22H19A2,2 0 0,0 21,20V4A2,2 0 0,0 19,2M8 12H16V14H8V12Z" /></svg>
|
||||||
|
Before Width: | Height: | Size: 449 B After Width: | Height: | Size: 380 B |
Loading…
Reference in New Issue
Block a user