diff options
43 files changed, 711 insertions, 7 deletions
diff --git a/assets/special_font.ttf b/assets/special_font.ttf Binary files differindex 5b9aa57..eb07561 100644 --- a/assets/special_font.ttf +++ b/assets/special_font.ttf 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> |
