abouttreesummaryrefslogcommitdiff
diff options
context:
space:
mode:
-rw-r--r--assets/special_font.ttfbin10328 -> 10504 bytes
-rw-r--r--check_layout.output5
-rw-r--r--check_layout.py3
-rw-r--r--res/drawable/ic_clipboard_paste.xml1
-rw-r--r--res/drawable/ic_clipboard_save.xml1
-rw-r--r--res/drawable/ic_delete.xml1
-rw-r--r--res/layout/clipboard_history_entry.xml8
-rw-r--r--res/layout/clipboard_pane.xml12
-rw-r--r--res/layout/clipboard_pin_entry.xml8
-rw-r--r--res/values-cs/strings.xml5
-rw-r--r--res/values-de/strings.xml5
-rw-r--r--res/values-es/strings.xml5
-rw-r--r--res/values-fa/strings.xml5
-rw-r--r--res/values-fr/strings.xml5
-rw-r--r--res/values-it/strings.xml5
-rw-r--r--res/values-ko/strings.xml5
-rw-r--r--res/values-lv/strings.xml5
-rw-r--r--res/values-pl/strings.xml5
-rw-r--r--res/values-pt/strings.xml5
-rw-r--r--res/values-ro/strings.xml5
-rw-r--r--res/values-ru/strings.xml5
-rw-r--r--res/values-tr/strings.xml5
-rw-r--r--res/values-uk/strings.xml5
-rw-r--r--res/values-vi/strings.xml5
-rw-r--r--res/values-zh-rCN/strings.xml5
-rw-r--r--res/values/strings.xml5
-rw-r--r--res/values/styles.xml34
-rw-r--r--res/values/themes.xml10
-rw-r--r--res/values/values.xml1
-rw-r--r--res/xml/bottom_row.xml2
-rw-r--r--res/xml/clipboard_bottom_row.xml10
-rw-r--r--srcs/juloo.keyboard2/ClipboardHistoryCheckBox.java22
-rw-r--r--srcs/juloo.keyboard2/ClipboardHistoryService.java180
-rw-r--r--srcs/juloo.keyboard2/ClipboardHistoryView.java125
-rw-r--r--srcs/juloo.keyboard2/ClipboardPinView.java139
-rw-r--r--srcs/juloo.keyboard2/Config.java2
-rw-r--r--srcs/juloo.keyboard2/KeyEventHandler.java10
-rw-r--r--srcs/juloo.keyboard2/KeyValue.java4
-rw-r--r--srcs/juloo.keyboard2/Keyboard2.java10
-rw-r--r--srcs/juloo.keyboard2/NonScrollListView.java38
-rw-r--r--srcs/juloo.keyboard2/prefs/ExtraKeysPreference.java3
-rw-r--r--srcs/special_font/17.svg2
-rw-r--r--srcs/special_font/35.svg2
43 files changed, 711 insertions, 7 deletions
diff --git a/assets/special_font.ttf b/assets/special_font.ttf
index 5b9aa57..eb07561 100644
--- a/assets/special_font.ttf
+++ b/assets/special_font.ttf
Binary files differ
diff --git a/check_layout.output b/check_layout.output
index 683db03..d6aa54a 100644
--- a/check_layout.output
+++ b/check_layout.output
@@ -63,7 +63,7 @@ Layout includes some ASCII punctuation but not all, missing: (, ), <, >, [, ], {
0 warnings
# latn_bone
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
# latn_colemak
Some keys contain whitespaces, unexpected: ́
@@ -71,7 +71,8 @@ Some keys contain whitespaces, unexpected: ́
# latn_dvorak
0 warnings
# latn_neo2
-0 warnings
+Layout redefines the bottom row but some important keys are missing, missing: loc switch_clipboard
+1 warnings
# latn_qwerty_br
0 warnings
# latn_qwerty_cz
diff --git a/check_layout.py b/check_layout.py
index dee9b9b..47a17b6 100644
--- a/check_layout.py
+++ b/check_layout.py
@@ -6,7 +6,8 @@ warning_count = 0
KNOWN_NOT_LAYOUT = set([
"number_row", "numpad", "pin",
"bottom_row", "settings", "method",
- "greekmath", "numeric", "emoji_bottom_row" ])
+ "greekmath", "numeric", "emoji_bottom_row",
+ "clipboard_bottom_row" ])
def warn(msg):
global warning_count
diff --git a/res/drawable/ic_clipboard_paste.xml b/res/drawable/ic_clipboard_paste.xml
new file mode 100644
index 0000000..1507f27
--- /dev/null
+++ b/res/drawable/ic_clipboard_paste.xml
@@ -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> \ No newline at end of file
diff --git a/res/drawable/ic_clipboard_save.xml b/res/drawable/ic_clipboard_save.xml
new file mode 100644
index 0000000..53abcf2
--- /dev/null
+++ b/res/drawable/ic_clipboard_save.xml
@@ -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> \ No newline at end of file
diff --git a/res/drawable/ic_delete.xml b/res/drawable/ic_delete.xml
new file mode 100644
index 0000000..5b69d0b
--- /dev/null
+++ b/res/drawable/ic_delete.xml
@@ -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> \ No newline at end of file
diff --git a/res/layout/clipboard_history_entry.xml b/res/layout/clipboard_history_entry.xml
new file mode 100644
index 0000000..9d34a9e
--- /dev/null
+++ b/res/layout/clipboard_history_entry.xml
@@ -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>
diff --git a/res/layout/clipboard_pane.xml b/res/layout/clipboard_pane.xml
new file mode 100644
index 0000000..84dc6c9
--- /dev/null
+++ b/res/layout/clipboard_pane.xml
@@ -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>
diff --git a/res/layout/clipboard_pin_entry.xml b/res/layout/clipboard_pin_entry.xml
new file mode 100644
index 0000000..9cd8b2d
--- /dev/null
+++ b/res/layout/clipboard_pin_entry.xml
@@ -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>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index 0e645a7..4e7c785 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -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_home">Home</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>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 8a63e4c..890d8af 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -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_home">Pos1</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>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 9f3322d..dc8578f 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -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_home">Inicio</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>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index f76e689..46e9310 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -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_home">Home</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>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index ba7d21a..93d7ff0 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -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_home">Début</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>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index f4da65d..0d58124 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -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_home">Home</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>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index 20844c2..c2036f2 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -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_home">Home</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>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index 7ae25b3..db6eded 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -118,4 +118,9 @@ Tagad lieliski piemērota izmantošanai ikdienā.
<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="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>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index 4531c8f..dff1b05 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -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_home">Home</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>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 1d98260..651eb0b 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -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_home">Home</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>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index b68f15e..13086c5 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -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_home">Home</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>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index 47e925c..982dcb3 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -116,4 +116,9 @@
<string name="key_descr_page_down">Страница вниз</string>
<string name="key_descr_home">Home</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>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index 4a77bbc..ce8c205 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -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_home">BAŞ(Sol 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>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index 268dc8b..0f7e81f 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -116,4 +116,9 @@
<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="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>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index 8ea468d..a97068a 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -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_home">Home</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>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index 89b6c28..8809ff2 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -116,4 +116,9 @@
<string name="key_descr_page_down">下一页</string>
<string name="key_descr_home">Home</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>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 224aca5..75df689 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -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_home">Home</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>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 07ed490..8705d98 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
+ <!-- Emoji pane -->
<style name="emojiTypeButton">
<item name="android:padding">1px</item>
<item name="android:gravity">center</item>
@@ -15,6 +16,39 @@
<item name="android:textSize">@dimen/emoji_text_size</item>
<item name="android:textColor">?attr/emoji_color</item>
</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">
<item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">wrap_content</item>
diff --git a/res/values/themes.xml b/res/values/themes.xml
index a1892d3..aa30080 100644
--- a/res/values/themes.xml
+++ b/res/values/themes.xml
@@ -23,11 +23,14 @@
<attr name="keyBorderColorTop" format="color"/>
<attr name="keyBorderColorRight" format="color"/>
<attr name="keyBorderColorBottom" format="color"/>
- <!-- Emoji panel -->
+ <!-- Emoji pane -->
<attr name="emoji_button_bg" 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_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 -->
<attr name="navigationBarColor" format="color"/>
<attr name="windowLightNavigationBar" format="boolean"/>
@@ -43,6 +46,8 @@
<item name="greyedDimming">0.5</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="clipboard_divider_color" type="color">?attr/colorKey</item>
+ <item name="clipboard_divider_height">1px</item>
</style>
<style name="Dark" parent="BaseTheme">
<item name="android:isLightTheme">false</item>
@@ -116,6 +121,7 @@
<item name="colorSubLabel">#333333</item>
<item name="emoji_button_bg">#ffffff</item>
<item name="emoji_color">#000000</item>
+ <item name="clipboard_divider_color" type="color">#eeeeee</item>
</style>
<style name="ePaper" parent="BaseTheme">
<item name="android:isLightTheme">true</item>
@@ -134,6 +140,8 @@
<item name="colorSubLabel">#333333</item>
<item name="emoji_button_bg">#ffffff</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 name="Desert" parent="@style/BaseTheme">
<item name="android:isLightTheme">true</item>
diff --git a/res/values/values.xml b/res/values/values.xml
index cc048e9..b13296b 100644
--- a/res/values/values.xml
+++ b/res/values/values.xml
@@ -4,6 +4,7 @@
<dimen name="key_padding">2dp</dimen>
<dimen name="emoji_grid_height">250dp</dimen>
<dimen name="emoji_text_size">28dp</dimen>
+ <dimen name="clipboard_view_height">300dp</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 -->
</resources>
diff --git a/res/xml/bottom_row.xml b/res/xml/bottom_row.xml
index 2f4de2b..600795e 100644
--- a/res/xml/bottom_row.xml
+++ b/res/xml/bottom_row.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<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="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"/>
diff --git a/res/xml/clipboard_bottom_row.xml b/res/xml/clipboard_bottom_row.xml
new file mode 100644
index 0000000..2dfc596
--- /dev/null
+++ b/res/xml/clipboard_bottom_row.xml
@@ -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>
diff --git a/srcs/juloo.keyboard2/ClipboardHistoryCheckBox.java b/srcs/juloo.keyboard2/ClipboardHistoryCheckBox.java
new file mode 100644
index 0000000..9842058
--- /dev/null
+++ b/srcs/juloo.keyboard2/ClipboardHistoryCheckBox.java
@@ -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);
+ }
+}
diff --git a/srcs/juloo.keyboard2/ClipboardHistoryService.java b/srcs/juloo.keyboard2/ClipboardHistoryService.java
new file mode 100644
index 0000000..e3f01ba
--- /dev/null
+++ b/srcs/juloo.keyboard2/ClipboardHistoryService.java
@@ -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);
+ }
+}
diff --git a/srcs/juloo.keyboard2/ClipboardHistoryView.java b/srcs/juloo.keyboard2/ClipboardHistoryView.java
new file mode 100644
index 0000000..b4eb6fe
--- /dev/null
+++ b/srcs/juloo.keyboard2/ClipboardHistoryView.java
@@ -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;
+ }
+ }
+}
diff --git a/srcs/juloo.keyboard2/ClipboardPinView.java b/srcs/juloo.keyboard2/ClipboardPinView.java
new file mode 100644
index 0000000..26833d6
--- /dev/null
+++ b/srcs/juloo.keyboard2/ClipboardPinView.java
@@ -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;
+ }
+ }
+}
diff --git a/srcs/juloo.keyboard2/Config.java b/srcs/juloo.keyboard2/Config.java
index 7570728..061183c 100644
--- a/srcs/juloo.keyboard2/Config.java
+++ b/srcs/juloo.keyboard2/Config.java
@@ -67,6 +67,7 @@ public final class Config
public boolean pin_entry_enabled;
public boolean borderConfig;
public int circle_sensitivity;
+ public boolean clipboard_history_enabled;
// Dynamically set
public boolean shouldOfferVoiceTyping;
@@ -185,6 +186,7 @@ public final class Config
current_layout_portrait = _prefs.getInt("current_layout_portrait", 0);
current_layout_landscape = _prefs.getInt("current_layout_landscape", 0);
circle_sensitivity = Integer.valueOf(_prefs.getString("circle_sensitivity", "2"));
+ clipboard_history_enabled = _prefs.getBoolean("clipboard_history_enabled", false);
}
public int get_current_layout()
diff --git a/srcs/juloo.keyboard2/KeyEventHandler.java b/srcs/juloo.keyboard2/KeyEventHandler.java
index b6225f1..087ac5b 100644
--- a/srcs/juloo.keyboard2/KeyEventHandler.java
+++ b/srcs/juloo.keyboard2/KeyEventHandler.java
@@ -10,7 +10,9 @@ import android.view.inputmethod.ExtractedTextRequest;
import android.view.inputmethod.InputConnection;
import java.util.Iterator;
-public final class KeyEventHandler implements Config.IKeyEventHandler
+public final class KeyEventHandler
+ implements Config.IKeyEventHandler,
+ ClipboardHistoryService.ClipboardPasteCallback
{
IReceiver _recv;
Autocapitalisation _autocap;
@@ -105,6 +107,12 @@ public final class KeyEventHandler implements Config.IKeyEventHandler
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
needed. */
void update_meta_state(Pointers.Modifiers mods)
diff --git a/srcs/juloo.keyboard2/KeyValue.java b/srcs/juloo.keyboard2/KeyValue.java
index 1635bab..31a92f2 100644
--- a/srcs/juloo.keyboard2/KeyValue.java
+++ b/srcs/juloo.keyboard2/KeyValue.java
@@ -12,6 +12,8 @@ public final class KeyValue implements Comparable<KeyValue>
SWITCH_NUMERIC,
SWITCH_EMOJI,
SWITCH_BACK_EMOJI,
+ SWITCH_CLIPBOARD,
+ SWITCH_BACK_CLIPBOARD,
CHANGE_METHOD_PICKER,
CHANGE_METHOD_AUTO,
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_emoji": return eventKey(0xE001, Event.SWITCH_EMOJI, FLAG_SMALLER_FONT);
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_backward": return eventKey(0xE014, Event.SWITCH_BACKWARD, FLAG_SMALLER_FONT);
case "switch_greekmath": return eventKey("πλ∇¬", Event.SWITCH_GREEKMATH, FLAG_SMALLER_FONT);
diff --git a/srcs/juloo.keyboard2/Keyboard2.java b/srcs/juloo.keyboard2/Keyboard2.java
index c332375..0c82aaf 100644
--- a/srcs/juloo.keyboard2/Keyboard2.java
+++ b/srcs/juloo.keyboard2/Keyboard2.java
@@ -36,6 +36,7 @@ public class Keyboard2 extends InputMethodService
/** Layout associated with the currently selected locale. Not 'null'. */
private KeyboardData _localeTextLayout;
private ViewGroup _emojiPane = null;
+ private ViewGroup _clipboard_pane = null;
public int actionId; // Action performed by the Action key.
private Config _config;
@@ -113,6 +114,7 @@ public class Keyboard2 extends InputMethodService
_keyboardView = (Keyboard2View)inflate_view(R.layout.keyboard);
_keyboardView.reset();
Logs.set_debug_logs(getResources().getBoolean(R.bool.debug_logs));
+ ClipboardHistoryService.on_startup(this, _keyeventhandler);
}
private List<InputMethodSubtype> getEnabledSubtypes(InputMethodManager imm)
@@ -223,6 +225,7 @@ public class Keyboard2 extends InputMethodService
{
_keyboardView = (Keyboard2View)inflate_view(R.layout.keyboard);
_emojiPane = null;
+ _clipboard_pane = null;
setInputView(_keyboardView);
}
_keyboardView.reset();
@@ -384,7 +387,14 @@ public class Keyboard2 extends InputMethodService
setInputView(_emojiPane);
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_CLIPBOARD:
setInputView(_keyboardView);
break;
diff --git a/srcs/juloo.keyboard2/NonScrollListView.java b/srcs/juloo.keyboard2/NonScrollListView.java
new file mode 100644
index 0000000..32ef744
--- /dev/null
+++ b/srcs/juloo.keyboard2/NonScrollListView.java
@@ -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();
+ }
+}
diff --git a/srcs/juloo.keyboard2/prefs/ExtraKeysPreference.java b/srcs/juloo.keyboard2/prefs/ExtraKeysPreference.java
index adf66ec..22c6bd9 100644
--- a/srcs/juloo.keyboard2/prefs/ExtraKeysPreference.java
+++ b/srcs/juloo.keyboard2/prefs/ExtraKeysPreference.java
@@ -24,6 +24,7 @@ public class ExtraKeysPreference extends PreferenceCategory
"meta",
"compose",
"voice_typing",
+ "switch_clipboard",
"accent_aigu",
"accent_grave",
"accent_double_aigu",
@@ -79,6 +80,7 @@ public class ExtraKeysPreference extends PreferenceCategory
{
case "voice_typing":
case "change_method":
+ case "switch_clipboard":
case "compose":
case "tab":
case "esc":
@@ -117,6 +119,7 @@ public class ExtraKeysPreference extends PreferenceCategory
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 "switch_clipboard": id = R.string.key_descr_clipboard; break;
}
if (id == 0)
return null;
diff --git a/srcs/special_font/17.svg b/srcs/special_font/17.svg
new file mode 100644
index 0000000..ebf77be
--- /dev/null
+++ b/srcs/special_font/17.svg
@@ -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>
diff --git a/srcs/special_font/35.svg b/srcs/special_font/35.svg
index e23d49b..f196412 100644
--- a/srcs/special_font/35.svg
+++ b/srcs/special_font/35.svg
@@ -1,2 +1,2 @@
<!-- 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>