mirror of
https://github.com/moparisthebest/k-9
synced 2025-02-25 15:11:52 -05:00
Merge remote branch 'k-9/master'
This commit is contained in:
commit
503b88e2fd
23
Android.mk
23
Android.mk
@ -1,10 +1,33 @@
|
|||||||
LOCAL_PATH:= $(call my-dir)
|
LOCAL_PATH:= $(call my-dir)
|
||||||
include $(CLEAR_VARS)
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
LOCAL_STATIC_JAVA_LIBRARIES += libcore
|
||||||
|
LOCAL_STATIC_JAVA_LIBRARIES += libdom
|
||||||
|
LOCAL_STATIC_JAVA_LIBRARIES += libio
|
||||||
|
LOCAL_STATIC_JAVA_LIBRARIES += libjutf
|
||||||
|
LOCAL_STATIC_JAVA_LIBRARIES += libjzlib
|
||||||
|
|
||||||
LOCAL_MODULE_TAGS := eng
|
LOCAL_MODULE_TAGS := eng
|
||||||
|
|
||||||
LOCAL_SRC_FILES := $(call all-subdir-java-files)
|
LOCAL_SRC_FILES := $(call all-subdir-java-files)
|
||||||
|
|
||||||
|
LOCAL_SDK_VERSION := current
|
||||||
|
|
||||||
LOCAL_PACKAGE_NAME := Email
|
LOCAL_PACKAGE_NAME := Email
|
||||||
|
|
||||||
include $(BUILD_PACKAGE)
|
include $(BUILD_PACKAGE)
|
||||||
|
##################################################
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES += libcore:libs/apache-mime4j-core-0.7-SNAPSHOT.jar
|
||||||
|
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES += libdom:libs/apache-mime4j-dom-0.7-SNAPSHOT.jar
|
||||||
|
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES += libio:libs/commons-io-2.0.1.jar
|
||||||
|
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES += libjutf:libs/jutf7-1.0.1-SNAPSHOT.jar
|
||||||
|
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES += libjzlib:libs/jzlib-1.0.7.jar
|
||||||
|
|
||||||
|
include $(BUILD_MULTI_PREBUILT)
|
||||||
|
|
||||||
|
|
||||||
|
# Use the folloing include to make our test apk.
|
||||||
|
include $(call all-makefiles-under,$(LOCAL_PATH))
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest
|
<manifest
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:versionCode="13010"
|
android:versionCode="14001"
|
||||||
android:versionName="3.709" package="com.fsck.k9"
|
android:versionName="3.900" package="com.fsck.k9"
|
||||||
>
|
>
|
||||||
<uses-sdk
|
<uses-sdk
|
||||||
android:minSdkVersion="3"
|
android:minSdkVersion="3"
|
||||||
@ -18,10 +18,6 @@
|
|||||||
<uses-permission android:name="android.permission.READ_CONTACTS"/>
|
<uses-permission android:name="android.permission.READ_CONTACTS"/>
|
||||||
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS"/>
|
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS"/>
|
||||||
|
|
||||||
<!-- Needed to get the owner name which is used when the first mail account is created -->
|
|
||||||
<uses-permission android:name="android.permission.READ_OWNER_DATA"/>
|
|
||||||
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
|
|
||||||
|
|
||||||
<!-- Needed to mark a contact as contacted -->
|
<!-- Needed to mark a contact as contacted -->
|
||||||
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>
|
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<body bgcolor="white">
|
<body bgcolor="white">
|
||||||
<table width="100%" height="100%">
|
<table width="100%" height="100%">
|
||||||
<tr>
|
<tr>
|
||||||
<td align="center" valign="center">
|
<td align="center" valign="middle">
|
||||||
<font color="gray">Downloading...</font>
|
<font color="gray">Downloading...</font>
|
||||||
<br/>
|
<br/>
|
||||||
<br/>
|
<br/>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<body bgcolor="white">
|
<body bgcolor="white">
|
||||||
<table width="100%" height="100%">
|
<table width="100%" height="100%">
|
||||||
<tr>
|
<tr>
|
||||||
<td align="center" valign="center">
|
<td align="center" valign="middle">
|
||||||
<font color="gray">No text</font>
|
<font color="gray">No text</font>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<body bgcolor="white">
|
<body bgcolor="white">
|
||||||
<table width="100%" height="100%">
|
<table width="100%" height="100%">
|
||||||
<tr>
|
<tr>
|
||||||
<td align="center" valign="center">
|
<td align="center" valign="middle">
|
||||||
<font color="gray">Loading...</font>
|
<font color="gray">Loading...</font>
|
||||||
<br/>
|
<br/>
|
||||||
<br/>
|
<br/>
|
||||||
|
29
k9mail.iml
29
k9mail.iml
@ -3,7 +3,6 @@
|
|||||||
<component name="FacetManager">
|
<component name="FacetManager">
|
||||||
<facet type="android" name="Android">
|
<facet type="android" name="Android">
|
||||||
<configuration>
|
<configuration>
|
||||||
<option name="PLATFORM_NAME" value="Android 2.3.1 Platform" />
|
|
||||||
<option name="GEN_FOLDER_RELATIVE_PATH_APT" value="/gen" />
|
<option name="GEN_FOLDER_RELATIVE_PATH_APT" value="/gen" />
|
||||||
<option name="GEN_FOLDER_RELATIVE_PATH_AIDL" value="/gen" />
|
<option name="GEN_FOLDER_RELATIVE_PATH_AIDL" value="/gen" />
|
||||||
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/AndroidManifest.xml" />
|
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/AndroidManifest.xml" />
|
||||||
@ -17,7 +16,6 @@
|
|||||||
<option name="USE_CUSTOM_COMPILER_MANIFEST" value="false" />
|
<option name="USE_CUSTOM_COMPILER_MANIFEST" value="false" />
|
||||||
<option name="CUSTOM_COMPILER_MANIFEST" value="" />
|
<option name="CUSTOM_COMPILER_MANIFEST" value="" />
|
||||||
<option name="APK_PATH" value="" />
|
<option name="APK_PATH" value="" />
|
||||||
<option name="ADD_ANDROID_LIBRARY" value="true" />
|
|
||||||
<option name="LIBRARY_PROJECT" value="false" />
|
<option name="LIBRARY_PROJECT" value="false" />
|
||||||
<option name="RUN_PROCESS_RESOURCES_MAVEN_TASK" value="true" />
|
<option name="RUN_PROCESS_RESOURCES_MAVEN_TASK" value="true" />
|
||||||
<option name="GENERATE_UNSIGNED_APK" value="false" />
|
<option name="GENERATE_UNSIGNED_APK" value="false" />
|
||||||
@ -79,33 +77,6 @@
|
|||||||
<SOURCES />
|
<SOURCES />
|
||||||
</library>
|
</library>
|
||||||
</orderEntry>
|
</orderEntry>
|
||||||
<orderEntry type="module-library" scope="PROVIDED">
|
|
||||||
<library>
|
|
||||||
<CLASSES>
|
|
||||||
<root url="jar://$MODULE_DIR$/compile-only-libs/commons-logging-1.1.1.jar!/" />
|
|
||||||
</CLASSES>
|
|
||||||
<JAVADOC />
|
|
||||||
<SOURCES />
|
|
||||||
</library>
|
|
||||||
</orderEntry>
|
|
||||||
<orderEntry type="module-library" scope="PROVIDED">
|
|
||||||
<library>
|
|
||||||
<CLASSES>
|
|
||||||
<root url="jar://$MODULE_DIR$/compile-only-libs/bcprov-jdk15-143.jar!/" />
|
|
||||||
</CLASSES>
|
|
||||||
<JAVADOC />
|
|
||||||
<SOURCES />
|
|
||||||
</library>
|
|
||||||
</orderEntry>
|
|
||||||
<orderEntry type="module-library" scope="PROVIDED">
|
|
||||||
<library>
|
|
||||||
<CLASSES>
|
|
||||||
<root url="jar://$MODULE_DIR$/compile-only-libs/commons-codec-1.3.jar!/" />
|
|
||||||
</CLASSES>
|
|
||||||
<JAVADOC />
|
|
||||||
<SOURCES />
|
|
||||||
</library>
|
|
||||||
</orderEntry>
|
|
||||||
<orderEntry type="module-library" scope="TEST">
|
<orderEntry type="module-library" scope="TEST">
|
||||||
<library>
|
<library>
|
||||||
<CLASSES>
|
<CLASSES>
|
||||||
|
@ -152,7 +152,6 @@
|
|||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/userId"
|
android:id="@+id/userId"
|
||||||
android:text=""
|
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||||
android:textColor="@android:color/primary_text_light"
|
android:textColor="@android:color/primary_text_light"
|
||||||
@ -161,7 +160,6 @@
|
|||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/userIdRest"
|
android:id="@+id/userIdRest"
|
||||||
android:text=""
|
|
||||||
android:textSize="10sp"
|
android:textSize="10sp"
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
android:textColor="@android:color/primary_text_light"
|
android:textColor="@android:color/primary_text_light"
|
||||||
@ -239,6 +237,17 @@
|
|||||||
android:textColor="@android:color/primary_text_light"
|
android:textColor="@android:color/primary_text_light"
|
||||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/quoted_text_show"
|
||||||
|
android:text="@string/message_compose_show_quoted_text_action"
|
||||||
|
android:textSize="16dip"
|
||||||
|
android:padding="0dip"
|
||||||
|
android:layout_gravity="right"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_alignParentTop="true"
|
||||||
|
android:layout_alignParentRight="true" />
|
||||||
|
|
||||||
<!-- Quoted text bar -->
|
<!-- Quoted text bar -->
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:id="@+id/quoted_text_bar"
|
android:id="@+id/quoted_text_bar"
|
||||||
|
@ -83,7 +83,7 @@
|
|||||||
android:layout_marginRight="0dip"
|
android:layout_marginRight="0dip"
|
||||||
android:singleLine="false"
|
android:singleLine="false"
|
||||||
android:bufferType="spannable"
|
android:bufferType="spannable"
|
||||||
android:textColor="?android:attr/textColorTertiary"
|
android:textColor="?android:attr/textColorPrimary"
|
||||||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
@ -344,7 +344,7 @@ Benvingut a la configuració del K-9. El K-9 és un client de codi obert per An
|
|||||||
<string name="global_settings_confirm_action_archive">Arxiva</string>
|
<string name="global_settings_confirm_action_archive">Arxiva</string>
|
||||||
<string name="global_settings_confirm_action_delete">Esborra (només la vista del missatge)</string>
|
<string name="global_settings_confirm_action_delete">Esborra (només la vista del missatge)</string>
|
||||||
<string name="global_settings_confirm_action_spam">Brossa</string>
|
<string name="global_settings_confirm_action_spam">Brossa</string>
|
||||||
<!-- NEW: <string name="global_settings_confirm_action_mark_all_as_read">Mark all as read</string>-->
|
<string name="global_settings_confirm_action_mark_all_as_read">Maca\'ls tots com a llegits</string>
|
||||||
<string name="global_settings_confirm_action_send">Envia</string>
|
<string name="global_settings_confirm_action_send">Envia</string>
|
||||||
|
|
||||||
<string name="global_settings_privacy_mode_title">Bloca notificacions</string>
|
<string name="global_settings_privacy_mode_title">Bloca notificacions</string>
|
||||||
@ -1001,7 +1001,7 @@ Benvingut a la configuració del K-9. El K-9 és un client de codi obert per An
|
|||||||
|
|
||||||
<!-- APG related -->
|
<!-- APG related -->
|
||||||
<string name="error_activity_not_found">No s’ha trobat cap aplicació idònia per a aquesta acció.</string>
|
<string name="error_activity_not_found">No s’ha trobat cap aplicació idònia per a aquesta acció.</string>
|
||||||
<string name="error_apg_version_not_supported">Versió APG instal lada no suportada.</string>
|
<string name="error_apg_version_not_supported">Versió APG instal·lada no suportada.</string>
|
||||||
<string name="btn_crypto_sign">Inicia</string>
|
<string name="btn_crypto_sign">Inicia</string>
|
||||||
<string name="btn_encrypt">Encripta</string>
|
<string name="btn_encrypt">Encripta</string>
|
||||||
<string name="btn_decrypt">Desencripta</string>
|
<string name="btn_decrypt">Desencripta</string>
|
||||||
@ -1025,10 +1025,10 @@ Benvingut a la configuració del K-9. El K-9 és un client de codi obert per An
|
|||||||
<string name="dialog_confirm_delete_confirm_button">Esborra</string>
|
<string name="dialog_confirm_delete_confirm_button">Esborra</string>
|
||||||
<string name="dialog_confirm_delete_cancel_button">No esborris</string>
|
<string name="dialog_confirm_delete_cancel_button">No esborris</string>
|
||||||
|
|
||||||
<!-- NEW: <string name="dialog_confirm_spam_title">Confirm move to spam folder</string>-->
|
<string name="dialog_confirm_spam_title">Confirma moure\'l carpeta brossa</string>
|
||||||
<!-- NEW: <string name="dialog_confirm_spam_message">Do you really want to move this message to the spam folder?</string>-->
|
<string name="dialog_confirm_spam_message">Realment vols moure aquest missatge a la carpeta brossa?</string>
|
||||||
<!-- NEW: <string name="dialog_confirm_spam_confirm_button">Yes</string>-->
|
<string name="dialog_confirm_spam_confirm_button">Sí</string>
|
||||||
<!-- NEW: <string name="dialog_confirm_spam_cancel_button">No</string>-->
|
<string name="dialog_confirm_spam_cancel_button">No</string>
|
||||||
|
|
||||||
<string name="dialog_attachment_progress_title">S\'està descarregant adjunt</string>
|
<string name="dialog_attachment_progress_title">S\'està descarregant adjunt</string>
|
||||||
|
|
||||||
@ -1038,6 +1038,9 @@ Benvingut a la configuració del K-9. El K-9 és un client de codi obert per An
|
|||||||
<string name="messagelist_sent_cc_me_sigil">›</string>
|
<string name="messagelist_sent_cc_me_sigil">›</string>
|
||||||
<string name="error_unable_to_connect">No es pot connectar.</string>
|
<string name="error_unable_to_connect">No es pot connectar.</string>
|
||||||
|
|
||||||
<!-- NEW: <string name="account_unavailable">Account \"<xliff:g id="account">%s</xliff:g>\" is unavailable; check storage</string>-->
|
<string name="account_unavailable">Compte \"<xliff:g id="account">%s</xliff:g>\" no és disponible; comprova emmagatzematge</string>
|
||||||
|
|
||||||
|
<string name="settings_attachment_default_path">Desa adjunts a...</string>
|
||||||
|
<string name="attachment_save_title">Desa adjunt</string>
|
||||||
|
<string name="attachment_save_desc">No s\'ha trobat l\'arxiu al navegador. On vols desar l\'adjunt?</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -1047,4 +1047,7 @@ Vítejte v nastavení pošty K-9 Mail. K-9 je open source poštovní klient pro
|
|||||||
|
|
||||||
<!-- NEW: <string name="account_unavailable">Account \"<xliff:g id="account">%s</xliff:g>\" is unavailable; check storage</string>-->
|
<!-- NEW: <string name="account_unavailable">Account \"<xliff:g id="account">%s</xliff:g>\" is unavailable; check storage</string>-->
|
||||||
|
|
||||||
|
<!-- NEW: <string name="settings_attachment_default_path">Save attachments to...</string>-->
|
||||||
|
<!-- NEW: <string name="attachment_save_title">Save attachment</string>-->
|
||||||
|
<!-- NEW: <string name="attachment_save_desc">No file browser found. Where would you like to save this attachment?</string>-->
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -56,7 +56,7 @@
|
|||||||
<string name="reply_action">Antworten</string>
|
<string name="reply_action">Antworten</string>
|
||||||
<string name="reply_all_action">Allen antworten</string>
|
<string name="reply_all_action">Allen antworten</string>
|
||||||
<string name="delete_action">Löschen</string>
|
<string name="delete_action">Löschen</string>
|
||||||
<string name="archive_action">Sichern</string>
|
<string name="archive_action">Archivieren</string>
|
||||||
<string name="spam_action">Spam</string>
|
<string name="spam_action">Spam</string>
|
||||||
<string name="delete_all_action">Ordner leeren</string>
|
<string name="delete_all_action">Ordner leeren</string>
|
||||||
<string name="forward_action">Weiterleiten</string>
|
<string name="forward_action">Weiterleiten</string>
|
||||||
@ -341,7 +341,7 @@ Willkommen zum \"K-9 Mail\"-Setup. K-9 ist eine quelloffene E-Mail-Anwendung fü
|
|||||||
<string name="global_settings_confirm_action_archive">Archivieren</string>
|
<string name="global_settings_confirm_action_archive">Archivieren</string>
|
||||||
<string name="global_settings_confirm_action_delete">Löschen (nur in Nachrichtenansicht)</string>
|
<string name="global_settings_confirm_action_delete">Löschen (nur in Nachrichtenansicht)</string>
|
||||||
<string name="global_settings_confirm_action_spam">Spam</string>
|
<string name="global_settings_confirm_action_spam">Spam</string>
|
||||||
<!-- NEW: <string name="global_settings_confirm_action_mark_all_as_read">Mark all as read</string>-->
|
<string name="global_settings_confirm_action_mark_all_as_read">Alle als gelesen markieren</string>
|
||||||
<string name="global_settings_confirm_action_send">Senden</string>
|
<string name="global_settings_confirm_action_send">Senden</string>
|
||||||
|
|
||||||
<string name="global_settings_privacy_mode_title">Vertrauliche Benachrichtigung</string>
|
<string name="global_settings_privacy_mode_title">Vertrauliche Benachrichtigung</string>
|
||||||
@ -688,7 +688,7 @@ Willkommen zum \"K-9 Mail\"-Setup. K-9 ist eine quelloffene E-Mail-Anwendung fü
|
|||||||
<string name="account_settings_add_account_label">Eine weiteres Konto hinzufügen</string>
|
<string name="account_settings_add_account_label">Eine weiteres Konto hinzufügen</string>
|
||||||
<string name="account_settings_description_label">Kontoname</string>
|
<string name="account_settings_description_label">Kontoname</string>
|
||||||
<string name="account_settings_name_label">Ihr Name</string>
|
<string name="account_settings_name_label">Ihr Name</string>
|
||||||
<string name="notifications_title">Benachrichtigungseinstellungen</string>
|
<string name="notifications_title">Benachrichtigungen</string>
|
||||||
<string name="account_settings_ring_summary">Klingeln bei neuer Nachricht</string>
|
<string name="account_settings_ring_summary">Klingeln bei neuer Nachricht</string>
|
||||||
<string name="account_settings_vibrate_enable">Vibration</string>
|
<string name="account_settings_vibrate_enable">Vibration</string>
|
||||||
<string name="account_settings_vibrate_summary">Vibration bei neuer Nachricht</string>
|
<string name="account_settings_vibrate_summary">Vibration bei neuer Nachricht</string>
|
||||||
@ -869,16 +869,16 @@ Willkommen zum \"K-9 Mail\"-Setup. K-9 ist eine quelloffene E-Mail-Anwendung fü
|
|||||||
<string name="date_format_common">dd.MMM yyyy</string>
|
<string name="date_format_common">dd.MMM yyyy</string>
|
||||||
<string name="date_format_iso8601">yyyy-MM-dd</string>
|
<string name="date_format_iso8601">yyyy-MM-dd</string>
|
||||||
|
|
||||||
<string name="batch_ops">Mehrfachauswahl</string>
|
<string name="batch_ops">Gruppenoperationen</string>
|
||||||
<string name="batch_delete_op">Ausgewählte löschen</string>
|
<string name="batch_delete_op">Gewählte löschen</string>
|
||||||
<string name="batch_mark_read_op">Ausgewählte als gelesen markieren</string>
|
<string name="batch_mark_read_op">Gewählte als gelesen markieren</string>
|
||||||
<string name="batch_mark_unread_op">Ausgewählte als ungelesen markieren</string>
|
<string name="batch_mark_unread_op">Gewählte als ungelesen markieren</string>
|
||||||
<string name="batch_flag_op">Ausgewählte als wichtig markieren</string>
|
<string name="batch_flag_op">Gewählte als wichtig markieren</string>
|
||||||
<string name="batch_unflag_op">Markierung bei Ausgewählten entfernen</string>
|
<string name="batch_unflag_op">Markierung bei Gewählten entfernen</string>
|
||||||
<string name="batch_archive_op">Ausgewählte sichern</string>
|
<string name="batch_archive_op">Gewählte sichern</string>
|
||||||
<string name="batch_spam_op">Ausgewählte als Spam markieren</string>
|
<string name="batch_spam_op">Gewählte als Spam markieren</string>
|
||||||
<string name="batch_move_op">Ausgewählte verschieben</string>
|
<string name="batch_move_op">Gewählte verschieben</string>
|
||||||
<string name="batch_copy_op">Ausgewählte kopieren</string>
|
<string name="batch_copy_op">Gewählte kopieren</string>
|
||||||
<string name="batch_flag_mode">Stern-Modus</string>
|
<string name="batch_flag_mode">Stern-Modus</string>
|
||||||
<string name="batch_select_mode">Auswahl-Modus</string>
|
<string name="batch_select_mode">Auswahl-Modus</string>
|
||||||
<string name="batch_plain_mode">Normaler Modus</string>
|
<string name="batch_plain_mode">Normaler Modus</string>
|
||||||
@ -1022,12 +1022,12 @@ Willkommen zum \"K-9 Mail\"-Setup. K-9 ist eine quelloffene E-Mail-Anwendung fü
|
|||||||
<string name="dialog_confirm_delete_confirm_button">Löschen</string>
|
<string name="dialog_confirm_delete_confirm_button">Löschen</string>
|
||||||
<string name="dialog_confirm_delete_cancel_button">Nicht löschen</string>
|
<string name="dialog_confirm_delete_cancel_button">Nicht löschen</string>
|
||||||
|
|
||||||
<!-- NEW: <string name="dialog_confirm_spam_title">Confirm move to spam folder</string>-->
|
<string name="dialog_confirm_spam_title">Als Spam markieren</string>
|
||||||
<!-- NEW: <string name="dialog_confirm_spam_message">Do you really want to move this message to the spam folder?</string>-->
|
<string name="dialog_confirm_spam_message">Wollen Sie diese Nachricht in den Spam-Ordner verschieben?</string>
|
||||||
<!-- NEW: <string name="dialog_confirm_spam_confirm_button">Yes</string>-->
|
<string name="dialog_confirm_spam_confirm_button">Ja</string>
|
||||||
<!-- NEW: <string name="dialog_confirm_spam_cancel_button">No</string>-->
|
<string name="dialog_confirm_spam_cancel_button">Nein</string>
|
||||||
|
|
||||||
<!-- NEW: <string name="dialog_attachment_progress_title">Downloading attachment</string>-->
|
<string name="dialog_attachment_progress_title">Anhang wird heruntergeladen</string>
|
||||||
|
|
||||||
<string name="debug_logging_enabled">Debug-Meldungen werden mit Hilfe des Android-Logging-Systems aufgezeichnet.</string>
|
<string name="debug_logging_enabled">Debug-Meldungen werden mit Hilfe des Android-Logging-Systems aufgezeichnet.</string>
|
||||||
|
|
||||||
@ -1037,4 +1037,7 @@ Willkommen zum \"K-9 Mail\"-Setup. K-9 ist eine quelloffene E-Mail-Anwendung fü
|
|||||||
|
|
||||||
<string name="account_unavailable">Konto \"<xliff:g id="account">%s</xliff:g>\" ist nicht verfügbar; Bitte SD-Karte prüfen.</string>
|
<string name="account_unavailable">Konto \"<xliff:g id="account">%s</xliff:g>\" ist nicht verfügbar; Bitte SD-Karte prüfen.</string>
|
||||||
|
|
||||||
|
<string name="settings_attachment_default_path">Anhang speichern unter...</string>
|
||||||
|
<string name="attachment_save_title">Anhang speichern</string>
|
||||||
|
<string name="attachment_save_desc">Es wurde kein Dateimanager gefunden. Wo soll der Anhang abgelegt werden?</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -1037,4 +1037,7 @@ Bienvenido a la Configuración de K-9. K-9 es un cliente de correo OpenSource pa
|
|||||||
|
|
||||||
<!-- NEW: <string name="account_unavailable">Account \"<xliff:g id="account">%s</xliff:g>\" is unavailable; check storage</string>-->
|
<!-- NEW: <string name="account_unavailable">Account \"<xliff:g id="account">%s</xliff:g>\" is unavailable; check storage</string>-->
|
||||||
|
|
||||||
|
<!-- NEW: <string name="settings_attachment_default_path">Save attachments to...</string>-->
|
||||||
|
<!-- NEW: <string name="attachment_save_title">Save attachment</string>-->
|
||||||
|
<!-- NEW: <string name="attachment_save_desc">No file browser found. Where would you like to save this attachment?</string>-->
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -1034,4 +1034,7 @@ Tervetuloa K-9 Mail asennukseen. K-9 on avoimen lähdekoodin sähköpostiasiak
|
|||||||
|
|
||||||
<!-- NEW: <string name="account_unavailable">Account \"<xliff:g id="account">%s</xliff:g>\" is unavailable; check storage</string>-->
|
<!-- NEW: <string name="account_unavailable">Account \"<xliff:g id="account">%s</xliff:g>\" is unavailable; check storage</string>-->
|
||||||
|
|
||||||
|
<!-- NEW: <string name="settings_attachment_default_path">Save attachments to...</string>-->
|
||||||
|
<!-- NEW: <string name="attachment_save_title">Save attachment</string>-->
|
||||||
|
<!-- NEW: <string name="attachment_save_desc">No file browser found. Where would you like to save this attachment?</string>-->
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -1037,4 +1037,7 @@ Benvido á Configuración de K-9. K-9 é un cliente de correo OpenSource para An
|
|||||||
|
|
||||||
<string name="account_unavailable">A conta \"<xliff:g id="account">%s</xliff:g>\" non está dispoñible; verifica o almacenamento</string>
|
<string name="account_unavailable">A conta \"<xliff:g id="account">%s</xliff:g>\" non está dispoñible; verifica o almacenamento</string>
|
||||||
|
|
||||||
|
<!-- NEW: <string name="settings_attachment_default_path">Save attachments to...</string>-->
|
||||||
|
<!-- NEW: <string name="attachment_save_title">Save attachment</string>-->
|
||||||
|
<!-- NEW: <string name="attachment_save_desc">No file browser found. Where would you like to save this attachment?</string>-->
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -1041,4 +1041,7 @@ Benvenuto nella configurazione della posta di K-9. K-9 è un client di posta ope
|
|||||||
|
|
||||||
<!-- NEW: <string name="account_unavailable">Account \"<xliff:g id="account">%s</xliff:g>\" is unavailable; check storage</string>-->
|
<!-- NEW: <string name="account_unavailable">Account \"<xliff:g id="account">%s</xliff:g>\" is unavailable; check storage</string>-->
|
||||||
|
|
||||||
|
<!-- NEW: <string name="settings_attachment_default_path">Save attachments to...</string>-->
|
||||||
|
<!-- NEW: <string name="attachment_save_title">Save attachment</string>-->
|
||||||
|
<!-- NEW: <string name="attachment_save_desc">No file browser found. Where would you like to save this attachment?</string>-->
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
<string name="accounts_title">アカウント一覧</string>
|
<string name="accounts_title">アカウント一覧</string>
|
||||||
<string name="advanced">拡張機能</string>
|
<string name="advanced">拡張機能</string>
|
||||||
<string name="folder_list_title"><xliff:g id="account">%s</xliff:g> </string>
|
<string name="folder_list_title"><xliff:g id="account">%s</xliff:g> </string>
|
||||||
<string name="shortcuts_title">K-9 Accounts</string>
|
<string name="shortcuts_title">K-9 アカウント</string>
|
||||||
|
|
||||||
<string name="message_list_title"><xliff:g id="account">%s</xliff:g>:<xliff:g id="folder">%s</xliff:g> </string>
|
<string name="message_list_title"><xliff:g id="account">%s</xliff:g>:<xliff:g id="folder">%s</xliff:g> </string>
|
||||||
|
|
||||||
@ -133,7 +133,7 @@
|
|||||||
<string name="status_loading_folder">(取込中 <xliff:g id="folder">%s</xliff:g><xliff:g id="progress">%s</xliff:g>)</string>
|
<string name="status_loading_folder">(取込中 <xliff:g id="folder">%s</xliff:g><xliff:g id="progress">%s</xliff:g>)</string>
|
||||||
<string name="status_loading_more">メール取込中\u2026</string>
|
<string name="status_loading_more">メール取込中\u2026</string>
|
||||||
<string name="status_network_error">接続エラー</string>
|
<string name="status_network_error">接続エラー</string>
|
||||||
<string name="status_invalid_id_error">新着メールなし</string>
|
<string name="status_invalid_id_error">メッセージが見つかりません</string>
|
||||||
<string name="status_error">エラー</string>
|
<string name="status_error">エラー</string>
|
||||||
<string name="status_sending">送信\u2026</string>
|
<string name="status_sending">送信\u2026</string>
|
||||||
|
|
||||||
@ -188,13 +188,13 @@
|
|||||||
|
|
||||||
<string name="send_failure_subject">メール送信に失敗しました</string>
|
<string name="send_failure_subject">メール送信に失敗しました</string>
|
||||||
<string name="send_failure_body_abbrev"><xliff:g id="errorFolder">%s</xliff:g> フォルダ詳細を確認してください</string>
|
<string name="send_failure_body_abbrev"><xliff:g id="errorFolder">%s</xliff:g> フォルダ詳細を確認してください</string>
|
||||||
<string name="send_failure_body_fmt">K-9 はメール送信中にトラブルが発生しました.
|
<string name="send_failure_body_fmt">メール送信中に問題が発生しました。
|
||||||
メッセージが送信されたかどうかについては、トラブルに応じるため不明です.
|
問題の性質により、メッセージが送信されたかどうかがわかりません。
|
||||||
送信宛先は、メールを既に受信している場合があります.
|
受信者は、そのメッセージを既に受信しているかもしれません。
|
||||||
\u000a\u000a送信済みトレイにトラブルで発生したメールを格納します.
|
\u000a\u000a問題が発生したメールには送信トレイにスターが付いています。
|
||||||
フラグ解除されたメールを再送信することができます.
|
スターを取ることで、メールを再送することができます。
|
||||||
送信済みトレイを長く押下することで「メール送信」メニューを表示させて送信することができます.\u000A\u000a
|
他のメッセージを送信するには、「メール送信」メニューを表示させるために送信トレイを長押ししてください。\u000A\u000a
|
||||||
<xliff:g id="errorFolder">%s</xliff:g> フォルダには失敗したエラーメッセージが含まれています.</string>
|
<xliff:g id="errorFolder">%s</xliff:g> フォルダにはその問題に関するエラーメッセージが含まれています。</string>
|
||||||
|
|
||||||
<string name="alert_header">K-9 警告</string>
|
<string name="alert_header">K-9 警告</string>
|
||||||
<string name="no_connection_alert">送信ネットワークのリソース不足のため同期処理中断</string>
|
<string name="no_connection_alert">送信ネットワークのリソース不足のため同期処理中断</string>
|
||||||
@ -231,7 +231,7 @@ K-9 Mail セットアップにようこそ。\nK-9 は標準のAndroidメール
|
|||||||
<string name="debug_enable_debug_logging_title">拡張デバッグログ</string>
|
<string name="debug_enable_debug_logging_title">拡張デバッグログ</string>
|
||||||
<string name="debug_enable_debug_logging_summary">追加診断情報ログ</string>
|
<string name="debug_enable_debug_logging_summary">追加診断情報ログ</string>
|
||||||
<string name="debug_enable_sensitive_logging_title">詳細情報ログ</string>
|
<string name="debug_enable_sensitive_logging_title">詳細情報ログ</string>
|
||||||
<string name="debug_enable_sensitive_logging_summary">ログにパスワードが表示されるかもしれません</string>
|
<string name="debug_enable_sensitive_logging_summary">ログにパスワードが表示される</string>
|
||||||
|
|
||||||
<string name="message_header_mua">K-9 for Android </string>
|
<string name="message_header_mua">K-9 for Android </string>
|
||||||
|
|
||||||
@ -259,16 +259,16 @@ K-9 Mail セットアップにようこそ。\nK-9 は標準のAndroidメール
|
|||||||
<string name="message_compose_content_hint">本文</string>
|
<string name="message_compose_content_hint">本文</string>
|
||||||
<string name="message_compose_quote_header_separator">-------- 元メール --------</string>
|
<string name="message_compose_quote_header_separator">-------- 元メール --------</string>
|
||||||
<string name="message_compose_quote_header_subject">件名:</string>
|
<string name="message_compose_quote_header_subject">件名:</string>
|
||||||
<!-- NEW: <string name="message_compose_quote_header_send_date">Sent:</string>-->
|
<string name="message_compose_quote_header_send_date">送信日:</string>
|
||||||
<string name="message_compose_quote_header_from">送信者:</string>
|
<string name="message_compose_quote_header_from">送信者:</string>
|
||||||
<string name="message_compose_quote_header_to">宛先:</string>
|
<string name="message_compose_quote_header_to">宛先:</string>
|
||||||
<string name="message_compose_quote_header_cc">CC:</string>
|
<string name="message_compose_quote_header_cc">CC:</string>
|
||||||
<string name="message_compose_reply_header_fmt"><xliff:g id="sender">%s</xliff:g> wrote:\n\n</string>
|
<string name="message_compose_reply_header_fmt"><xliff:g id="sender">%s</xliff:g> wrote:\n\n</string>
|
||||||
<string name="message_compose_quoted_text_label">テキスト引用</string>
|
<string name="message_compose_quoted_text_label">テキスト引用</string>
|
||||||
<string name="message_compose_error_no_recipients">少なくとも1つの受信者を追加する必要があります</string>
|
<string name="message_compose_error_no_recipients">少なくとも1つの受信者を追加する必要があります</string>
|
||||||
<!-- NEW: <string name="error_contact_address_not_found">No email address could be found.</string>-->
|
<string name="error_contact_address_not_found">メールアドレスが登録されていません</string>
|
||||||
<string name="message_compose_downloading_attachments_toast">一部の添付ファイルをダウンロードしていません.このメールが送信される前に自動的にダウンロードされます.</string>
|
<string name="message_compose_downloading_attachments_toast">一部の添付ファイルをダウンロードしていません。このメールが送信される前に自動的にダウンロードされます。</string>
|
||||||
<string name="message_compose_attachments_skipped_toast">ダウンロードしていないため、一部の添付ファイルを転送することはできません.</string>
|
<string name="message_compose_attachments_skipped_toast">ダウンロードしていないため、一部の添付ファイルを転送することはできません。</string>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -293,9 +293,9 @@ K-9 Mail セットアップにようこそ。\nK-9 は標準のAndroidメール
|
|||||||
<string name="message_view_download_remainder">すべてダウンロード</string>
|
<string name="message_view_download_remainder">すべてダウンロード</string>
|
||||||
|
|
||||||
<!-- NOTE: The following message refers to strings with id 'account_setup_incoming_save_all_headers_label' and 'account_setup_incoming_title' -->
|
<!-- NOTE: The following message refers to strings with id 'account_setup_incoming_save_all_headers_label' and 'account_setup_incoming_title' -->
|
||||||
<string name="message_additional_headers_not_downloaded">一部のヘッダしか保存されていません.ヘッダをすべて保存するためには、アカウント設定の受信メールサーバ設定で「すべてのヘッダを端末に保存」をチェックしてください.</string>
|
<string name="message_additional_headers_not_downloaded">一部のヘッダしか保存されていません。ヘッダをすべて保存するためには、アカウント設定の受信メールサーバ設定で「ヘッダのダウンロード」をチェックしてください。</string>
|
||||||
<string name="message_no_additional_headers_available">すべてのヘッダをダウンロードしましたが、表示すべき追加ヘッダはありませんでした.</string>
|
<string name="message_no_additional_headers_available">すべてのヘッダをダウンロードしましたが、表示すべき追加ヘッダはありませんでした。</string>
|
||||||
<string name="message_additional_headers_retrieval_failed">追加ヘッダをデータベースまたはメールサーバから取得できませんでした.</string>
|
<string name="message_additional_headers_retrieval_failed">追加ヘッダをデータベースまたはメールサーバから取得できませんでした。</string>
|
||||||
|
|
||||||
<string name="mailbox_select_dlg_title">フォルダ</string>
|
<string name="mailbox_select_dlg_title">フォルダ</string>
|
||||||
<string name="mailbox_select_dlg_new_mailbox_action">新しいフォルダ</string>
|
<string name="mailbox_select_dlg_new_mailbox_action">新しいフォルダ</string>
|
||||||
@ -318,7 +318,7 @@ K-9 Mail セットアップにようこそ。\nK-9 は標準のAndroidメール
|
|||||||
|
|
||||||
|
|
||||||
<string name="global_settings_flag_label">スターを表示</string>
|
<string name="global_settings_flag_label">スターを表示</string>
|
||||||
<string name="global_settings_flag_summary">スターは印を付けたメッセージを示します</string>
|
<string name="global_settings_flag_summary">スターは印の付いたメッセージを示す</string>
|
||||||
<string name="global_settings_checkbox_label">複数選択チェックボックス</string>
|
<string name="global_settings_checkbox_label">複数選択チェックボックス</string>
|
||||||
<string name="global_settings_checkbox_summary">複数選択チェックボックス常時表示</string>
|
<string name="global_settings_checkbox_summary">複数選択チェックボックス常時表示</string>
|
||||||
<string name="global_settings_touchable_label">メッセージプレビュー</string>
|
<string name="global_settings_touchable_label">メッセージプレビュー</string>
|
||||||
@ -333,7 +333,7 @@ K-9 Mail セットアップにようこそ。\nK-9 は標準のAndroidメール
|
|||||||
<string name="global_settings_registered_name_color_changed">連絡先の名前の場合は色を付ける</string>
|
<string name="global_settings_registered_name_color_changed">連絡先の名前の場合は色を付ける</string>
|
||||||
|
|
||||||
<string name="global_settings_messageview_fixedwidth_label">固定幅フォント</string>
|
<string name="global_settings_messageview_fixedwidth_label">固定幅フォント</string>
|
||||||
<string name="global_settings_messageview_fixedwidth_summary">プレーンテキストメッセージを表示する際、固定幅フォントを利用します.</string>
|
<string name="global_settings_messageview_fixedwidth_summary">プレーンテキストメッセージの表示に固定幅フォントを利用</string>
|
||||||
<string name="global_settings_messageview_return_to_list_label">削除後メッセージ一覧へ戻る</string>
|
<string name="global_settings_messageview_return_to_list_label">削除後メッセージ一覧へ戻る</string>
|
||||||
<string name="global_settings_messageview_return_to_list_summary">メッセージの削除後、メッセージ一覧に戻る</string>
|
<string name="global_settings_messageview_return_to_list_summary">メッセージの削除後、メッセージ一覧に戻る</string>
|
||||||
|
|
||||||
@ -342,7 +342,7 @@ K-9 Mail セットアップにようこそ。\nK-9 は標準のAndroidメール
|
|||||||
<string name="global_settings_confirm_action_archive">アーカイブ</string>
|
<string name="global_settings_confirm_action_archive">アーカイブ</string>
|
||||||
<string name="global_settings_confirm_action_delete">削除(メッセージ表示画面のみ)</string>
|
<string name="global_settings_confirm_action_delete">削除(メッセージ表示画面のみ)</string>
|
||||||
<string name="global_settings_confirm_action_spam">迷惑メール</string>
|
<string name="global_settings_confirm_action_spam">迷惑メール</string>
|
||||||
<!-- NEW: <string name="global_settings_confirm_action_mark_all_as_read">Mark all as read</string>-->
|
<string name="global_settings_confirm_action_mark_all_as_read">すべて既読にする</string>
|
||||||
<string name="global_settings_confirm_action_send">送信</string>
|
<string name="global_settings_confirm_action_send">送信</string>
|
||||||
|
|
||||||
<string name="global_settings_privacy_mode_title">スクリーンロック時の通知</string>
|
<string name="global_settings_privacy_mode_title">スクリーンロック時の通知</string>
|
||||||
@ -350,7 +350,7 @@ K-9 Mail セットアップにようこそ。\nK-9 は標準のAndroidメール
|
|||||||
|
|
||||||
|
|
||||||
<string name="quiet_time">夜間時間帯</string>
|
<string name="quiet_time">夜間時間帯</string>
|
||||||
<string name="quiet_time_description">夜間での各種通知や表示を抑制する時間帯を設定します.</string>
|
<string name="quiet_time_description">夜間での各種通知や表示を抑制する時間帯を設定</string>
|
||||||
<string name="quiet_time_starts">開始時刻</string>
|
<string name="quiet_time_starts">開始時刻</string>
|
||||||
<string name="quiet_time_ends">終了時刻</string>
|
<string name="quiet_time_ends">終了時刻</string>
|
||||||
|
|
||||||
@ -491,7 +491,7 @@ K-9 Mail セットアップにようこそ。\nK-9 は標準のAndroidメール
|
|||||||
|
|
||||||
<string name="push_poll_on_connect_label">プッシュ接続時の同期</string>
|
<string name="push_poll_on_connect_label">プッシュ接続時の同期</string>
|
||||||
<string name="account_setup_options_enable_push_label">このアカウントにプッシュメールを有効化</string>
|
<string name="account_setup_options_enable_push_label">このアカウントにプッシュメールを有効化</string>
|
||||||
<string name="account_setup_options_enable_push_summary">メールサーバがサポートしていれば新しいメッセージは即座に表示されます.当オプションはパフォーマンスが改善もしくは低下します.</string>
|
<string name="account_setup_options_enable_push_summary">メールサーバがサポートしていれば新しいメッセージは即座に表示されます。当オプションはパフォーマンスが改善もしくは低下します。</string>
|
||||||
<string name="idle_refresh_period_label">IMAP IDLE(プッシュ)接続のリフレッシュ</string>
|
<string name="idle_refresh_period_label">IMAP IDLE(プッシュ)接続のリフレッシュ</string>
|
||||||
<string name="idle_refresh_period_1min">1分毎</string>
|
<string name="idle_refresh_period_1min">1分毎</string>
|
||||||
<string name="idle_refresh_period_2min">2分毎</string>
|
<string name="idle_refresh_period_2min">2分毎</string>
|
||||||
@ -584,7 +584,7 @@ K-9 Mail セットアップにようこそ。\nK-9 は標準のAndroidメール
|
|||||||
<string name="account_settings_crypto_app_none">なし</string>
|
<string name="account_settings_crypto_app_none">なし</string>
|
||||||
<string name="account_settings_crypto_app_not_available">利用不可</string>
|
<string name="account_settings_crypto_app_not_available">利用不可</string>
|
||||||
<string name="account_settings_crypto_auto_signature">自動署名</string>
|
<string name="account_settings_crypto_auto_signature">自動署名</string>
|
||||||
<string name="account_settings_crypto_auto_signature_summary">このアカウントのE-Mailアドレスから署名の鍵を自動的に決定する.</string>
|
<string name="account_settings_crypto_auto_signature_summary">このアカウントのE-Mailアドレスから署名の鍵を自動的に決定する</string>
|
||||||
|
|
||||||
<string name="account_settings_mail_check_frequency_label">同期フォルダの同期間隔</string>
|
<string name="account_settings_mail_check_frequency_label">同期フォルダの同期間隔</string>
|
||||||
<string name="account_settings_second_class_check_frequency_label">2nd クラス自動受信間隔</string>
|
<string name="account_settings_second_class_check_frequency_label">2nd クラス自動受信間隔</string>
|
||||||
@ -600,7 +600,7 @@ K-9 Mail セットアップにようこそ。\nK-9 は標準のAndroidメール
|
|||||||
|
|
||||||
<string name="account_settings_mail_display_count_label">一度に表示するメール数</string>
|
<string name="account_settings_mail_display_count_label">一度に表示するメール数</string>
|
||||||
|
|
||||||
<string name="account_settings_autodownload_message_size_label">ダウンロードするメッセージの上限</string>
|
<string name="account_settings_autodownload_message_size_label">ダウンロードするメッセージサイズの上限</string>
|
||||||
<string name="account_settings_autodownload_message_size_1">1Kb</string>
|
<string name="account_settings_autodownload_message_size_1">1Kb</string>
|
||||||
<string name="account_settings_autodownload_message_size_2">2Kb</string>
|
<string name="account_settings_autodownload_message_size_2">2Kb</string>
|
||||||
<string name="account_settings_autodownload_message_size_4">4Kb</string>
|
<string name="account_settings_autodownload_message_size_4">4Kb</string>
|
||||||
@ -841,7 +841,7 @@ K-9 Mail セットアップにようこそ。\nK-9 は標準のAndroidメール
|
|||||||
<string name="settings_messageview_mobile_layout_label">1列レイアウト</string>
|
<string name="settings_messageview_mobile_layout_label">1列レイアウト</string>
|
||||||
<string name="settings_messageview_mobile_layout_summary">小さい画面用にHTMLメッセージを再構成</string>
|
<string name="settings_messageview_mobile_layout_summary">小さい画面用にHTMLメッセージを再構成</string>
|
||||||
<string name="settings_messageview_zoom_controls_label">ズーム制御</string>
|
<string name="settings_messageview_zoom_controls_label">ズーム制御</string>
|
||||||
<string name="settings_messageview_zoom_controls_summary">デバイスが対応するならば、ズームウィジェットやピンチズームを有効にします</string>
|
<string name="settings_messageview_zoom_controls_summary">デバイスが対応するならば、ズームウィジェットやピンチズームを有効にする</string>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -910,13 +910,13 @@ K-9 Mail セットアップにようこそ。\nK-9 は標準のAndroidメール
|
|||||||
<string name="start_integrated_inbox_summary">起動後に統合フォルダを表示する</string>
|
<string name="start_integrated_inbox_summary">起動後に統合フォルダを表示する</string>
|
||||||
|
|
||||||
<string name="measure_accounts_title">アカウントのサイズ表示</string>
|
<string name="measure_accounts_title">アカウントのサイズ表示</string>
|
||||||
<string name="measure_accounts_summary">表示を早くしたい場合はチェックをはずしてください</string>
|
<string name="measure_accounts_summary">表示を速くしたい場合はチェックしない</string>
|
||||||
|
|
||||||
<string name="count_search_title">検索結果の件数表示</string>
|
<string name="count_search_title">検索結果の件数表示</string>
|
||||||
<string name="count_search_summary">表示を早くしたい場合はチェックをはずしてください</string>
|
<string name="count_search_summary">表示を速くしたい場合はチェックしない</string>
|
||||||
|
|
||||||
<!-- NEW: <string name="hide_special_accounts_title">Hide special accounts</string>-->
|
<string name="hide_special_accounts_title">特殊なアカウントを隠す</string>
|
||||||
<!-- NEW: <string name="hide_special_accounts_summary">Hide the unified inbox and all messages accounts</string>-->
|
<string name="hide_special_accounts_summary">統合フォルダと全メッセージを隠す</string>
|
||||||
|
|
||||||
<string name="search_title"><xliff:g id="search_name">%s</xliff:g> <xliff:g id="modifier">%s</xliff:g></string>
|
<string name="search_title"><xliff:g id="search_name">%s</xliff:g> <xliff:g id="modifier">%s</xliff:g></string>
|
||||||
<string name="flagged_modifier"> - スター</string>
|
<string name="flagged_modifier"> - スター</string>
|
||||||
@ -1018,12 +1018,12 @@ K-9 Mail セットアップにようこそ。\nK-9 は標準のAndroidメール
|
|||||||
<string name="dialog_confirm_delete_confirm_button">削除する</string>
|
<string name="dialog_confirm_delete_confirm_button">削除する</string>
|
||||||
<string name="dialog_confirm_delete_cancel_button">削除しない</string>
|
<string name="dialog_confirm_delete_cancel_button">削除しない</string>
|
||||||
|
|
||||||
<!-- NEW: <string name="dialog_confirm_spam_title">Confirm move to spam folder</string>-->
|
<string name="dialog_confirm_spam_title">迷惑メールフォルダへの移動の確認</string>
|
||||||
<!-- NEW: <string name="dialog_confirm_spam_message">Do you really want to move this message to the spam folder?</string>-->
|
<string name="dialog_confirm_spam_message">本当にこのメッセージを迷惑メールフォルダに移動しますか?</string>
|
||||||
<!-- NEW: <string name="dialog_confirm_spam_confirm_button">Yes</string>-->
|
<string name="dialog_confirm_spam_confirm_button">はい</string>
|
||||||
<!-- NEW: <string name="dialog_confirm_spam_cancel_button">No</string>-->
|
<string name="dialog_confirm_spam_cancel_button">いいえ</string>
|
||||||
|
|
||||||
<!-- NEW: <string name="dialog_attachment_progress_title">Downloading attachment</string>-->
|
<string name="dialog_attachment_progress_title">添付ファイルをダウンロードしています</string>
|
||||||
|
|
||||||
<string name="debug_logging_enabled">Android のログにデバッグ用のログを出力するように設定しました。</string>
|
<string name="debug_logging_enabled">Android のログにデバッグ用のログを出力するように設定しました。</string>
|
||||||
|
|
||||||
@ -1031,6 +1031,9 @@ K-9 Mail セットアップにようこそ。\nK-9 は標準のAndroidメール
|
|||||||
<string name="messagelist_sent_cc_me_sigil">\u203a</string>
|
<string name="messagelist_sent_cc_me_sigil">\u203a</string>
|
||||||
<string name="error_unable_to_connect">接続できません</string>
|
<string name="error_unable_to_connect">接続できません</string>
|
||||||
|
|
||||||
<!-- NEW: <string name="account_unavailable">Account \"<xliff:g id="account">%s</xliff:g>\" is unavailable; check storage</string>-->
|
<string name="account_unavailable">アカウント \"<xliff:g id="account">%s</xliff:g>\" は利用できません。ストレージを確認してください。</string>
|
||||||
|
|
||||||
|
<string name="settings_attachment_default_path">添付ファイルの保存先</string>
|
||||||
|
<string name="attachment_save_title">添付ファイルの保存先</string>
|
||||||
|
<string name="attachment_save_desc">ファイルブラウザがインストールされていません。添付ファイルの保存場所を直接入力してください。</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
1043
res/values-ko/strings.xml
Normal file
1043
res/values-ko/strings.xml
Normal file
File diff suppressed because it is too large
Load Diff
@ -3,14 +3,14 @@
|
|||||||
<string name="app_name">K-9 Mail</string>
|
<string name="app_name">K-9 Mail</string>
|
||||||
<string name="beta_app_name">K-9 Mail BETA</string>
|
<string name="beta_app_name">K-9 Mail BETA</string>
|
||||||
<string name="app_authors">Google, The K-9 Dog Walkers.</string>
|
<string name="app_authors">Google, The K-9 Dog Walkers.</string>
|
||||||
<!-- NEW: <string name="app_copyright_fmt">Copyright 2008-<xliff:g>%s</xliff:g> The K-9 Dog Walkers. Portions Copyright 2006-<xliff:g>%s</xliff:g> the Android Open Source Project.</string>-->
|
<string name="app_copyright_fmt">Copyright 2008-<xliff:g>%s</xliff:g> The K-9 Dog Walkers. Portions Copyright 2006-<xliff:g>%s</xliff:g> the Android Open Source Project.</string>
|
||||||
<!-- NEW: <string name="app_license">Licensed under the Apache License, Version 2.0.</string>-->
|
<string name="app_license">Licensed under the Apache License, Version 2.0.</string>
|
||||||
<string name="app_authors_fmt">Auteurs: <xliff:g id="app_authors">%s</xliff:g></string>
|
<string name="app_authors_fmt">Auteurs: <xliff:g id="app_authors">%s</xliff:g></string>
|
||||||
<string name="app_revision_url">http://code.google.com/p/k9mail/wiki/ReleaseNotes</string>
|
<string name="app_revision_url">http://code.google.com/p/k9mail/wiki/ReleaseNotes</string>
|
||||||
<string name="app_revision_fmt">Revisie Informatie: <xliff:g id="app_revision_url">%s</xliff:g></string>
|
<string name="app_revision_fmt">Revisie Informatie: <xliff:g id="app_revision_url">%s</xliff:g></string>
|
||||||
<string name="app_webpage_url">http://code.google.com/p/k9mail/</string>
|
<string name="app_webpage_url">http://code.google.com/p/k9mail/</string>
|
||||||
<!-- NEW: <string name="app_libraries">We\'re using the following third-party libraries: <xliff:g id="app_libraries_list">%s</xliff:g></string>-->
|
<string name="app_libraries">De volgende externe bibliotheken worden gebruikt: <xliff:g id="app_libraries_list">%s</xliff:g></string>
|
||||||
<!-- NEW: <string name="app_emoji_icons">Emoji icons: <xliff:g id="app_emoji_icons_link">%s</xliff:g></string>-->
|
<string name="app_emoji_icons">Emoji icons: <xliff:g id="app_emoji_icons_link">%s</xliff:g></string>
|
||||||
|
|
||||||
<string name="read_attachment_label">Lees Email bijlage</string>
|
<string name="read_attachment_label">Lees Email bijlage</string>
|
||||||
<string name="read_attachment_desc">Sta deze applicatie toe de bijlage van emails te lezen.</string>
|
<string name="read_attachment_desc">Sta deze applicatie toe de bijlage van emails te lezen.</string>
|
||||||
@ -42,15 +42,15 @@
|
|||||||
<string name="folder_progress">\u0020<xliff:g id="completed">%s</xliff:g>/<xliff:g id="total">%s</xliff:g></string>
|
<string name="folder_progress">\u0020<xliff:g id="completed">%s</xliff:g>/<xliff:g id="total">%s</xliff:g></string>
|
||||||
|
|
||||||
<string name="status_next_poll">\u0020(Volgende poll @ <xliff:g id="nexttime">%s</xliff:g>)</string>
|
<string name="status_next_poll">\u0020(Volgende poll @ <xliff:g id="nexttime">%s</xliff:g>)</string>
|
||||||
<!-- NEW: <string name="status_syncing_off">\u0020(Syncing disabled)</string>-->
|
<string name="status_syncing_off">\u0020(Synchroniseren uitgeschakeld)</string>
|
||||||
|
|
||||||
<!-- Actions will be used as buttons and in menu items -->
|
<!-- Actions will be used as buttons and in menu items -->
|
||||||
<string name="next_action">Volgende</string> <!-- Used as part of a multi-step process -->
|
<string name="next_action">Volgende</string> <!-- Used as part of a multi-step process -->
|
||||||
<!-- NEW: <string name="previous_action">Previous</string>--> <!-- Used as part of a multi-step process -->
|
<string name="previous_action">Vorige</string> <!-- Used as part of a multi-step process -->
|
||||||
<string name="okay_action">OK</string> <!-- User to confirm acceptance of dialog boxes, warnings, errors, etc. -->
|
<string name="okay_action">OK</string> <!-- User to confirm acceptance of dialog boxes, warnings, errors, etc. -->
|
||||||
<string name="cancel_action">Annuleer</string>
|
<string name="cancel_action">Annuleer</string>
|
||||||
<string name="send_action">Verzenden</string>
|
<string name="send_action">Verzenden</string>
|
||||||
<!-- NEW: <string name="send_again_action">Send Again</string>-->
|
<string name="send_again_action">Opnieuw Verzenden</string>
|
||||||
<string name="select_action">Selecteren</string>
|
<string name="select_action">Selecteren</string>
|
||||||
<string name="deselect_action">Annuleer selectie</string>
|
<string name="deselect_action">Annuleer selectie</string>
|
||||||
<string name="reply_action">Antwoorden</string>
|
<string name="reply_action">Antwoorden</string>
|
||||||
@ -117,7 +117,7 @@
|
|||||||
<string name="dump_settings_action">Gooi instellingen weg</string>
|
<string name="dump_settings_action">Gooi instellingen weg</string>
|
||||||
<string name="empty_trash_action">Prullenbak legen</string>
|
<string name="empty_trash_action">Prullenbak legen</string>
|
||||||
<string name="expunge_action">Wissen</string>
|
<string name="expunge_action">Wissen</string>
|
||||||
<!-- NEW: <string name="clear_local_folder_action">Clear local messages</string>-->
|
<string name="clear_local_folder_action">Lokale berichten wissen</string>
|
||||||
<string name="set_sort_action">Kies sortering</string>
|
<string name="set_sort_action">Kies sortering</string>
|
||||||
<string name="reverse_sort_action">Omgekeerd sorteren</string>
|
<string name="reverse_sort_action">Omgekeerd sorteren</string>
|
||||||
<string name="about_action">Over</string>
|
<string name="about_action">Over</string>
|
||||||
@ -127,7 +127,7 @@
|
|||||||
<string name="folder_context_menu_title">Map opties</string>
|
<string name="folder_context_menu_title">Map opties</string>
|
||||||
|
|
||||||
<string name="general_no_subject">(Geen onderwerp)</string> <!-- Shown in place of the subject when a message has no subject. Showing this in parentheses is customary. -->
|
<string name="general_no_subject">(Geen onderwerp)</string> <!-- Shown in place of the subject when a message has no subject. Showing this in parentheses is customary. -->
|
||||||
<!-- NEW: <string name="general_no_date">No date</string>-->
|
<string name="general_no_date">Geen datum</string>
|
||||||
<string name="general_no_sender">Geen afzender</string>
|
<string name="general_no_sender">Geen afzender</string>
|
||||||
<string name="status_loading">Polling</string>
|
<string name="status_loading">Polling</string>
|
||||||
<string name="status_loading_folder">(Poll <xliff:g id="folder">%s</xliff:g><xliff:g id="progress">%s</xliff:g>)</string>
|
<string name="status_loading_folder">(Poll <xliff:g id="folder">%s</xliff:g><xliff:g id="progress">%s</xliff:g>)</string>
|
||||||
@ -259,14 +259,14 @@ Welkom bij K-9 Mail setup. K-9 is een open source mail cliënt voor Android, ge
|
|||||||
<string name="message_compose_content_hint">Bericht tekst</string>
|
<string name="message_compose_content_hint">Bericht tekst</string>
|
||||||
<string name="message_compose_quote_header_separator">-------- Origineel bericht --------</string>
|
<string name="message_compose_quote_header_separator">-------- Origineel bericht --------</string>
|
||||||
<string name="message_compose_quote_header_subject">Subject:</string>
|
<string name="message_compose_quote_header_subject">Subject:</string>
|
||||||
<!-- NEW: <string name="message_compose_quote_header_send_date">Sent:</string>-->
|
<string name="message_compose_quote_header_send_date">Verzonden:</string>
|
||||||
<string name="message_compose_quote_header_from">From:</string>
|
<string name="message_compose_quote_header_from">From:</string>
|
||||||
<string name="message_compose_quote_header_to">To:</string>
|
<string name="message_compose_quote_header_to">To:</string>
|
||||||
<string name="message_compose_quote_header_cc">CC:</string>
|
<string name="message_compose_quote_header_cc">CC:</string>
|
||||||
<string name="message_compose_reply_header_fmt"><xliff:g id="sender">%s</xliff:g> wrote:\n\n</string>
|
<string name="message_compose_reply_header_fmt"><xliff:g id="sender">%s</xliff:g> wrote:\n\n</string>
|
||||||
<string name="message_compose_quoted_text_label">Ge-quote tekst</string>
|
<string name="message_compose_quoted_text_label">Ge-quote tekst</string>
|
||||||
<string name="message_compose_error_no_recipients">Minimaal 1 ontvanger kiezen.</string>
|
<string name="message_compose_error_no_recipients">Minimaal 1 ontvanger kiezen.</string>
|
||||||
<!-- NEW: <string name="error_contact_address_not_found">No email address could be found.</string>-->
|
<string name="error_contact_address_not_found">Geen email adres gevonden.</string>
|
||||||
<string name="message_compose_downloading_attachments_toast">Sommige bijlage zijn niet gedownload. Deze worden automatisch gedownload voor dat dit bericht is verzonden.</string>
|
<string name="message_compose_downloading_attachments_toast">Sommige bijlage zijn niet gedownload. Deze worden automatisch gedownload voor dat dit bericht is verzonden.</string>
|
||||||
<string name="message_compose_attachments_skipped_toast">Sommige bijlagen kunnen niet worden doorgestuurd, omdat ze niet zijn gedownload.</string>
|
<string name="message_compose_attachments_skipped_toast">Sommige bijlagen kunnen niet worden doorgestuurd, omdat ze niet zijn gedownload.</string>
|
||||||
|
|
||||||
@ -324,11 +324,11 @@ Welkom bij K-9 Mail setup. K-9 is een open source mail cliënt voor Android, ge
|
|||||||
<string name="global_settings_checkbox_summary">Laat altijd multi-selecteer selectieboxen zien</string>
|
<string name="global_settings_checkbox_summary">Laat altijd multi-selecteer selectieboxen zien</string>
|
||||||
<string name="global_settings_touchable_label">Berichten voorbeelden</string>
|
<string name="global_settings_touchable_label">Berichten voorbeelden</string>
|
||||||
<string name="global_settings_touchable_summary">Ruimere lijst items met bericht voorbeelden</string>
|
<string name="global_settings_touchable_summary">Ruimere lijst items met bericht voorbeelden</string>
|
||||||
<!-- NEW: <string name="global_settings_preview_lines_label">Preview lines</string>-->
|
<string name="global_settings_preview_lines_label">Preview regels</string>
|
||||||
<!-- NEW: <string name="global_settings_show_correspondent_names_label">Show correspondent names</string>-->
|
<string name="global_settings_show_correspondent_names_label">Toon naam bij bericht</string>
|
||||||
<!-- NEW: <string name="global_settings_show_correspondent_names_summary">Show correspondent names rather than their email addresses</string>-->
|
<string name="global_settings_show_correspondent_names_summary">Geef bij voorkeur naam van afzender/geadresseerde weer i.p.v. email adres</string>
|
||||||
<!-- NEW: <string name="global_settings_show_contact_name_label">Show contact names</string>-->
|
<string name="global_settings_show_contact_name_label">Toon naam uit contactenlijst</string>
|
||||||
<!-- NEW: <string name="global_settings_show_contact_name_summary">Use recipient names from Contacts when available</string>-->
|
<string name="global_settings_show_contact_name_summary">Geef de naam weer uit het adresboek</string>
|
||||||
<string name="global_settings_registered_name_color_label">Kleuren contacten</string>
|
<string name="global_settings_registered_name_color_label">Kleuren contacten</string>
|
||||||
<string name="global_settings_registered_name_color_default">Niet kleuren van namen in uw lijst met contactpersonen</string>
|
<string name="global_settings_registered_name_color_default">Niet kleuren van namen in uw lijst met contactpersonen</string>
|
||||||
<string name="global_settings_registered_name_color_changed">Kleuren van namen in uw lijst met contactpersonen</string>
|
<string name="global_settings_registered_name_color_changed">Kleuren van namen in uw lijst met contactpersonen</string>
|
||||||
@ -343,17 +343,17 @@ Welkom bij K-9 Mail setup. K-9 is een open source mail cliënt voor Android, ge
|
|||||||
<string name="global_settings_confirm_action_archive">Archief</string>
|
<string name="global_settings_confirm_action_archive">Archief</string>
|
||||||
<string name="global_settings_confirm_action_delete">Verwijder (alleen berichten bekijken)</string>
|
<string name="global_settings_confirm_action_delete">Verwijder (alleen berichten bekijken)</string>
|
||||||
<string name="global_settings_confirm_action_spam">Spam</string>
|
<string name="global_settings_confirm_action_spam">Spam</string>
|
||||||
<!-- NEW: <string name="global_settings_confirm_action_mark_all_as_read">Mark all as read</string>-->
|
<string name="global_settings_confirm_action_mark_all_as_read">Markeer alles als gelezen</string>
|
||||||
<string name="global_settings_confirm_action_send">Verzonden</string>
|
<string name="global_settings_confirm_action_send">Verzonden</string>
|
||||||
|
|
||||||
<string name="global_settings_privacy_mode_title">Lock-screen meldingen</string>
|
<string name="global_settings_privacy_mode_title">Lock-screen meldingen</string>
|
||||||
<string name="global_settings_privacy_mode_summary">Niet weergegeven onderwerp van het bericht in de notificatie bar als het systeem is vergrendeld</string>
|
<string name="global_settings_privacy_mode_summary">Niet weergegeven onderwerp van het bericht in de notificatie bar als het systeem is vergrendeld</string>
|
||||||
|
|
||||||
|
|
||||||
<!-- NEW: <string name="quiet_time">Quiet Time</string>-->
|
<string name="quiet_time">Stilteperiode</string>
|
||||||
<!-- NEW: <string name="quiet_time_description">Disable ringing, buzzing and flashing at night</string>-->
|
<string name="quiet_time_description">Schakel beltoon, vibratie en leds uit gedurende de nacht</string>
|
||||||
<!-- NEW: <string name="quiet_time_starts">Quiet Time starts</string>-->
|
<string name="quiet_time_starts">Stilteperiode start</string>
|
||||||
<!-- NEW: <string name="quiet_time_ends">Quiet Time ends</string>-->
|
<string name="quiet_time_ends">Stilteperiode eindigt</string>
|
||||||
|
|
||||||
|
|
||||||
<string name="account_setup_basics_title">Een nieuwe account instellen</string>
|
<string name="account_setup_basics_title">Een nieuwe account instellen</string>
|
||||||
@ -370,8 +370,8 @@ Welkom bij K-9 Mail setup. K-9 is een open source mail cliënt voor Android, ge
|
|||||||
<string name="account_setup_check_settings_retr_info_msg">Ophalen account informatie\u2026</string>
|
<string name="account_setup_check_settings_retr_info_msg">Ophalen account informatie\u2026</string>
|
||||||
<string name="account_setup_check_settings_check_incoming_msg">Controleren van inkomende serverinstellingen\u2026</string>
|
<string name="account_setup_check_settings_check_incoming_msg">Controleren van inkomende serverinstellingen\u2026</string>
|
||||||
<string name="account_setup_check_settings_check_outgoing_msg">Controleren van uitgaande serverinstellingen\u2026</string>
|
<string name="account_setup_check_settings_check_outgoing_msg">Controleren van uitgaande serverinstellingen\u2026</string>
|
||||||
<!-- NEW: <string name="account_setup_check_settings_authenticate">Authenticating\u2026</string>-->
|
<string name="account_setup_check_settings_authenticate">Authenticatie\u2026</string>
|
||||||
<!-- NEW: <string name="account_setup_check_settings_fetch">Fetching account settings\u2026</string>-->
|
<string name="account_setup_check_settings_fetch">Accountinstellingen worden opgehaald\u2026</string>
|
||||||
<string name="account_setup_check_settings_finishing_msg">Afronden\u2026</string>
|
<string name="account_setup_check_settings_finishing_msg">Afronden\u2026</string>
|
||||||
<string name="account_setup_check_settings_canceling_msg">Annuleren\u2026</string>
|
<string name="account_setup_check_settings_canceling_msg">Annuleren\u2026</string>
|
||||||
|
|
||||||
@ -417,10 +417,10 @@ Welkom bij K-9 Mail setup. K-9 is een open source mail cliënt voor Android, ge
|
|||||||
<string name="account_setup_incoming_save_all_headers_title">Downloaden van email headers</string>
|
<string name="account_setup_incoming_save_all_headers_title">Downloaden van email headers</string>
|
||||||
<string name="account_setup_incoming_save_all_headers_label">Sla alle headers lokaal op</string>
|
<string name="account_setup_incoming_save_all_headers_label">Sla alle headers lokaal op</string>
|
||||||
|
|
||||||
<!-- NEW: <string name="local_storage_provider_external_label">External storage (SD card)</string>-->
|
<string name="local_storage_provider_external_label">Externe opslag (SD kaart)</string>
|
||||||
<!-- NEW: <string name="local_storage_provider_internal_label">Regular internal storage</string>-->
|
<string name="local_storage_provider_internal_label">Reguliere interne opslag</string>
|
||||||
<!-- NEW: <string name="local_storage_provider_samsunggalaxy_label">%1$s additional internal storage</string>-->
|
<string name="local_storage_provider_samsunggalaxy_label">%1$s extra interne opslag</string>
|
||||||
<!-- NEW: <string name="local_storage_provider_label">Storage location</string>-->
|
<string name="local_storage_provider_label">Opslag locatie</string>
|
||||||
|
|
||||||
<string name="account_setup_expunge_policy_label">Wissen berichten</string>
|
<string name="account_setup_expunge_policy_label">Wissen berichten</string>
|
||||||
<string name="account_setup_expunge_policy_immediately">Onmiddellijk na verwijderen of verplaatsen</string>
|
<string name="account_setup_expunge_policy_immediately">Onmiddellijk na verwijderen of verplaatsen</string>
|
||||||
@ -517,7 +517,7 @@ Welkom bij K-9 Mail setup. K-9 is een open source mail cliënt voor Android, ge
|
|||||||
<string name="account_setup_options_mail_display_count_250">250 berichten</string>
|
<string name="account_setup_options_mail_display_count_250">250 berichten</string>
|
||||||
<string name="account_setup_options_mail_display_count_500">500 berichten</string>
|
<string name="account_setup_options_mail_display_count_500">500 berichten</string>
|
||||||
<string name="account_setup_options_mail_display_count_1000">1000 berichten</string>
|
<string name="account_setup_options_mail_display_count_1000">1000 berichten</string>
|
||||||
<!-- NEW: <string name="account_setup_options_mail_display_count_all">all messages</string>-->
|
<string name="account_setup_options_mail_display_count_all">alle berichten</string>
|
||||||
|
|
||||||
|
|
||||||
<string name="move_copy_cannot_copy_unsynced_message">Kan bericht niet kopiëren of verplaatsen omdat deze niet gesynchroniseerd is met de server</string>
|
<string name="move_copy_cannot_copy_unsynced_message">Kan bericht niet kopiëren of verplaatsen omdat deze niet gesynchroniseerd is met de server</string>
|
||||||
@ -529,7 +529,7 @@ Welkom bij K-9 Mail setup. K-9 is een open source mail cliënt voor Android, ge
|
|||||||
<string name="account_setup_failed_dlg_edit_details_action">Aanpassen details</string>
|
<string name="account_setup_failed_dlg_edit_details_action">Aanpassen details</string>
|
||||||
<string name="account_setup_failed_dlg_continue_action">Doorgaan</string>
|
<string name="account_setup_failed_dlg_continue_action">Doorgaan</string>
|
||||||
|
|
||||||
<!-- NEW: <string name="account_settings_push_advanced_title">Advanced</string>-->
|
<string name="account_settings_push_advanced_title">Geavanceerd</string>
|
||||||
<string name="account_settings_title_fmt">Algemene instellingen</string>
|
<string name="account_settings_title_fmt">Algemene instellingen</string>
|
||||||
<string name="account_settings_default">Standaard account</string>
|
<string name="account_settings_default">Standaard account</string>
|
||||||
<string name="account_settings_default_label">Standaard account</string>
|
<string name="account_settings_default_label">Standaard account</string>
|
||||||
@ -544,8 +544,8 @@ Welkom bij K-9 Mail setup. K-9 is een open source mail cliënt voor Android, ge
|
|||||||
<string name="account_settings_notify_self_summary">Notificatie ook voor mail verzonden vanaf een identiteit</string>
|
<string name="account_settings_notify_self_summary">Notificatie ook voor mail verzonden vanaf een identiteit</string>
|
||||||
<string name="account_settings_notification_opens_unread_label">Notificatie opent ongelezen berichten</string>
|
<string name="account_settings_notification_opens_unread_label">Notificatie opent ongelezen berichten</string>
|
||||||
<string name="account_settings_notification_opens_unread_summary">Zoekt voor ongelezen berichten wanneer Notificatie is geopend</string>
|
<string name="account_settings_notification_opens_unread_summary">Zoekt voor ongelezen berichten wanneer Notificatie is geopend</string>
|
||||||
<!-- NEW: <string name="account_settings_notification_unread_count_label">Show unread count</string>-->
|
<string name="account_settings_notification_unread_count_label">Toon aantal ongelezen</string>
|
||||||
<!-- NEW: <string name="account_settings_notification_unread_count_summary">Show the number of unread messages in the notification bar.</string>-->
|
<string name="account_settings_notification_unread_count_summary">Toon het aantal ongelezen berichten in de \'notification bar\'.</string>
|
||||||
|
|
||||||
<string name="account_settings_hide_buttons_label">Scroll navigatie knoppen</string>
|
<string name="account_settings_hide_buttons_label">Scroll navigatie knoppen</string>
|
||||||
<string name="account_settings_hide_buttons_never">Nooit</string>
|
<string name="account_settings_hide_buttons_never">Nooit</string>
|
||||||
@ -566,16 +566,16 @@ Welkom bij K-9 Mail setup. K-9 is een open source mail cliënt voor Android, ge
|
|||||||
<string name="account_settings_reply_after_quote_label">Antwoorden na quote</string>
|
<string name="account_settings_reply_after_quote_label">Antwoorden na quote</string>
|
||||||
<string name="account_settings_reply_after_quote_summary">Wanneer u antwoord op berichten, zal het originele bericht boven uw antwoord staan.</string>
|
<string name="account_settings_reply_after_quote_summary">Wanneer u antwoord op berichten, zal het originele bericht boven uw antwoord staan.</string>
|
||||||
|
|
||||||
<!-- NEW: <string name="account_settings_message_format_label">Message Format</string>-->
|
<string name="account_settings_message_format_label">Berichtopmaak</string>
|
||||||
<!-- NEW: <string name="account_settings_message_format_text">Plain Text (images and formatting will be removed)</string>-->
|
<string name="account_settings_message_format_text">Platte Tekst (plaatjes en formattering worden verwijderd)</string>
|
||||||
<!-- NEW: <string name="account_settings_message_format_html">HTML (images and formatting are preserved)</string>-->
|
<string name="account_settings_message_format_html">HTML (plaatjes en formattering blijven behouden)</string>
|
||||||
|
|
||||||
<!-- NEW: <string name="account_settings_quote_style_label">Reply quoting style</string>-->
|
<string name="account_settings_quote_style_label">Quotestijl bij antwoorden</string>
|
||||||
<!-- NEW: <string name="account_settings_quote_style_prefix">Prefix (like Gmail, Pine)</string>-->
|
<string name="account_settings_quote_style_prefix">Prefix (zoals Gmail, Pine)</string>
|
||||||
<!-- NEW: <string name="account_settings_quote_style_header">Header (like Outlook, Yahoo!, Hotmail)</string>-->
|
<string name="account_settings_quote_style_header">Header (zoals Outlook, Yahoo!, Hotmail)</string>
|
||||||
|
|
||||||
<!-- NEW: <string name="account_settings_general_title">General settings</string>-->
|
<string name="account_settings_general_title">Algemeen</string>
|
||||||
<!-- NEW: <string name="account_settings_display_prefs_title">Display</string>-->
|
<string name="account_settings_display_prefs_title">Scherm</string>
|
||||||
<string name="account_settings_sync">Synchroniseren van mappen</string>
|
<string name="account_settings_sync">Synchroniseren van mappen</string>
|
||||||
<string name="account_settings_folders">Mappen</string>
|
<string name="account_settings_folders">Mappen</string>
|
||||||
<string name="account_settings_message_lists">Lijst berichten</string>
|
<string name="account_settings_message_lists">Lijst berichten</string>
|
||||||
@ -591,7 +591,7 @@ Welkom bij K-9 Mail setup. K-9 is een open source mail cliënt voor Android, ge
|
|||||||
<string name="account_settings_mail_check_frequency_label">Mappen poll controleer frequentie</string>
|
<string name="account_settings_mail_check_frequency_label">Mappen poll controleer frequentie</string>
|
||||||
<string name="account_settings_second_class_check_frequency_label">2e klasse controleer frequentie</string>
|
<string name="account_settings_second_class_check_frequency_label">2e klasse controleer frequentie</string>
|
||||||
|
|
||||||
<!-- NEW: <string name="account_settings_storage_title">Storage</string>-->
|
<string name="account_settings_storage_title">Opslag</string>
|
||||||
|
|
||||||
|
|
||||||
<string name="account_settings_color_label">Account kleur</string>
|
<string name="account_settings_color_label">Account kleur</string>
|
||||||
@ -752,7 +752,7 @@ Welkom bij K-9 Mail setup. K-9 is een open source mail cliënt voor Android, ge
|
|||||||
<string name="choose_identity">Kies identiteit</string>
|
<string name="choose_identity">Kies identiteit</string>
|
||||||
<string name="choose_identity_title">Kies identiteit</string>
|
<string name="choose_identity_title">Kies identiteit</string>
|
||||||
<string name="choose_account_title">Kies account/identiteit</string>
|
<string name="choose_account_title">Kies account/identiteit</string>
|
||||||
<!-- NEW: <string name="send_as">Send as</string>-->
|
<string name="send_as">Verzenden als</string>
|
||||||
|
|
||||||
|
|
||||||
<string name="no_identities">Ga naar Account Instellingen -> Beheer identiteiten om identiteiten aan te maken</string>
|
<string name="no_identities">Ga naar Account Instellingen -> Beheer identiteiten om identiteiten aan te maken</string>
|
||||||
@ -794,7 +794,7 @@ Welkom bij K-9 Mail setup. K-9 is een open source mail cliënt voor Android, ge
|
|||||||
<string name="provider_note_live">Alleen sommige \"Plus\" accounts staan POP access
|
<string name="provider_note_live">Alleen sommige \"Plus\" accounts staan POP access
|
||||||
toe om verbinding te krijgen met dit programma. Als het niet mogelijk is om in te loggen met de juiste gebruikersnaam en wachtwoord, heb je misschien geen betaalde \"Plus\" account. Start de webbrowser om de toegang tot deze e-mailaccount te krijgen.</string>
|
toe om verbinding te krijgen met dit programma. Als het niet mogelijk is om in te loggen met de juiste gebruikersnaam en wachtwoord, heb je misschien geen betaalde \"Plus\" account. Start de webbrowser om de toegang tot deze e-mailaccount te krijgen.</string>
|
||||||
|
|
||||||
<!-- NEW: <string name="provider_note_yahoojp">If you would like to use POP3 for this provider, You should permit to use POP3 on Yahoo mail settings page.</string>-->
|
<string name="provider_note_yahoojp">Als je POP3 wilt gebruiken, moet je het geebruik van POP3 activeren op de Yahoo mail settings pagina.</string>
|
||||||
|
|
||||||
<string name="account_setup_failed_dlg_invalid_certificate_title">Onbekend Certificaat</string>
|
<string name="account_setup_failed_dlg_invalid_certificate_title">Onbekend Certificaat</string>
|
||||||
<string name="account_setup_failed_dlg_invalid_certificate_accept">Accepteer Sleutel</string>
|
<string name="account_setup_failed_dlg_invalid_certificate_accept">Accepteer Sleutel</string>
|
||||||
@ -831,21 +831,21 @@ Welkom bij K-9 Mail setup. K-9 is een open source mail cliënt voor Android, ge
|
|||||||
<string name="setting_theme_dark">Donker</string>
|
<string name="setting_theme_dark">Donker</string>
|
||||||
<string name="setting_theme_light">Licht</string>
|
<string name="setting_theme_light">Licht</string>
|
||||||
<string name="display_preferences">Algemene instellingen</string>
|
<string name="display_preferences">Algemene instellingen</string>
|
||||||
<!-- NEW: <string name="global_preferences">Global</string>-->
|
<string name="global_preferences">Globaal</string>
|
||||||
<string name="debug_preferences">Verwijderen van fouten</string>
|
<string name="debug_preferences">Verwijderen van fouten</string>
|
||||||
<!-- NEW: <string name="privacy_preferences">Privacy</string>-->
|
<string name="privacy_preferences">Privacy</string>
|
||||||
<!-- NEW: <string name="network_preferences">Network</string>-->
|
<string name="network_preferences">Netwerk</string>
|
||||||
<!-- NEW: <string name="interaction_preferences">Interaction</string>-->
|
<string name="interaction_preferences">Interactie</string>
|
||||||
<string name="accountlist_preferences">Account Lijst</string>
|
<string name="accountlist_preferences">Account Lijst</string>
|
||||||
<string name="messagelist_preferences">Berichten Lijst</string>
|
<string name="messagelist_preferences">Berichten Lijst</string>
|
||||||
<string name="messageview_preferences">Berichten</string>
|
<string name="messageview_preferences">Berichten</string>
|
||||||
<string name="settings_theme_label">Thema</string>
|
<string name="settings_theme_label">Thema</string>
|
||||||
<string name="settings_language_label">Taal</string>
|
<string name="settings_language_label">Taal</string>
|
||||||
|
|
||||||
<!-- NEW: <string name="settings_messageview_mobile_layout_label">Single-column layout</string>-->
|
<string name="settings_messageview_mobile_layout_label">1-kolom layout</string>
|
||||||
<!-- NEW: <string name="settings_messageview_mobile_layout_summary">Reformat HTML messages for smaller screens</string>-->
|
<string name="settings_messageview_mobile_layout_summary">Herschik HTML berichten voor kleinere schermen</string>
|
||||||
<!-- NEW: <string name="settings_messageview_zoom_controls_label">System zoom controls</string>-->
|
<string name="settings_messageview_zoom_controls_label">Apparaat zoom</string>
|
||||||
<!-- NEW: <string name="settings_messageview_zoom_controls_summary">Enable zoom widgets or pinch-zoom if your device supports it</string>-->
|
<string name="settings_messageview_zoom_controls_summary">Gebruik zoom widgets of pinch-zoom als het apparaat dat ondersteunt</string>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -899,8 +899,8 @@ Welkom bij K-9 Mail setup. K-9 is een open source mail cliënt voor Android, ge
|
|||||||
<string name="gestures_title">Gebaren</string>
|
<string name="gestures_title">Gebaren</string>
|
||||||
<string name="gestures_summary">Accepteer gebaren sturing</string>
|
<string name="gestures_summary">Accepteer gebaren sturing</string>
|
||||||
|
|
||||||
<!-- NEW: <string name="compact_layouts_title">Compact layouts</string>-->
|
<string name="compact_layouts_title">Compacte layout</string>
|
||||||
<!-- NEW: <string name="compact_layouts_summary">Adjust layouts to display more on each page</string>-->
|
<string name="compact_layouts_summary">Pas layout aan zodat er meer op een pagina past</string>
|
||||||
|
|
||||||
<string name="volume_navigation_title">Volume op/neer navigatie</string>
|
<string name="volume_navigation_title">Volume op/neer navigatie</string>
|
||||||
<string name="volume_navigation_summary">Spring tussen items door gebruik van de volumeknoppen</string>
|
<string name="volume_navigation_summary">Spring tussen items door gebruik van de volumeknoppen</string>
|
||||||
@ -919,8 +919,8 @@ Welkom bij K-9 Mail setup. K-9 is een open source mail cliënt voor Android, ge
|
|||||||
<string name="count_search_title">Tel zoek resultaten</string>
|
<string name="count_search_title">Tel zoek resultaten</string>
|
||||||
<string name="count_search_summary">Zet uit voor sneller beeldscherm</string>
|
<string name="count_search_summary">Zet uit voor sneller beeldscherm</string>
|
||||||
|
|
||||||
<!-- NEW: <string name="hide_special_accounts_title">Hide special accounts</string>-->
|
<string name="hide_special_accounts_title">Verberg speciale accounts</string>
|
||||||
<!-- NEW: <string name="hide_special_accounts_summary">Hide the unified inbox and all messages accounts</string>-->
|
<string name="hide_special_accounts_summary">Verberg de gecombineerde inbox and alle berichtaccounts</string>
|
||||||
|
|
||||||
<string name="search_title"><xliff:g id="search_name">%s</xliff:g> <xliff:g id="modifier">%s</xliff:g></string>
|
<string name="search_title"><xliff:g id="search_name">%s</xliff:g> <xliff:g id="modifier">%s</xliff:g></string>
|
||||||
<string name="flagged_modifier"> - Starred</string>
|
<string name="flagged_modifier"> - Starred</string>
|
||||||
@ -960,7 +960,7 @@ Welkom bij K-9 Mail setup. K-9 is een open source mail cliënt voor Android, ge
|
|||||||
<string name="font_size_message_list_subject">Bericht onderwerp</string>
|
<string name="font_size_message_list_subject">Bericht onderwerp</string>
|
||||||
<string name="font_size_message_list_sender">bericht afzender</string>
|
<string name="font_size_message_list_sender">bericht afzender</string>
|
||||||
<string name="font_size_message_list_date">Bericht datum</string>
|
<string name="font_size_message_list_date">Bericht datum</string>
|
||||||
<!-- NEW: <string name="font_size_message_list_preview">Preview</string>-->
|
<string name="font_size_message_list_preview">Preview</string>
|
||||||
|
|
||||||
<string name="font_size_message_view">Beeld berichten</string>
|
<string name="font_size_message_view">Beeld berichten</string>
|
||||||
<string name="font_size_message_view_sender">bericht afzender</string>
|
<string name="font_size_message_view_sender">bericht afzender</string>
|
||||||
@ -1022,19 +1022,22 @@ Welkom bij K-9 Mail setup. K-9 is een open source mail cliënt voor Android, ge
|
|||||||
<string name="dialog_confirm_delete_confirm_button">Verwijder</string>
|
<string name="dialog_confirm_delete_confirm_button">Verwijder</string>
|
||||||
<string name="dialog_confirm_delete_cancel_button">Niet verwijderen</string>
|
<string name="dialog_confirm_delete_cancel_button">Niet verwijderen</string>
|
||||||
|
|
||||||
<!-- NEW: <string name="dialog_confirm_spam_title">Confirm move to spam folder</string>-->
|
<string name="dialog_confirm_spam_title">Bevestig verplaatsing naar spam map</string>
|
||||||
<!-- NEW: <string name="dialog_confirm_spam_message">Do you really want to move this message to the spam folder?</string>-->
|
<string name="dialog_confirm_spam_message">Wil je dit bericht echt verplaatsen naar de spam map?</string>
|
||||||
<!-- NEW: <string name="dialog_confirm_spam_confirm_button">Yes</string>-->
|
<string name="dialog_confirm_spam_confirm_button">Ja</string>
|
||||||
<!-- NEW: <string name="dialog_confirm_spam_cancel_button">No</string>-->
|
<string name="dialog_confirm_spam_cancel_button">Nee</string>
|
||||||
|
|
||||||
<!-- NEW: <string name="dialog_attachment_progress_title">Downloading attachment</string>-->
|
<string name="dialog_attachment_progress_title">Bijlage wordt opgehaald</string>
|
||||||
|
|
||||||
<string name="debug_logging_enabled">Debug logging van Android logging systeem ingeschakeld</string>
|
<string name="debug_logging_enabled">Debug logging van Android logging systeem ingeschakeld</string>
|
||||||
|
|
||||||
<!-- NEW: <string name="messagelist_sent_to_me_sigil">»</string>-->
|
<string name="messagelist_sent_to_me_sigil">»</string> <!-- why is this language dependent? -->
|
||||||
<!-- NEW: <string name="messagelist_sent_cc_me_sigil">›</string>-->
|
<string name="messagelist_sent_cc_me_sigil">›</string>
|
||||||
<!-- NEW: <string name="error_unable_to_connect">Unable to connect.</string>-->
|
<string name="error_unable_to_connect">Kan geen verbinding maken.</string>
|
||||||
|
|
||||||
<!-- NEW: <string name="account_unavailable">Account \"<xliff:g id="account">%s</xliff:g>\" is unavailable; check storage</string>-->
|
<string name="account_unavailable">Account \"<xliff:g id="account">%s</xliff:g>\" is niet beschikbaar; controleer opslag</string>
|
||||||
|
|
||||||
|
<string name="settings_attachment_default_path">Sla bijlagen op naar...</string>
|
||||||
|
<string name="attachment_save_title">Sla bijlage op</string>
|
||||||
|
<string name="attachment_save_desc">Geen bestandsverkenner gevonden. Waar wil je deze bijlage opslaan?</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -1049,4 +1049,7 @@ Witaj w K-9 Mail, darmowym programie pocztowym dla systemu Android. Najistotniej
|
|||||||
|
|
||||||
<string name="account_unavailable">Konto \"<xliff:g id="account">%s</xliff:g>\" jest niedostępne; sprawdź pamięc</string>
|
<string name="account_unavailable">Konto \"<xliff:g id="account">%s</xliff:g>\" jest niedostępne; sprawdź pamięc</string>
|
||||||
|
|
||||||
|
<!-- NEW: <string name="settings_attachment_default_path">Save attachments to...</string>-->
|
||||||
|
<!-- NEW: <string name="attachment_save_title">Save attachment</string>-->
|
||||||
|
<!-- NEW: <string name="attachment_save_desc">No file browser found. Where would you like to save this attachment?</string>-->
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -1034,4 +1034,7 @@ Bem-vindo à configuração do K-9 Mail. K-9 é um cliente de e-mail com código
|
|||||||
|
|
||||||
<!-- NEW: <string name="account_unavailable">Account \"<xliff:g id="account">%s</xliff:g>\" is unavailable; check storage</string>-->
|
<!-- NEW: <string name="account_unavailable">Account \"<xliff:g id="account">%s</xliff:g>\" is unavailable; check storage</string>-->
|
||||||
|
|
||||||
|
<!-- NEW: <string name="settings_attachment_default_path">Save attachments to...</string>-->
|
||||||
|
<!-- NEW: <string name="attachment_save_title">Save attachment</string>-->
|
||||||
|
<!-- NEW: <string name="attachment_save_desc">No file browser found. Where would you like to save this attachment?</string>-->
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -1031,4 +1031,7 @@
|
|||||||
|
|
||||||
<!-- NEW: <string name="account_unavailable">Account \"<xliff:g id="account">%s</xliff:g>\" is unavailable; check storage</string>-->
|
<!-- NEW: <string name="account_unavailable">Account \"<xliff:g id="account">%s</xliff:g>\" is unavailable; check storage</string>-->
|
||||||
|
|
||||||
|
<!-- NEW: <string name="settings_attachment_default_path">Save attachments to...</string>-->
|
||||||
|
<!-- NEW: <string name="attachment_save_title">Save attachment</string>-->
|
||||||
|
<!-- NEW: <string name="attachment_save_desc">No file browser found. Where would you like to save this attachment?</string>-->
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -1040,4 +1040,7 @@ Välkommen till installationen av K-9 E-post. K-9 är en e-postklient med öppen
|
|||||||
|
|
||||||
<!-- NEW: <string name="account_unavailable">Account \"<xliff:g id="account">%s</xliff:g>\" is unavailable; check storage</string>-->
|
<!-- NEW: <string name="account_unavailable">Account \"<xliff:g id="account">%s</xliff:g>\" is unavailable; check storage</string>-->
|
||||||
|
|
||||||
|
<!-- NEW: <string name="settings_attachment_default_path">Save attachments to...</string>-->
|
||||||
|
<!-- NEW: <string name="attachment_save_title">Save attachment</string>-->
|
||||||
|
<!-- NEW: <string name="attachment_save_desc">No file browser found. Where would you like to save this attachment?</string>-->
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -1021,4 +1021,7 @@
|
|||||||
|
|
||||||
<!-- NEW: <string name="account_unavailable">Account \"<xliff:g id="account">%s</xliff:g>\" is unavailable; check storage</string>-->
|
<!-- NEW: <string name="account_unavailable">Account \"<xliff:g id="account">%s</xliff:g>\" is unavailable; check storage</string>-->
|
||||||
|
|
||||||
|
<!-- NEW: <string name="settings_attachment_default_path">Save attachments to...</string>-->
|
||||||
|
<!-- NEW: <string name="attachment_save_title">Save attachment</string>-->
|
||||||
|
<!-- NEW: <string name="attachment_save_desc">No file browser found. Where would you like to save this attachment?</string>-->
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -501,6 +501,7 @@
|
|||||||
<item>zh_CN</item>
|
<item>zh_CN</item>
|
||||||
<item>fi</item>
|
<item>fi</item>
|
||||||
<item>sv</item>
|
<item>sv</item>
|
||||||
|
<item>ko</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
<string-array name="settings_theme_entries">
|
<string-array name="settings_theme_entries">
|
||||||
|
@ -270,7 +270,7 @@ Welcome to K-9 Mail setup. K-9 is an open source mail client for Android origin
|
|||||||
<string name="error_contact_address_not_found">No email address could be found.</string>
|
<string name="error_contact_address_not_found">No email address could be found.</string>
|
||||||
<string name="message_compose_downloading_attachments_toast">Some attachments were not downloaded. They will be downloaded automatically before this message is sent.</string>
|
<string name="message_compose_downloading_attachments_toast">Some attachments were not downloaded. They will be downloaded automatically before this message is sent.</string>
|
||||||
<string name="message_compose_attachments_skipped_toast">Some attachments cannot be forwarded because they have not been downloaded.</string>
|
<string name="message_compose_attachments_skipped_toast">Some attachments cannot be forwarded because they have not been downloaded.</string>
|
||||||
|
<string name="message_compose_show_quoted_text_action">Quote message</string>
|
||||||
|
|
||||||
|
|
||||||
<string name="message_view_from_format">From: <xliff:g id="name">%s</xliff:g> <<xliff:g id="email">%s</xliff:g>></string>
|
<string name="message_view_from_format">From: <xliff:g id="name">%s</xliff:g> <<xliff:g id="email">%s</xliff:g>></string>
|
||||||
@ -564,6 +564,9 @@ Welcome to K-9 Mail setup. K-9 is an open source mail client for Android origin
|
|||||||
|
|
||||||
<string name="account_settings_composition">Sending mail</string>
|
<string name="account_settings_composition">Sending mail</string>
|
||||||
|
|
||||||
|
<string name="account_settings_default_quoted_text_shown_label">Quote original message when replying</string>
|
||||||
|
<string name="account_settings_default_quoted_text_shown_summary">When replying to messages, the original message is in your reply.</string>
|
||||||
|
|
||||||
<string name="account_settings_reply_after_quote_label">Reply after quoted text</string>
|
<string name="account_settings_reply_after_quote_label">Reply after quoted text</string>
|
||||||
<string name="account_settings_reply_after_quote_summary">When replying to messages, the original message will appear above your reply.</string>
|
<string name="account_settings_reply_after_quote_summary">When replying to messages, the original message will appear above your reply.</string>
|
||||||
|
|
||||||
@ -800,6 +803,11 @@ Welcome to K-9 Mail setup. K-9 is an open source mail client for Android origin
|
|||||||
|
|
||||||
<string name="provider_note_yahoojp">If you would like to use POP3 for this provider, You should permit to use POP3 on Yahoo mail settings page.</string>
|
<string name="provider_note_yahoojp">If you would like to use POP3 for this provider, You should permit to use POP3 on Yahoo mail settings page.</string>
|
||||||
|
|
||||||
|
<string name="provider_note_naver">If you would like to use IMAP or POP3 for this provider, You should permit to use IMAP or POP3 on Naver mail settings page.</string>
|
||||||
|
<string name="provider_note_hanmail">If you would like to use IMAP or POP3 for this provider, You should permit to use IMAP or POP3 on Hanmail(Daum) mail settings page.</string>
|
||||||
|
<string name="provider_note_paran">If you would like to use IMAP or POP3 for this provider, You should permit to use IMAP or POP3 on Paran mail settings page.</string>
|
||||||
|
<string name="provider_note_nate">If you would like to use IMAP or POP3 for this provider, You should permit to use IMAP or POP3 on Nate mail settings page.</string>
|
||||||
|
|
||||||
<string name="account_setup_failed_dlg_invalid_certificate_title">Unrecognized Certificate</string>
|
<string name="account_setup_failed_dlg_invalid_certificate_title">Unrecognized Certificate</string>
|
||||||
<string name="account_setup_failed_dlg_invalid_certificate_accept">Accept Key</string>
|
<string name="account_setup_failed_dlg_invalid_certificate_accept">Accept Key</string>
|
||||||
<string name="account_setup_failed_dlg_invalid_certificate_reject">Reject Key</string>
|
<string name="account_setup_failed_dlg_invalid_certificate_reject">Reject Key</string>
|
||||||
@ -1041,4 +1049,8 @@ Welcome to K-9 Mail setup. K-9 is an open source mail client for Android origin
|
|||||||
|
|
||||||
<string name="account_unavailable">Account \"<xliff:g id="account">%s</xliff:g>\" is unavailable; check storage</string>
|
<string name="account_unavailable">Account \"<xliff:g id="account">%s</xliff:g>\" is unavailable; check storage</string>
|
||||||
|
|
||||||
|
<string name="settings_attachment_default_path">Save attachments to...</string>
|
||||||
|
<string name="attachment_save_title">Save attachment</string>
|
||||||
|
<string name="attachment_save_desc">No file browser found. Where would you like to save this attachment?</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -239,6 +239,13 @@
|
|||||||
android:entries="@array/account_settings_quote_style_entries"
|
android:entries="@array/account_settings_quote_style_entries"
|
||||||
android:entryValues="@array/account_settings_quote_style_values" />
|
android:entryValues="@array/account_settings_quote_style_values" />
|
||||||
|
|
||||||
|
<CheckBoxPreference
|
||||||
|
android:persistent="false"
|
||||||
|
android:key="default_quoted_text_shown"
|
||||||
|
android:title="@string/account_settings_default_quoted_text_shown_label"
|
||||||
|
android:defaultValue="true"
|
||||||
|
android:summary="@string/account_settings_default_quoted_text_shown_summary" />
|
||||||
|
|
||||||
<CheckBoxPreference
|
<CheckBoxPreference
|
||||||
android:persistent="false"
|
android:persistent="false"
|
||||||
android:key="reply_after_quote"
|
android:key="reply_after_quote"
|
||||||
|
@ -231,7 +231,6 @@
|
|||||||
android:dialogTitle="@string/global_settings_confirm_actions_title"
|
android:dialogTitle="@string/global_settings_confirm_actions_title"
|
||||||
android:positiveButtonText="@android:string/ok"
|
android:positiveButtonText="@android:string/ok"
|
||||||
android:negativeButtonText="@android:string/cancel" />
|
android:negativeButtonText="@android:string/cancel" />
|
||||||
|
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
||||||
|
|
||||||
<PreferenceScreen
|
<PreferenceScreen
|
||||||
@ -284,6 +283,11 @@
|
|||||||
android:title="@string/misc_preferences_attachment_title"
|
android:title="@string/misc_preferences_attachment_title"
|
||||||
android:summary="@string/misc_preferences_attachment_description" />
|
android:summary="@string/misc_preferences_attachment_description" />
|
||||||
|
|
||||||
|
<Preference
|
||||||
|
android:persistent="false"
|
||||||
|
android:title="@string/settings_attachment_default_path"
|
||||||
|
android:key="attachment_default_path"
|
||||||
|
android:summary="- PATH - set by activty -"/>
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
||||||
|
|
||||||
<PreferenceScreen
|
<PreferenceScreen
|
||||||
|
@ -276,6 +276,33 @@
|
|||||||
<outgoing uri="smtp://smtp.mail.yahoo.co.jp:587" username="$user" />
|
<outgoing uri="smtp://smtp.mail.yahoo.co.jp:587" username="$user" />
|
||||||
</provider>
|
</provider>
|
||||||
|
|
||||||
|
<!-- Korean -->
|
||||||
|
<provider id="naver" label="Naver" domain="naver.com"
|
||||||
|
note="@string/provider_note_naver">
|
||||||
|
<incoming uri="imap+ssl://imap.naver.com" username="$user" />
|
||||||
|
<outgoing uri="smtp+tls://smtp.naver.com:587" username="$user" />
|
||||||
|
</provider>
|
||||||
|
<provider id="hanmail" label="Hanmail" domain="hanmail.net"
|
||||||
|
note="@string/provider_note_hanmail">
|
||||||
|
<incoming uri="imap+ssl://imap.hanmail.net" username="$user" />
|
||||||
|
<outgoing uri="smtp+ssl://smtp.hanmail.net" username="$user" />
|
||||||
|
</provider>
|
||||||
|
<provider id="daum" label="Hanmail" domain="daum.net"
|
||||||
|
note="@string/provider_note_hanmail">
|
||||||
|
<incoming uri="imap+ssl://imap.hanmail.net" username="$user" />
|
||||||
|
<outgoing uri="smtp+ssl://smtp.hanmail.net" username="$user" />
|
||||||
|
</provider>
|
||||||
|
<provider id="paran" label="Paran" domain="paran.com"
|
||||||
|
note="@string/provider_note_paran">
|
||||||
|
<incoming uri="imap+ssl://imap.paran.com" username="$email" />
|
||||||
|
<outgoing uri="smtp+tls://smtp.paran.com" username="$email" />
|
||||||
|
</provider>
|
||||||
|
<provider id="nate" label="Nate" domain="nate.com"
|
||||||
|
note="@string/provider_note_nate">
|
||||||
|
<incoming uri="imap+ssl://imap.nate.com" username="$user" />
|
||||||
|
<outgoing uri="smtp+tls://smtp.mail.nate.com" username="$user" />
|
||||||
|
</provider>
|
||||||
|
|
||||||
<!-- Developers' vanity providers -->
|
<!-- Developers' vanity providers -->
|
||||||
<provider id="fsck.com" label="Jesse's personal mail" domain="fsck.com" >
|
<provider id="fsck.com" label="Jesse's personal mail" domain="fsck.com" >
|
||||||
<incoming uri="imap+ssl://fsck.com" username="$user" />
|
<incoming uri="imap+ssl://fsck.com" username="$user" />
|
||||||
|
@ -33,6 +33,16 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||||||
* and delete itself given a Preferences to work with. Each account is defined by a UUID.
|
* and delete itself given a Preferences to work with. Each account is defined by a UUID.
|
||||||
*/
|
*/
|
||||||
public class Account implements BaseAccount {
|
public class Account implements BaseAccount {
|
||||||
|
/**
|
||||||
|
* Default value for the inbox folder (never changes for POP3 and IMAP)
|
||||||
|
*/
|
||||||
|
public static final String INBOX = "INBOX";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This local folder is used to store messages to be sent.
|
||||||
|
*/
|
||||||
|
public static final String OUTBOX = "OUTBOX";
|
||||||
|
|
||||||
public static final String EXPUNGE_IMMEDIATELY = "EXPUNGE_IMMEDIATELY";
|
public static final String EXPUNGE_IMMEDIATELY = "EXPUNGE_IMMEDIATELY";
|
||||||
public static final String EXPUNGE_MANUALLY = "EXPUNGE_MANUALLY";
|
public static final String EXPUNGE_MANUALLY = "EXPUNGE_MANUALLY";
|
||||||
public static final String EXPUNGE_ON_POLL = "EXPUNGE_ON_POLL";
|
public static final String EXPUNGE_ON_POLL = "EXPUNGE_ON_POLL";
|
||||||
@ -50,6 +60,7 @@ public class Account implements BaseAccount {
|
|||||||
private static final MessageFormat DEFAULT_MESSAGE_FORMAT = MessageFormat.HTML;
|
private static final MessageFormat DEFAULT_MESSAGE_FORMAT = MessageFormat.HTML;
|
||||||
private static final QuoteStyle DEFAULT_QUOTE_STYLE = QuoteStyle.PREFIX;
|
private static final QuoteStyle DEFAULT_QUOTE_STYLE = QuoteStyle.PREFIX;
|
||||||
private static final String DEFAULT_QUOTE_PREFIX = ">";
|
private static final String DEFAULT_QUOTE_PREFIX = ">";
|
||||||
|
private static final boolean DEFAULT_QUOTED_TEXT_SHOWN = true;
|
||||||
private static final boolean DEFAULT_REPLY_AFTER_QUOTE = false;
|
private static final boolean DEFAULT_REPLY_AFTER_QUOTE = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -80,6 +91,7 @@ public class Account implements BaseAccount {
|
|||||||
private long mLatestOldMessageSeenTime;
|
private long mLatestOldMessageSeenTime;
|
||||||
private boolean mNotifyNewMail;
|
private boolean mNotifyNewMail;
|
||||||
private boolean mNotifySelfNewMail;
|
private boolean mNotifySelfNewMail;
|
||||||
|
private String mInboxFolderName;
|
||||||
private String mDraftsFolderName;
|
private String mDraftsFolderName;
|
||||||
private String mSentFolderName;
|
private String mSentFolderName;
|
||||||
private String mTrashFolderName;
|
private String mTrashFolderName;
|
||||||
@ -115,6 +127,7 @@ public class Account implements BaseAccount {
|
|||||||
private MessageFormat mMessageFormat;
|
private MessageFormat mMessageFormat;
|
||||||
private QuoteStyle mQuoteStyle;
|
private QuoteStyle mQuoteStyle;
|
||||||
private String mQuotePrefix;
|
private String mQuotePrefix;
|
||||||
|
private boolean mDefaultQuotedTextShown;
|
||||||
private boolean mReplyAfterQuote;
|
private boolean mReplyAfterQuote;
|
||||||
private boolean mSyncRemoteDeletions;
|
private boolean mSyncRemoteDeletions;
|
||||||
private String mCryptoApp;
|
private String mCryptoApp;
|
||||||
@ -180,7 +193,8 @@ public class Account implements BaseAccount {
|
|||||||
mEnableMoveButtons = false;
|
mEnableMoveButtons = false;
|
||||||
mIsSignatureBeforeQuotedText = false;
|
mIsSignatureBeforeQuotedText = false;
|
||||||
mExpungePolicy = EXPUNGE_IMMEDIATELY;
|
mExpungePolicy = EXPUNGE_IMMEDIATELY;
|
||||||
mAutoExpandFolderName = "INBOX";
|
mAutoExpandFolderName = INBOX;
|
||||||
|
mInboxFolderName = INBOX;
|
||||||
mMaxPushFolders = 10;
|
mMaxPushFolders = 10;
|
||||||
mChipColor = (new Random()).nextInt(0xffffff) + 0xff000000;
|
mChipColor = (new Random()).nextInt(0xffffff) + 0xff000000;
|
||||||
goToUnreadMessageSearch = false;
|
goToUnreadMessageSearch = false;
|
||||||
@ -191,6 +205,7 @@ public class Account implements BaseAccount {
|
|||||||
mMessageFormat = DEFAULT_MESSAGE_FORMAT;
|
mMessageFormat = DEFAULT_MESSAGE_FORMAT;
|
||||||
mQuoteStyle = DEFAULT_QUOTE_STYLE;
|
mQuoteStyle = DEFAULT_QUOTE_STYLE;
|
||||||
mQuotePrefix = DEFAULT_QUOTE_PREFIX;
|
mQuotePrefix = DEFAULT_QUOTE_PREFIX;
|
||||||
|
mDefaultQuotedTextShown = DEFAULT_QUOTED_TEXT_SHOWN;
|
||||||
mReplyAfterQuote = DEFAULT_REPLY_AFTER_QUOTE;
|
mReplyAfterQuote = DEFAULT_REPLY_AFTER_QUOTE;
|
||||||
mSyncRemoteDeletions = true;
|
mSyncRemoteDeletions = true;
|
||||||
mCryptoApp = Apg.NAME;
|
mCryptoApp = Apg.NAME;
|
||||||
@ -246,6 +261,7 @@ public class Account implements BaseAccount {
|
|||||||
mNotifySelfNewMail = prefs.getBoolean(mUuid + ".notifySelfNewMail", true);
|
mNotifySelfNewMail = prefs.getBoolean(mUuid + ".notifySelfNewMail", true);
|
||||||
mNotifySync = prefs.getBoolean(mUuid + ".notifyMailCheck", false);
|
mNotifySync = prefs.getBoolean(mUuid + ".notifyMailCheck", false);
|
||||||
mDeletePolicy = prefs.getInt(mUuid + ".deletePolicy", 0);
|
mDeletePolicy = prefs.getInt(mUuid + ".deletePolicy", 0);
|
||||||
|
mInboxFolderName = prefs.getString(mUuid + ".inboxFolderName", INBOX);
|
||||||
mDraftsFolderName = prefs.getString(mUuid + ".draftsFolderName", "Drafts");
|
mDraftsFolderName = prefs.getString(mUuid + ".draftsFolderName", "Drafts");
|
||||||
mSentFolderName = prefs.getString(mUuid + ".sentFolderName", "Sent");
|
mSentFolderName = prefs.getString(mUuid + ".sentFolderName", "Sent");
|
||||||
mTrashFolderName = prefs.getString(mUuid + ".trashFolderName", "Trash");
|
mTrashFolderName = prefs.getString(mUuid + ".trashFolderName", "Trash");
|
||||||
@ -263,6 +279,7 @@ public class Account implements BaseAccount {
|
|||||||
mMessageFormat = MessageFormat.valueOf(prefs.getString(mUuid + ".messageFormat", DEFAULT_MESSAGE_FORMAT.name()));
|
mMessageFormat = MessageFormat.valueOf(prefs.getString(mUuid + ".messageFormat", DEFAULT_MESSAGE_FORMAT.name()));
|
||||||
mQuoteStyle = QuoteStyle.valueOf(prefs.getString(mUuid + ".quoteStyle", DEFAULT_QUOTE_STYLE.name()));
|
mQuoteStyle = QuoteStyle.valueOf(prefs.getString(mUuid + ".quoteStyle", DEFAULT_QUOTE_STYLE.name()));
|
||||||
mQuotePrefix = prefs.getString(mUuid + ".quotePrefix", DEFAULT_QUOTE_PREFIX);
|
mQuotePrefix = prefs.getString(mUuid + ".quotePrefix", DEFAULT_QUOTE_PREFIX);
|
||||||
|
mDefaultQuotedTextShown = prefs.getBoolean(mUuid + ".defaultQuotedTextShown", DEFAULT_QUOTED_TEXT_SHOWN);
|
||||||
mReplyAfterQuote = prefs.getBoolean(mUuid + ".replyAfterQuote", DEFAULT_REPLY_AFTER_QUOTE);
|
mReplyAfterQuote = prefs.getBoolean(mUuid + ".replyAfterQuote", DEFAULT_REPLY_AFTER_QUOTE);
|
||||||
for (String type : networkTypes) {
|
for (String type : networkTypes) {
|
||||||
Boolean useCompression = prefs.getBoolean(mUuid + ".useCompression." + type,
|
Boolean useCompression = prefs.getBoolean(mUuid + ".useCompression." + type,
|
||||||
@ -270,8 +287,7 @@ public class Account implements BaseAccount {
|
|||||||
compressionMap.put(type, useCompression);
|
compressionMap.put(type, useCompression);
|
||||||
}
|
}
|
||||||
|
|
||||||
mAutoExpandFolderName = prefs.getString(mUuid + ".autoExpandFolderName",
|
mAutoExpandFolderName = prefs.getString(mUuid + ".autoExpandFolderName", INBOX);
|
||||||
"INBOX");
|
|
||||||
|
|
||||||
mAccountNumber = prefs.getInt(mUuid + ".accountNumber", 0);
|
mAccountNumber = prefs.getInt(mUuid + ".accountNumber", 0);
|
||||||
|
|
||||||
@ -485,6 +501,7 @@ public class Account implements BaseAccount {
|
|||||||
editor.putBoolean(mUuid + ".notifySelfNewMail", mNotifySelfNewMail);
|
editor.putBoolean(mUuid + ".notifySelfNewMail", mNotifySelfNewMail);
|
||||||
editor.putBoolean(mUuid + ".notifyMailCheck", mNotifySync);
|
editor.putBoolean(mUuid + ".notifyMailCheck", mNotifySync);
|
||||||
editor.putInt(mUuid + ".deletePolicy", mDeletePolicy);
|
editor.putInt(mUuid + ".deletePolicy", mDeletePolicy);
|
||||||
|
editor.putString(mUuid + ".inboxFolderName", mInboxFolderName);
|
||||||
editor.putString(mUuid + ".draftsFolderName", mDraftsFolderName);
|
editor.putString(mUuid + ".draftsFolderName", mDraftsFolderName);
|
||||||
editor.putString(mUuid + ".sentFolderName", mSentFolderName);
|
editor.putString(mUuid + ".sentFolderName", mSentFolderName);
|
||||||
editor.putString(mUuid + ".trashFolderName", mTrashFolderName);
|
editor.putString(mUuid + ".trashFolderName", mTrashFolderName);
|
||||||
@ -514,6 +531,7 @@ public class Account implements BaseAccount {
|
|||||||
editor.putString(mUuid + ".messageFormat", mMessageFormat.name());
|
editor.putString(mUuid + ".messageFormat", mMessageFormat.name());
|
||||||
editor.putString(mUuid + ".quoteStyle", mQuoteStyle.name());
|
editor.putString(mUuid + ".quoteStyle", mQuoteStyle.name());
|
||||||
editor.putString(mUuid + ".quotePrefix", mQuotePrefix);
|
editor.putString(mUuid + ".quotePrefix", mQuotePrefix);
|
||||||
|
editor.putBoolean(mUuid + ".defaultQuotedTextShown", mDefaultQuotedTextShown);
|
||||||
editor.putBoolean(mUuid + ".replyAfterQuote", mReplyAfterQuote);
|
editor.putBoolean(mUuid + ".replyAfterQuote", mReplyAfterQuote);
|
||||||
editor.putString(mUuid + ".cryptoApp", mCryptoApp);
|
editor.putString(mUuid + ".cryptoApp", mCryptoApp);
|
||||||
editor.putBoolean(mUuid + ".cryptoAutoSignature", mCryptoAutoSignature);
|
editor.putBoolean(mUuid + ".cryptoAutoSignature", mCryptoAutoSignature);
|
||||||
@ -762,7 +780,7 @@ public class Account implements BaseAccount {
|
|||||||
|
|
||||||
|
|
||||||
public boolean isSpecialFolder(String folderName) {
|
public boolean isSpecialFolder(String folderName) {
|
||||||
if (folderName != null && (folderName.equalsIgnoreCase(K9.INBOX) ||
|
if (folderName != null && (folderName.equalsIgnoreCase(getInboxFolderName()) ||
|
||||||
folderName.equals(getTrashFolderName()) ||
|
folderName.equals(getTrashFolderName()) ||
|
||||||
folderName.equals(getDraftsFolderName()) ||
|
folderName.equals(getDraftsFolderName()) ||
|
||||||
folderName.equals(getArchiveFolderName()) ||
|
folderName.equals(getArchiveFolderName()) ||
|
||||||
@ -824,7 +842,7 @@ public class Account implements BaseAccount {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public synchronized String getOutboxFolderName() {
|
public synchronized String getOutboxFolderName() {
|
||||||
return K9.OUTBOX;
|
return OUTBOX;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized String getAutoExpandFolderName() {
|
public synchronized String getAutoExpandFolderName() {
|
||||||
@ -1270,6 +1288,14 @@ public class Account implements BaseAccount {
|
|||||||
mQuotePrefix = quotePrefix;
|
mQuotePrefix = quotePrefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public synchronized boolean isDefaultQuotedTextShown() {
|
||||||
|
return mDefaultQuotedTextShown;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void setDefaultQuotedTextShown(boolean shown) {
|
||||||
|
mDefaultQuotedTextShown = shown;
|
||||||
|
}
|
||||||
|
|
||||||
public synchronized boolean isReplyAfterQuote() {
|
public synchronized boolean isReplyAfterQuote() {
|
||||||
return mReplyAfterQuote;
|
return mReplyAfterQuote;
|
||||||
}
|
}
|
||||||
@ -1303,6 +1329,15 @@ public class Account implements BaseAccount {
|
|||||||
public void setCryptoAutoSignature(boolean cryptoAutoSignature) {
|
public void setCryptoAutoSignature(boolean cryptoAutoSignature) {
|
||||||
mCryptoAutoSignature = cryptoAutoSignature;
|
mCryptoAutoSignature = cryptoAutoSignature;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getInboxFolderName() {
|
||||||
|
return mInboxFolderName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInboxFolderName(String mInboxFolderName) {
|
||||||
|
this.mInboxFolderName = mInboxFolderName;
|
||||||
|
}
|
||||||
|
|
||||||
public synchronized boolean syncRemoteDeletions() {
|
public synchronized boolean syncRemoteDeletions() {
|
||||||
return mSyncRemoteDeletions;
|
return mSyncRemoteDeletions;
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
package com.fsck.k9;
|
package com.fsck.k9;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -18,9 +19,11 @@ import android.content.pm.PackageInfo;
|
|||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.PackageManager.NameNotFoundException;
|
import android.content.pm.PackageManager.NameNotFoundException;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import android.os.Environment;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.text.format.Time;
|
import android.text.format.Time;
|
||||||
|
import android.text.style.AbsoluteSizeSpan;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.fsck.k9.activity.MessageCompose;
|
import com.fsck.k9.activity.MessageCompose;
|
||||||
@ -65,6 +68,10 @@ public class K9 extends Application {
|
|||||||
*/
|
*/
|
||||||
private static List<ApplicationAware> observers = new ArrayList<ApplicationAware>();
|
private static List<ApplicationAware> observers = new ArrayList<ApplicationAware>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see K9#createAbsoluteSizeSpan(int)
|
||||||
|
*/
|
||||||
|
private static Constructor<AbsoluteSizeSpan> sAbsoluteSizeSpanConstructor;
|
||||||
|
|
||||||
public enum BACKGROUND_OPS {
|
public enum BACKGROUND_OPS {
|
||||||
WHEN_CHECKED, ALWAYS, NEVER, WHEN_CHECKED_AUTO_SYNC
|
WHEN_CHECKED, ALWAYS, NEVER, WHEN_CHECKED_AUTO_SYNC
|
||||||
@ -143,7 +150,6 @@ public class K9 extends Application {
|
|||||||
public static boolean ENABLE_ERROR_FOLDER = true;
|
public static boolean ENABLE_ERROR_FOLDER = true;
|
||||||
public static String ERROR_FOLDER_NAME = "K9mail-errors";
|
public static String ERROR_FOLDER_NAME = "K9mail-errors";
|
||||||
|
|
||||||
|
|
||||||
private static boolean mAnimations = true;
|
private static boolean mAnimations = true;
|
||||||
|
|
||||||
private static boolean mConfirmDelete = false;
|
private static boolean mConfirmDelete = false;
|
||||||
@ -177,7 +183,7 @@ public class K9 extends Application {
|
|||||||
private static String mQuietTimeStarts = null;
|
private static String mQuietTimeStarts = null;
|
||||||
private static String mQuietTimeEnds = null;
|
private static String mQuietTimeEnds = null;
|
||||||
private static boolean compactLayouts = false;
|
private static boolean compactLayouts = false;
|
||||||
|
private static String mAttachmentDefaultPath = "";
|
||||||
|
|
||||||
|
|
||||||
private static boolean useGalleryBugWorkaround = false;
|
private static boolean useGalleryBugWorkaround = false;
|
||||||
@ -210,17 +216,6 @@ public class K9 extends Application {
|
|||||||
public static final String[] UNACCEPTABLE_ATTACHMENT_DOWNLOAD_TYPES = new String[] {
|
public static final String[] UNACCEPTABLE_ATTACHMENT_DOWNLOAD_TYPES = new String[] {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* The special name "INBOX" is used throughout the application to mean "Whatever folder
|
|
||||||
* the server refers to as the user's Inbox. Placed here to ease use.
|
|
||||||
*/
|
|
||||||
public static final String INBOX = "INBOX";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This local folder is used to store messages to be sent.
|
|
||||||
*/
|
|
||||||
public static final String OUTBOX = "OUTBOX";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For use when displaying that no folder is selected
|
* For use when displaying that no folder is selected
|
||||||
*/
|
*/
|
||||||
@ -452,7 +447,7 @@ public class K9 extends Application {
|
|||||||
editor.putBoolean("keyguardPrivacy", mKeyguardPrivacy);
|
editor.putBoolean("keyguardPrivacy", mKeyguardPrivacy);
|
||||||
|
|
||||||
editor.putBoolean("compactLayouts", compactLayouts);
|
editor.putBoolean("compactLayouts", compactLayouts);
|
||||||
|
editor.putString("attachmentdefaultpath", mAttachmentDefaultPath);
|
||||||
fontSizes.save(editor);
|
fontSizes.save(editor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -507,7 +502,7 @@ public class K9 extends Application {
|
|||||||
mKeyguardPrivacy = sprefs.getBoolean("keyguardPrivacy", false);
|
mKeyguardPrivacy = sprefs.getBoolean("keyguardPrivacy", false);
|
||||||
|
|
||||||
compactLayouts = sprefs.getBoolean("compactLayouts", false);
|
compactLayouts = sprefs.getBoolean("compactLayouts", false);
|
||||||
|
mAttachmentDefaultPath = sprefs.getString("attachmentdefaultpath", Environment.getExternalStorageDirectory().toString());
|
||||||
fontSizes.load(sprefs);
|
fontSizes.load(sprefs);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -995,4 +990,55 @@ public class K9 extends Application {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getAttachmentDefaultPath() {
|
||||||
|
return mAttachmentDefaultPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setAttachmentDefaultPath(String attachmentDefaultPath) {
|
||||||
|
K9.mAttachmentDefaultPath = attachmentDefaultPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an {@link AbsoluteSizeSpan} object.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Android versions prior to 2.0 don't support the constructor with two parameters
|
||||||
|
* ({@link AbsoluteSizeSpan#AbsoluteSizeSpan(int, boolean)}). So we have to perform some
|
||||||
|
* reflection magic to dynamically load the new constructor on devices that support it.
|
||||||
|
* For devices with old Android versions we just use the size as pixels (instead of dip).
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param size This is used as the {@code size} parameter for the AbsoluteSizeSpan constructor.
|
||||||
|
* @return a AbsoluteSizeSpan object with the specified text size.
|
||||||
|
*/
|
||||||
|
public static AbsoluteSizeSpan createAbsoluteSizeSpan(int size) {
|
||||||
|
if (Integer.parseInt(android.os.Build.VERSION.SDK) < 5) {
|
||||||
|
// For Android 1.5/1.6 simply use the constructor with only the size parameter.
|
||||||
|
// Yes, that will most likely look wrong!
|
||||||
|
return new AbsoluteSizeSpan(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sAbsoluteSizeSpanConstructor == null) {
|
||||||
|
try {
|
||||||
|
sAbsoluteSizeSpanConstructor = AbsoluteSizeSpan.class.getConstructor(int.class, boolean.class);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(K9.LOG_TAG, "Couldn't get the AbsoluteSizeSpan(int, boolean) constructor", e);
|
||||||
|
|
||||||
|
// Fallback
|
||||||
|
return new AbsoluteSizeSpan(size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AbsoluteSizeSpan result;
|
||||||
|
try {
|
||||||
|
result = sAbsoluteSizeSpanConstructor.newInstance(size, true);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(K9.LOG_TAG, "Couldn't call the AbsoluteSizeSpan(int, boolean) constructor", e);
|
||||||
|
|
||||||
|
// Fallback
|
||||||
|
result = new AbsoluteSizeSpan(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@ import android.content.Context;
|
|||||||
|
|
||||||
import com.fsck.k9.Account;
|
import com.fsck.k9.Account;
|
||||||
import com.fsck.k9.AccountStats;
|
import com.fsck.k9.AccountStats;
|
||||||
import com.fsck.k9.K9;
|
|
||||||
import com.fsck.k9.R;
|
import com.fsck.k9.R;
|
||||||
import com.fsck.k9.controller.MessagingListener;
|
import com.fsck.k9.controller.MessagingListener;
|
||||||
import com.fsck.k9.service.MailService;
|
import com.fsck.k9.service.MailService;
|
||||||
@ -35,7 +34,7 @@ public class ActivityListener extends MessagingListener {
|
|||||||
|
|
||||||
if (mLoadingFolderName != null || mLoadingHeaderFolderName != null) {
|
if (mLoadingFolderName != null || mLoadingHeaderFolderName != null) {
|
||||||
String displayName = mLoadingFolderName;
|
String displayName = mLoadingFolderName;
|
||||||
if (K9.INBOX.equalsIgnoreCase(displayName)) {
|
if ((mAccount != null) && (mAccount.getInboxFolderName() != null) && mAccount.getInboxFolderName().equalsIgnoreCase(displayName)) {
|
||||||
displayName = context.getString(R.string.special_mailbox_name_inbox);
|
displayName = context.getString(R.string.special_mailbox_name_inbox);
|
||||||
} else if ((mAccount != null) && mAccount.getOutboxFolderName().equals(displayName)) {
|
} else if ((mAccount != null) && mAccount.getOutboxFolderName().equals(displayName)) {
|
||||||
displayName = context.getString(R.string.special_mailbox_name_outbox);
|
displayName = context.getString(R.string.special_mailbox_name_outbox);
|
||||||
|
@ -100,6 +100,7 @@ public class ChooseFolder extends K9ListActivity {
|
|||||||
setListAdapter(mAdapter);
|
setListAdapter(mAdapter);
|
||||||
|
|
||||||
|
|
||||||
|
mMode = mAccount.getFolderTargetMode();
|
||||||
MessagingController.getInstance(getApplication()).listFolders(mAccount, false, mListener);
|
MessagingController.getInstance(getApplication()).listFolders(mAccount, false, mListener);
|
||||||
|
|
||||||
|
|
||||||
@ -248,7 +249,8 @@ public class ChooseFolder extends K9ListActivity {
|
|||||||
String name = folder.getName();
|
String name = folder.getName();
|
||||||
|
|
||||||
// Inbox needs to be compared case-insensitively
|
// Inbox needs to be compared case-insensitively
|
||||||
if (hideCurrentFolder && (name.equals(mFolder) || (K9.INBOX.equalsIgnoreCase(mFolder) && K9.INBOX.equalsIgnoreCase(name)))) {
|
if (hideCurrentFolder && (name.equals(mFolder) ||
|
||||||
|
(mAccount.getInboxFolderName().equalsIgnoreCase(mFolder) && mAccount.getInboxFolderName().equalsIgnoreCase(name)))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
@ -282,10 +284,10 @@ public class ChooseFolder extends K9ListActivity {
|
|||||||
if (K9.FOLDER_NONE.equalsIgnoreCase(bName)) {
|
if (K9.FOLDER_NONE.equalsIgnoreCase(bName)) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (K9.INBOX.equalsIgnoreCase(aName)) {
|
if (mAccount.getInboxFolderName().equalsIgnoreCase(aName)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (K9.INBOX.equalsIgnoreCase(bName)) {
|
if (mAccount.getInboxFolderName().equalsIgnoreCase(bName)) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -298,7 +300,7 @@ public class ChooseFolder extends K9ListActivity {
|
|||||||
mAdapter.clear();
|
mAdapter.clear();
|
||||||
int position = 0;
|
int position = 0;
|
||||||
for (String name : localFolders) {
|
for (String name : localFolders) {
|
||||||
if (K9.INBOX.equalsIgnoreCase(name)) {
|
if (mAccount.getInboxFolderName().equalsIgnoreCase(name)) {
|
||||||
mAdapter.add(getString(R.string.special_mailbox_name_inbox));
|
mAdapter.add(getString(R.string.special_mailbox_name_inbox));
|
||||||
heldInbox = name;
|
heldInbox = name;
|
||||||
} else if (!K9.ERROR_FOLDER_NAME.equals(name) && !account.getOutboxFolderName().equals(name)) {
|
} else if (!K9.ERROR_FOLDER_NAME.equals(name) && !account.getOutboxFolderName().equals(name)) {
|
||||||
@ -315,7 +317,7 @@ public class ChooseFolder extends K9ListActivity {
|
|||||||
selectedFolder = position;
|
selectedFolder = position;
|
||||||
}
|
}
|
||||||
} else if (name.equals(mFolder) ||
|
} else if (name.equals(mFolder) ||
|
||||||
(K9.INBOX.equalsIgnoreCase(mFolder) && K9.INBOX.equalsIgnoreCase(name))) {
|
(mAccount.getInboxFolderName().equalsIgnoreCase(mFolder) && mAccount.getInboxFolderName().equalsIgnoreCase(name))) {
|
||||||
selectedFolder = position;
|
selectedFolder = position;
|
||||||
}
|
}
|
||||||
position++;
|
position++;
|
||||||
|
@ -97,7 +97,7 @@ public class FolderInfoHolder implements Comparable<FolderInfoHolder> {
|
|||||||
|
|
||||||
this.status = truncateStatus(folder.getStatus());
|
this.status = truncateStatus(folder.getStatus());
|
||||||
|
|
||||||
if (this.name.equalsIgnoreCase(K9.INBOX)) {
|
if (this.name.equalsIgnoreCase(account.getInboxFolderName())) {
|
||||||
this.displayName = context.getString(R.string.special_mailbox_name_inbox);
|
this.displayName = context.getString(R.string.special_mailbox_name_inbox);
|
||||||
} else {
|
} else {
|
||||||
this.displayName = folder.getName();
|
this.displayName = folder.getName();
|
||||||
|
@ -487,6 +487,7 @@ public class FolderList extends K9ListActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onRefresh(!REFRESH_REMOTE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -644,7 +645,9 @@ public class FolderList extends K9ListActivity {
|
|||||||
.markAllMessagesRead(mAccount, mSelectedContextFolder.name);
|
.markAllMessagesRead(mAccount, mSelectedContextFolder.name);
|
||||||
mSelectedContextFolder.unreadMessageCount = 0;
|
mSelectedContextFolder.unreadMessageCount = 0;
|
||||||
mHandler.dataChanged();
|
mHandler.dataChanged();
|
||||||
} catch (Exception e) { /* Ignore */ }
|
} catch (Exception e) {
|
||||||
|
/* Ignore */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
package com.fsck.k9.activity;
|
package com.fsck.k9.activity;
|
||||||
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@ -38,6 +38,7 @@ import android.view.View.OnFocusChangeListener;
|
|||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
import android.webkit.WebView;
|
import android.webkit.WebView;
|
||||||
import android.widget.AutoCompleteTextView.Validator;
|
import android.widget.AutoCompleteTextView.Validator;
|
||||||
|
import android.widget.Button;
|
||||||
import android.widget.CheckBox;
|
import android.widget.CheckBox;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.ImageButton;
|
import android.widget.ImageButton;
|
||||||
@ -89,8 +90,8 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
|
|||||||
"com.fsck.k9.activity.MessageCompose.ccShown";
|
"com.fsck.k9.activity.MessageCompose.ccShown";
|
||||||
private static final String STATE_KEY_BCC_SHOWN =
|
private static final String STATE_KEY_BCC_SHOWN =
|
||||||
"com.fsck.k9.activity.MessageCompose.bccShown";
|
"com.fsck.k9.activity.MessageCompose.bccShown";
|
||||||
private static final String STATE_KEY_QUOTED_TEXT_SHOWN =
|
private static final String STATE_KEY_QUOTED_TEXT_MODE =
|
||||||
"com.fsck.k9.activity.MessageCompose.quotedTextShown";
|
"com.fsck.k9.activity.MessageCompose.QuotedTextShown";
|
||||||
private static final String STATE_KEY_SOURCE_MESSAGE_PROCED =
|
private static final String STATE_KEY_SOURCE_MESSAGE_PROCED =
|
||||||
"com.fsck.k9.activity.MessageCompose.stateKeySourceMessageProced";
|
"com.fsck.k9.activity.MessageCompose.stateKeySourceMessageProced";
|
||||||
private static final String STATE_KEY_DRAFT_UID =
|
private static final String STATE_KEY_DRAFT_UID =
|
||||||
@ -161,6 +162,13 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
|
|||||||
*/
|
*/
|
||||||
private boolean mSourceMessageProcessed = false;
|
private boolean mSourceMessageProcessed = false;
|
||||||
|
|
||||||
|
private enum QuotedTextMode {
|
||||||
|
NONE,
|
||||||
|
SHOW,
|
||||||
|
HIDE
|
||||||
|
};
|
||||||
|
|
||||||
|
private QuotedTextMode mQuotedTextMode = QuotedTextMode.NONE;
|
||||||
|
|
||||||
private TextView mFromView;
|
private TextView mFromView;
|
||||||
private LinearLayout mCcWrapper;
|
private LinearLayout mCcWrapper;
|
||||||
@ -172,6 +180,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
|
|||||||
private EditText mSignatureView;
|
private EditText mSignatureView;
|
||||||
private EditText mMessageContentView;
|
private EditText mMessageContentView;
|
||||||
private LinearLayout mAttachments;
|
private LinearLayout mAttachments;
|
||||||
|
private Button mQuotedTextShow;
|
||||||
private View mQuotedTextBar;
|
private View mQuotedTextBar;
|
||||||
private ImageButton mQuotedTextEdit;
|
private ImageButton mQuotedTextEdit;
|
||||||
private ImageButton mQuotedTextDelete;
|
private ImageButton mQuotedTextDelete;
|
||||||
@ -391,6 +400,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
|
|||||||
mMessageContentView = (EditText)findViewById(R.id.message_content);
|
mMessageContentView = (EditText)findViewById(R.id.message_content);
|
||||||
mMessageContentView.getInputExtras(true).putBoolean("allowEmoji", true);
|
mMessageContentView.getInputExtras(true).putBoolean("allowEmoji", true);
|
||||||
mAttachments = (LinearLayout)findViewById(R.id.attachments);
|
mAttachments = (LinearLayout)findViewById(R.id.attachments);
|
||||||
|
mQuotedTextShow = (Button)findViewById(R.id.quoted_text_show);
|
||||||
mQuotedTextBar = findViewById(R.id.quoted_text_bar);
|
mQuotedTextBar = findViewById(R.id.quoted_text_bar);
|
||||||
mQuotedTextEdit = (ImageButton)findViewById(R.id.quoted_text_edit);
|
mQuotedTextEdit = (ImageButton)findViewById(R.id.quoted_text_edit);
|
||||||
mQuotedTextDelete = (ImageButton)findViewById(R.id.quoted_text_delete);
|
mQuotedTextDelete = (ImageButton)findViewById(R.id.quoted_text_delete);
|
||||||
@ -467,11 +477,10 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
|
|||||||
* We set this to invisible by default. Other methods will turn it back on if it's
|
* We set this to invisible by default. Other methods will turn it back on if it's
|
||||||
* needed.
|
* needed.
|
||||||
*/
|
*/
|
||||||
mQuotedTextBar.setVisibility(View.GONE);
|
|
||||||
mQuotedText.setVisibility(View.GONE);
|
|
||||||
mQuotedHTML.setVisibility(View.GONE);
|
|
||||||
mQuotedTextEdit.setVisibility(View.GONE);
|
|
||||||
|
|
||||||
|
showOrHideQuotedText(QuotedTextMode.NONE);
|
||||||
|
|
||||||
|
mQuotedTextShow.setOnClickListener(this);
|
||||||
mQuotedTextEdit.setOnClickListener(this);
|
mQuotedTextEdit.setOnClickListener(this);
|
||||||
mQuotedTextDelete.setOnClickListener(this);
|
mQuotedTextDelete.setOnClickListener(this);
|
||||||
|
|
||||||
@ -801,7 +810,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
|
|||||||
outState.putParcelableArrayList(STATE_KEY_ATTACHMENTS, attachments);
|
outState.putParcelableArrayList(STATE_KEY_ATTACHMENTS, attachments);
|
||||||
outState.putBoolean(STATE_KEY_CC_SHOWN, mCcView.getVisibility() == View.VISIBLE);
|
outState.putBoolean(STATE_KEY_CC_SHOWN, mCcView.getVisibility() == View.VISIBLE);
|
||||||
outState.putBoolean(STATE_KEY_BCC_SHOWN, mBccView.getVisibility() == View.VISIBLE);
|
outState.putBoolean(STATE_KEY_BCC_SHOWN, mBccView.getVisibility() == View.VISIBLE);
|
||||||
outState.putBoolean(STATE_KEY_QUOTED_TEXT_SHOWN, mQuotedTextBar.getVisibility() == View.VISIBLE);
|
outState.putSerializable(STATE_KEY_QUOTED_TEXT_MODE, mQuotedTextMode);
|
||||||
outState.putBoolean(STATE_KEY_SOURCE_MESSAGE_PROCED, mSourceMessageProcessed);
|
outState.putBoolean(STATE_KEY_SOURCE_MESSAGE_PROCED, mSourceMessageProcessed);
|
||||||
outState.putString(STATE_KEY_DRAFT_UID, mDraftUid);
|
outState.putString(STATE_KEY_DRAFT_UID, mDraftUid);
|
||||||
outState.putSerializable(STATE_IDENTITY, mIdentity);
|
outState.putSerializable(STATE_IDENTITY, mIdentity);
|
||||||
@ -829,17 +838,13 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
|
|||||||
: View.GONE);
|
: View.GONE);
|
||||||
mBccWrapper.setVisibility(savedInstanceState
|
mBccWrapper.setVisibility(savedInstanceState
|
||||||
.getBoolean(STATE_KEY_BCC_SHOWN) ? View.VISIBLE : View.GONE);
|
.getBoolean(STATE_KEY_BCC_SHOWN) ? View.VISIBLE : View.GONE);
|
||||||
if (mMessageFormat == MessageFormat.HTML) {
|
showOrHideQuotedText((QuotedTextMode)savedInstanceState.getSerializable(STATE_KEY_QUOTED_TEXT_MODE));
|
||||||
|
|
||||||
|
if (mQuotedTextMode != QuotedTextMode.NONE && mMessageFormat == MessageFormat.HTML) {
|
||||||
mQuotedHtmlContent = (InsertableHtmlContent) savedInstanceState.getSerializable(STATE_KEY_HTML_QUOTE);
|
mQuotedHtmlContent = (InsertableHtmlContent) savedInstanceState.getSerializable(STATE_KEY_HTML_QUOTE);
|
||||||
mQuotedTextBar.setVisibility(savedInstanceState.getBoolean(STATE_KEY_QUOTED_TEXT_SHOWN) ? View.VISIBLE : View.GONE);
|
|
||||||
mQuotedHTML.setVisibility(savedInstanceState.getBoolean(STATE_KEY_QUOTED_TEXT_SHOWN) ? View.VISIBLE : View.GONE);
|
|
||||||
if (mQuotedHtmlContent != null && mQuotedHtmlContent.getQuotedContent() != null) {
|
if (mQuotedHtmlContent != null && mQuotedHtmlContent.getQuotedContent() != null) {
|
||||||
mQuotedHTML.loadDataWithBaseURL("http://", mQuotedHtmlContent.getQuotedContent(), "text/html", "utf-8", null);
|
mQuotedHTML.loadDataWithBaseURL("http://", mQuotedHtmlContent.getQuotedContent(), "text/html", "utf-8", null);
|
||||||
mQuotedTextEdit.setVisibility(View.VISIBLE);
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
mQuotedTextBar.setVisibility(savedInstanceState.getBoolean(STATE_KEY_QUOTED_TEXT_SHOWN) ? View.VISIBLE : View.GONE);
|
|
||||||
mQuotedText.setVisibility(savedInstanceState.getBoolean(STATE_KEY_QUOTED_TEXT_SHOWN) ? View.VISIBLE : View.GONE);
|
|
||||||
}
|
}
|
||||||
mDraftUid = savedInstanceState.getString(STATE_KEY_DRAFT_UID);
|
mDraftUid = savedInstanceState.getString(STATE_KEY_DRAFT_UID);
|
||||||
mIdentity = (Identity)savedInstanceState.getSerializable(STATE_IDENTITY);
|
mIdentity = (Identity)savedInstanceState.getSerializable(STATE_IDENTITY);
|
||||||
@ -904,10 +909,27 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
|
|||||||
|
|
||||||
String text = mMessageContentView.getText().toString();
|
String text = mMessageContentView.getText().toString();
|
||||||
|
|
||||||
|
boolean discardQuotedText = false;
|
||||||
|
if (!isDraft && !mQuotedTextMode.equals(QuotedTextMode.SHOW)) {
|
||||||
|
discardQuotedText = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (discardQuotedText) {
|
||||||
|
if (!isDraft) {
|
||||||
|
text = appendSignature(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build the body.
|
||||||
|
TextBody body = new TextBody(text);
|
||||||
|
body.setComposedMessageLength(text.length());
|
||||||
|
body.setComposedMessageOffset(0);
|
||||||
|
|
||||||
|
return body;
|
||||||
|
}
|
||||||
// Handle HTML separate from the rest of the text content. HTML mode doesn't allow signature after the quoted
|
// Handle HTML separate from the rest of the text content. HTML mode doesn't allow signature after the quoted
|
||||||
// text, nor does it allow reply after quote. Users who want that functionality will need to stick with text
|
// text, nor does it allow reply after quote. Users who want that functionality will need to stick with text
|
||||||
// mode.
|
// mode.
|
||||||
if (mMessageFormat == MessageFormat.HTML) {
|
else if (mMessageFormat == MessageFormat.HTML) {
|
||||||
// Add the signature.
|
// Add the signature.
|
||||||
if (!isDraft) {
|
if (!isDraft) {
|
||||||
text = appendSignature(text);
|
text = appendSignature(text);
|
||||||
@ -917,10 +939,6 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
|
|||||||
if (K9.DEBUG && mQuotedHtmlContent != null)
|
if (K9.DEBUG && mQuotedHtmlContent != null)
|
||||||
Log.d(K9.LOG_TAG, "insertable: " + mQuotedHtmlContent.toDebugString());
|
Log.d(K9.LOG_TAG, "insertable: " + mQuotedHtmlContent.toDebugString());
|
||||||
if (mQuotedHtmlContent != null) {
|
if (mQuotedHtmlContent != null) {
|
||||||
// Remove the quoted part if it's no longer visible.
|
|
||||||
if (mQuotedTextBar.getVisibility() != View.VISIBLE) {
|
|
||||||
mQuotedHtmlContent.clearQuotedContent();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the insertion location based upon our reply after quote setting. Reply after
|
// Set the insertion location based upon our reply after quote setting. Reply after
|
||||||
// quote makes no sense for HEADER style replies. In addition, add some extra
|
// quote makes no sense for HEADER style replies. In addition, add some extra
|
||||||
@ -965,7 +983,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
|
|||||||
text = appendSignature(text);
|
text = appendSignature(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mQuotedTextBar.getVisibility() == View.VISIBLE) {
|
if (mQuotedTextMode != QuotedTextMode.NONE) {
|
||||||
if (replyAfterQuote) {
|
if (replyAfterQuote) {
|
||||||
composedMessageOffset = mQuotedText.getText().toString().length() + "\n".length();
|
composedMessageOffset = mQuotedText.getText().toString().length() + "\n".length();
|
||||||
text = mQuotedText.getText().toString() + "\n" + text;
|
text = mQuotedText.getText().toString() + "\n" + text;
|
||||||
@ -1139,7 +1157,9 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
|
|||||||
NAME("n"),
|
NAME("n"),
|
||||||
EMAIL("e"),
|
EMAIL("e"),
|
||||||
// TODO - store a reference to the message being replied so we can mark it at the time of send.
|
// TODO - store a reference to the message being replied so we can mark it at the time of send.
|
||||||
ORIGINAL_MESSAGE("m");
|
ORIGINAL_MESSAGE("m"),
|
||||||
|
CURSOR_POSITION("p"), // Where in the message your cursor was when you saved.
|
||||||
|
QUOTED_TEXT_MODE("q");
|
||||||
|
|
||||||
private final String value;
|
private final String value;
|
||||||
|
|
||||||
@ -1202,6 +1222,10 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
|
|||||||
uri.appendQueryParameter(IdentityField.ORIGINAL_MESSAGE.value(), mMessageReference.toIdentityString());
|
uri.appendQueryParameter(IdentityField.ORIGINAL_MESSAGE.value(), mMessageReference.toIdentityString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uri.appendQueryParameter(IdentityField.CURSOR_POSITION.value(), Integer.toString(mMessageContentView.getSelectionStart()));
|
||||||
|
|
||||||
|
uri.appendQueryParameter(IdentityField.QUOTED_TEXT_MODE.value(), mQuotedTextMode.name());
|
||||||
|
|
||||||
String k9identity = IDENTITY_VERSION_1 + uri.build().getEncodedQuery();
|
String k9identity = IDENTITY_VERSION_1 + uri.build().getEncodedQuery();
|
||||||
|
|
||||||
if (K9.DEBUG) {
|
if (K9.DEBUG) {
|
||||||
@ -1276,6 +1300,9 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
|
|||||||
if (tokens.hasMoreTokens()) {
|
if (tokens.hasMoreTokens()) {
|
||||||
identity.put(IdentityField.EMAIL, Utility.base64Decode(tokens.nextToken()));
|
identity.put(IdentityField.EMAIL, Utility.base64Decode(tokens.nextToken()));
|
||||||
}
|
}
|
||||||
|
if (tokens.hasMoreTokens()) {
|
||||||
|
identity.put(IdentityField.QUOTED_TEXT_MODE, Utility.base64Decode(tokens.nextToken()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return identity;
|
return identity;
|
||||||
@ -1652,8 +1679,12 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
|
|||||||
mAttachments.removeView((View) view.getTag());
|
mAttachments.removeView((View) view.getTag());
|
||||||
mDraftNeedsSaving = true;
|
mDraftNeedsSaving = true;
|
||||||
break;
|
break;
|
||||||
|
case R.id.quoted_text_show:
|
||||||
|
showOrHideQuotedText(QuotedTextMode.SHOW);
|
||||||
|
mDraftNeedsSaving = true;
|
||||||
|
break;
|
||||||
case R.id.quoted_text_delete:
|
case R.id.quoted_text_delete:
|
||||||
deleteQuotedText();
|
showOrHideQuotedText(QuotedTextMode.HIDE);
|
||||||
mDraftNeedsSaving = true;
|
mDraftNeedsSaving = true;
|
||||||
break;
|
break;
|
||||||
case R.id.quoted_text_edit:
|
case R.id.quoted_text_edit:
|
||||||
@ -1670,15 +1701,37 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* Delete the quoted text.
|
* Show or Hide the quoted text according to mQuotedTextMode.
|
||||||
*/
|
*/
|
||||||
private void deleteQuotedText() {
|
private void showOrHideQuotedText(QuotedTextMode mode) {
|
||||||
|
mQuotedTextMode = mode;
|
||||||
|
if (mQuotedTextMode == QuotedTextMode.NONE) {
|
||||||
|
mQuotedTextShow.setVisibility(View.GONE);
|
||||||
mQuotedTextBar.setVisibility(View.GONE);
|
mQuotedTextBar.setVisibility(View.GONE);
|
||||||
|
|
||||||
mQuotedText.setVisibility(View.GONE);
|
mQuotedText.setVisibility(View.GONE);
|
||||||
mQuotedHTML.setVisibility(View.GONE);
|
mQuotedHTML.setVisibility(View.GONE);
|
||||||
if (mQuotedHtmlContent != null) {
|
mQuotedTextEdit.setVisibility(View.GONE);
|
||||||
mQuotedHtmlContent.clearQuotedContent();
|
} else if (mQuotedTextMode == QuotedTextMode.SHOW) {
|
||||||
|
mQuotedTextShow.setVisibility(View.GONE);
|
||||||
|
mQuotedTextBar.setVisibility(View.VISIBLE);
|
||||||
|
if (mMessageFormat == MessageFormat.HTML) {
|
||||||
|
mQuotedText.setVisibility(View.GONE);
|
||||||
|
mQuotedHTML.setVisibility(View.VISIBLE);
|
||||||
|
mQuotedTextEdit.setVisibility(View.VISIBLE);
|
||||||
|
} else {
|
||||||
|
mQuotedText.setVisibility(View.VISIBLE);
|
||||||
|
mQuotedHTML.setVisibility(View.GONE);
|
||||||
|
mQuotedTextEdit.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
} else if (mQuotedTextMode == QuotedTextMode.HIDE) {
|
||||||
|
mQuotedTextShow.setVisibility(View.VISIBLE);
|
||||||
|
mQuotedTextBar.setVisibility(View.GONE);
|
||||||
|
|
||||||
|
mQuotedText.setVisibility(View.GONE);
|
||||||
|
mQuotedHTML.setVisibility(View.GONE);
|
||||||
|
mQuotedTextEdit.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1908,7 +1961,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Quote the message and setup the UI.
|
// Quote the message and setup the UI.
|
||||||
populateUIWithQuotedMessage();
|
populateUIWithQuotedMessage(mAccount.isDefaultQuotedTextShown());
|
||||||
|
|
||||||
if (ACTION_REPLY_ALL.equals(action) || ACTION_REPLY.equals(action)) {
|
if (ACTION_REPLY_ALL.equals(action) || ACTION_REPLY.equals(action)) {
|
||||||
Identity useIdentity = null;
|
Identity useIdentity = null;
|
||||||
@ -1963,7 +2016,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Quote the message and setup the UI.
|
// Quote the message and setup the UI.
|
||||||
populateUIWithQuotedMessage();
|
populateUIWithQuotedMessage(true);
|
||||||
|
|
||||||
if (!mSourceMessageProcessed) {
|
if (!mSourceMessageProcessed) {
|
||||||
if (!loadAttachments(message, 0)) {
|
if (!loadAttachments(message, 0)) {
|
||||||
@ -1971,6 +2024,8 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (ACTION_EDIT_DRAFT.equals(action)) {
|
} else if (ACTION_EDIT_DRAFT.equals(action)) {
|
||||||
|
String showQuotedTextMode = "NONE";
|
||||||
|
|
||||||
mDraftUid = message.getUid();
|
mDraftUid = message.getUid();
|
||||||
mSubjectView.setText(message.getSubject());
|
mSubjectView.setText(message.getSubject());
|
||||||
addAddresses(mToView, message.getRecipients(RecipientType.TO));
|
addAddresses(mToView, message.getRecipients(RecipientType.TO));
|
||||||
@ -2047,6 +2102,19 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int cursorPosition = 0;
|
||||||
|
if (k9identity.containsKey(IdentityField.CURSOR_POSITION)) {
|
||||||
|
try {
|
||||||
|
cursorPosition = Integer.valueOf(k9identity.get(IdentityField.CURSOR_POSITION)).intValue();
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(K9.LOG_TAG, "Could not parse cursor position for MessageCompose; continuing.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (k9identity.containsKey(IdentityField.QUOTED_TEXT_MODE)) {
|
||||||
|
showQuotedTextMode = k9identity.get(IdentityField.QUOTED_TEXT_MODE);
|
||||||
|
}
|
||||||
|
|
||||||
mIdentity = newIdentity;
|
mIdentity = newIdentity;
|
||||||
|
|
||||||
updateSignature();
|
updateSignature();
|
||||||
@ -2061,15 +2129,22 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
|
|||||||
// Always respect the user's current composition format preference, even if the
|
// Always respect the user's current composition format preference, even if the
|
||||||
// draft was saved in a different format.
|
// draft was saved in a different format.
|
||||||
// TODO - The current implementation doesn't allow a user in HTML mode to edit a draft that wasn't saved with K9mail.
|
// TODO - The current implementation doesn't allow a user in HTML mode to edit a draft that wasn't saved with K9mail.
|
||||||
if (mMessageFormat == MessageFormat.HTML) {
|
String messageFormat = k9identity.get(IdentityField.MESSAGE_FORMAT);
|
||||||
if (k9identity.get(IdentityField.MESSAGE_FORMAT) == null || !MessageFormat.valueOf(k9identity.get(IdentityField.MESSAGE_FORMAT)).equals(MessageFormat.HTML)) {
|
if (messageFormat == null) {
|
||||||
// This message probably wasn't created by us. The exception is legacy
|
// This message probably wasn't created by us. The exception is legacy
|
||||||
// drafts created before the advent of HTML composition. In those cases,
|
// drafts created before the advent of HTML composition. In those cases,
|
||||||
// we'll display the whole message (including the quoted part) in the
|
// we'll display the whole message (including the quoted part) in the
|
||||||
// composition window. If that's the case, try and convert it to text to
|
// composition window. If that's the case, try and convert it to text to
|
||||||
// match the behavior in text mode.
|
// match the behavior in text mode.
|
||||||
mMessageContentView.setText(getBodyTextFromMessage(message, MessageFormat.TEXT));
|
mMessageContentView.setText(getBodyTextFromMessage(message, MessageFormat.TEXT));
|
||||||
} else {
|
mMessageFormat = MessageFormat.TEXT;
|
||||||
|
showOrHideQuotedText(QuotedTextMode.valueOf(showQuotedTextMode));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mMessageFormat = MessageFormat.valueOf(messageFormat);
|
||||||
|
|
||||||
|
if (mMessageFormat == MessageFormat.HTML) {
|
||||||
Part part = MimeUtility.findFirstPartByMimeType(message, "text/html");
|
Part part = MimeUtility.findFirstPartByMimeType(message, "text/html");
|
||||||
if (part != null) { // Shouldn't happen if we were the one who saved it.
|
if (part != null) { // Shouldn't happen if we were the one who saved it.
|
||||||
String text = MimeUtility.getTextFromPart(part);
|
String text = MimeUtility.getTextFromPart(part);
|
||||||
@ -2090,44 +2165,9 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
|
|||||||
mQuotedHtmlContent.setQuotedContent(quotedHTML);
|
mQuotedHtmlContent.setQuotedContent(quotedHTML);
|
||||||
mQuotedHtmlContent.setHeaderInsertionPoint(bodyOffset);
|
mQuotedHtmlContent.setHeaderInsertionPoint(bodyOffset);
|
||||||
mQuotedHTML.loadDataWithBaseURL("http://", mQuotedHtmlContent.getQuotedContent(), "text/html", "utf-8", null);
|
mQuotedHTML.loadDataWithBaseURL("http://", mQuotedHtmlContent.getQuotedContent(), "text/html", "utf-8", null);
|
||||||
mQuotedHTML.setVisibility(View.VISIBLE);
|
|
||||||
mQuotedTextBar.setVisibility(View.VISIBLE);
|
|
||||||
mQuotedTextEdit.setVisibility(View.VISIBLE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (mMessageFormat == MessageFormat.TEXT) {
|
} else if (mMessageFormat == MessageFormat.TEXT) {
|
||||||
MessageFormat format = k9identity.get(IdentityField.MESSAGE_FORMAT) != null
|
|
||||||
? MessageFormat.valueOf(k9identity.get(IdentityField.MESSAGE_FORMAT))
|
|
||||||
: null;
|
|
||||||
if (format == null) {
|
|
||||||
mMessageContentView.setText(getBodyTextFromMessage(message, MessageFormat.TEXT));
|
|
||||||
} else if (format.equals(MessageFormat.HTML)) {
|
|
||||||
// We are in text mode, but have an HTML message.
|
|
||||||
Part htmlPart = MimeUtility.findFirstPartByMimeType(message, "text/html");
|
|
||||||
if (htmlPart != null) { // Shouldn't happen if we were the one who saved it.
|
|
||||||
String text = MimeUtility.getTextFromPart(htmlPart);
|
|
||||||
if (K9.DEBUG) {
|
|
||||||
Log.d(K9.LOG_TAG, "Loading message with offset " + bodyOffset + ", length " + bodyLength + ". Text length is " + text.length() + ".");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Grab our reply text.
|
|
||||||
String bodyText = text.substring(bodyOffset, bodyOffset + bodyLength);
|
|
||||||
mMessageContentView.setText(Html.fromHtml(bodyText).toString());
|
|
||||||
|
|
||||||
// Regenerate the quoted html without out content in it.
|
|
||||||
StringBuilder quotedHTML = new StringBuilder();
|
|
||||||
quotedHTML.append(text.substring(0, bodyOffset)); // stuff before the reply
|
|
||||||
quotedHTML.append(text.substring(bodyOffset + bodyLength));
|
|
||||||
// Convert it to text.
|
|
||||||
mQuotedText.setText(HtmlConverter.htmlToText(quotedHTML.toString()));
|
|
||||||
|
|
||||||
mQuotedTextBar.setVisibility(View.VISIBLE);
|
|
||||||
mQuotedText.setVisibility(View.VISIBLE);
|
|
||||||
} else {
|
|
||||||
Log.e(K9.LOG_TAG, "Found an HTML draft but couldn't find the HTML part! Something's wrong.");
|
|
||||||
}
|
|
||||||
} else if (format.equals(MessageFormat.TEXT)) {
|
|
||||||
Part textPart = MimeUtility.findFirstPartByMimeType(message, "text/plain");
|
Part textPart = MimeUtility.findFirstPartByMimeType(message, "text/plain");
|
||||||
if (textPart != null) {
|
if (textPart != null) {
|
||||||
String text = MimeUtility.getTextFromPart(textPart);
|
String text = MimeUtility.getTextFromPart(textPart);
|
||||||
@ -2139,10 +2179,6 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
|
|||||||
|
|
||||||
mMessageContentView.setText(bodyText);
|
mMessageContentView.setText(bodyText);
|
||||||
mQuotedText.setText(quotedText);
|
mQuotedText.setText(quotedText);
|
||||||
|
|
||||||
mQuotedTextBar.setVisibility(View.VISIBLE);
|
|
||||||
mQuotedText.setVisibility(View.VISIBLE);
|
|
||||||
mQuotedHTML.setVisibility(View.VISIBLE);
|
|
||||||
} else {
|
} else {
|
||||||
mMessageContentView.setText(text);
|
mMessageContentView.setText(text);
|
||||||
}
|
}
|
||||||
@ -2150,7 +2186,15 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
|
|||||||
} else {
|
} else {
|
||||||
Log.e(K9.LOG_TAG, "Unhandled message format.");
|
Log.e(K9.LOG_TAG, "Unhandled message format.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the cursor position if we have it.
|
||||||
|
try {
|
||||||
|
mMessageContentView.setSelection(cursorPosition);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(K9.LOG_TAG, "Could not set cursor position in MessageCompose; ignoring.", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
showOrHideQuotedText(QuotedTextMode.valueOf(showQuotedTextMode));
|
||||||
}
|
}
|
||||||
} catch (MessagingException me) {
|
} catch (MessagingException me) {
|
||||||
/**
|
/**
|
||||||
@ -2158,16 +2202,17 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
|
|||||||
* the source message. Log it as an error, though.
|
* the source message. Log it as an error, though.
|
||||||
*/
|
*/
|
||||||
Log.e(K9.LOG_TAG, "Error while processing source message: ", me);
|
Log.e(K9.LOG_TAG, "Error while processing source message: ", me);
|
||||||
}
|
} finally {
|
||||||
mSourceMessageProcessed = true;
|
mSourceMessageProcessed = true;
|
||||||
mDraftNeedsSaving = false;
|
mDraftNeedsSaving = false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build and populate the UI with the quoted message.
|
* Build and populate the UI with the quoted message.
|
||||||
* @throws MessagingException
|
* @throws MessagingException
|
||||||
*/
|
*/
|
||||||
private void populateUIWithQuotedMessage() throws MessagingException {
|
private void populateUIWithQuotedMessage(boolean shown) throws MessagingException {
|
||||||
// TODO -- I am assuming that mSourceMessageBody will always be a text part. Is this a safe assumption?
|
// TODO -- I am assuming that mSourceMessageBody will always be a text part. Is this a safe assumption?
|
||||||
|
|
||||||
// Handle the original message in the reply
|
// Handle the original message in the reply
|
||||||
@ -2181,20 +2226,14 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
|
|||||||
// Load the message with the reply header.
|
// Load the message with the reply header.
|
||||||
mQuotedHTML.loadDataWithBaseURL("http://", mQuotedHtmlContent.getQuotedContent(), "text/html", "utf-8", null);
|
mQuotedHTML.loadDataWithBaseURL("http://", mQuotedHtmlContent.getQuotedContent(), "text/html", "utf-8", null);
|
||||||
|
|
||||||
mQuotedTextBar.setVisibility(View.VISIBLE);
|
|
||||||
mQuotedHTML.setVisibility(View.VISIBLE);
|
|
||||||
mQuotedTextEdit.setVisibility(View.VISIBLE);
|
|
||||||
|
|
||||||
mQuotedText.setVisibility(View.GONE);
|
|
||||||
} else if (mMessageFormat == MessageFormat.TEXT) {
|
} else if (mMessageFormat == MessageFormat.TEXT) {
|
||||||
mQuotedText.setText(quoteOriginalTextMessage(mSourceMessage, content, mAccount.getQuoteStyle()));
|
mQuotedText.setText(quoteOriginalTextMessage(mSourceMessage, content, mAccount.getQuoteStyle()));
|
||||||
|
}
|
||||||
|
|
||||||
mQuotedTextBar.setVisibility(View.VISIBLE);
|
if (shown) {
|
||||||
mQuotedText.setVisibility(View.VISIBLE);
|
showOrHideQuotedText(QuotedTextMode.SHOW);
|
||||||
|
} else {
|
||||||
mQuotedHtmlContent = null;
|
showOrHideQuotedText(QuotedTextMode.HIDE);
|
||||||
mQuotedTextEdit.setVisibility(View.GONE);
|
|
||||||
mQuotedHTML.setVisibility(View.GONE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2406,10 +2445,10 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
|
|||||||
// part).
|
// part).
|
||||||
if (mSourceProcessed) {
|
if (mSourceProcessed) {
|
||||||
try {
|
try {
|
||||||
populateUIWithQuotedMessage();
|
populateUIWithQuotedMessage(true);
|
||||||
} catch (MessagingException e) {
|
} catch (MessagingException e) {
|
||||||
// Hm, if we couldn't populate the UI after source reprocessing, let's just delete it?
|
// Hm, if we couldn't populate the UI after source reprocessing, let's just delete it?
|
||||||
deleteQuotedText();
|
showOrHideQuotedText(QuotedTextMode.HIDE);
|
||||||
Log.e(K9.LOG_TAG, "Could not re-process source message; deleting quoted text to be safe.", e);
|
Log.e(K9.LOG_TAG, "Could not re-process source message; deleting quoted text to be safe.", e);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -12,13 +12,14 @@ import android.app.AlertDialog;
|
|||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.res.ColorStateList;
|
import android.graphics.Color;
|
||||||
import android.graphics.Typeface;
|
import android.graphics.Typeface;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.text.Spannable;
|
import android.text.Spannable;
|
||||||
import android.text.SpannableStringBuilder;
|
import android.text.SpannableStringBuilder;
|
||||||
import android.text.style.TextAppearanceSpan;
|
import android.text.style.ForegroundColorSpan;
|
||||||
|
import android.text.style.StyleSpan;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.TypedValue;
|
import android.util.TypedValue;
|
||||||
import android.view.animation.Animation;
|
import android.view.animation.Animation;
|
||||||
@ -491,7 +492,7 @@ public class MessageList
|
|||||||
if (mFolderName != null) {
|
if (mFolderName != null) {
|
||||||
displayName = mFolderName;
|
displayName = mFolderName;
|
||||||
|
|
||||||
if (K9.INBOX.equalsIgnoreCase(displayName)) {
|
if (mAccount.getInboxFolderName().equalsIgnoreCase(displayName)) {
|
||||||
displayName = getString(R.string.special_mailbox_name_inbox);
|
displayName = getString(R.string.special_mailbox_name_inbox);
|
||||||
} else if (mAccount.getOutboxFolderName().equals(displayName)) {
|
} else if (mAccount.getOutboxFolderName().equals(displayName)) {
|
||||||
displayName = getString(R.string.special_mailbox_name_outbox);
|
displayName = getString(R.string.special_mailbox_name_outbox);
|
||||||
@ -565,9 +566,10 @@ public class MessageList
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||||
// Use mListView.getAdapter() to get the WrapperListAdapter that includes the footer view.
|
if (view == mFooterView) {
|
||||||
if (mCurrentFolder != null && ((position + 1) == mListView.getAdapter().getCount())) {
|
if (mCurrentFolder != null) {
|
||||||
mController.loadMoreMessages(mAccount, mFolderName, mAdapter.mListener);
|
mController.loadMoreMessages(mAccount, mFolderName, mAdapter.mListener);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -726,6 +728,9 @@ public class MessageList
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
// reread the selected date format preference in case it has changed
|
||||||
|
mMessageHelper.refresh();
|
||||||
|
|
||||||
new Thread() {
|
new Thread() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
@ -2156,13 +2161,14 @@ public class MessageList
|
|||||||
holder.preview.setText(noSender, TextView.BufferType.SPANNABLE);
|
holder.preview.setText(noSender, TextView.BufferType.SPANNABLE);
|
||||||
Spannable str = (Spannable) holder.preview.getText();
|
Spannable str = (Spannable) holder.preview.getText();
|
||||||
|
|
||||||
ColorStateList color = holder.subject.getTextColors();
|
str.setSpan(new StyleSpan(Typeface.NORMAL),
|
||||||
ColorStateList linkColor = holder.subject.getLinkTextColors();
|
|
||||||
str.setSpan(new TextAppearanceSpan(null, Typeface.NORMAL, mFontSizes.getMessageListSender(), color, linkColor),
|
|
||||||
0,
|
0,
|
||||||
noSender.length(),
|
noSender.length(),
|
||||||
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
|
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
);
|
str.setSpan(K9.createAbsoluteSizeSpan(mFontSizes.getMessageListSender()),
|
||||||
|
0,
|
||||||
|
noSender.length(),
|
||||||
|
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
} else {
|
} else {
|
||||||
holder.from.setText(noSender);
|
holder.from.setText(noSender);
|
||||||
holder.from.setTypeface(null, Typeface.NORMAL);
|
holder.from.setTypeface(null, Typeface.NORMAL);
|
||||||
@ -2244,13 +2250,20 @@ public class MessageList
|
|||||||
Spannable str = (Spannable)holder.preview.getText();
|
Spannable str = (Spannable)holder.preview.getText();
|
||||||
|
|
||||||
// Create a span section for the sender, and assign the correct font size and weight.
|
// Create a span section for the sender, and assign the correct font size and weight.
|
||||||
ColorStateList color = holder.subject.getTextColors();
|
str.setSpan(new StyleSpan(senderTypeface),
|
||||||
ColorStateList linkColor = holder.subject.getLinkTextColors();
|
|
||||||
str.setSpan(new TextAppearanceSpan(null, senderTypeface, mFontSizes.getMessageListSender(), color, linkColor),
|
|
||||||
0,
|
0,
|
||||||
message.sender.length() + 1,
|
message.sender.length() + 1,
|
||||||
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
|
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
);
|
str.setSpan(K9.createAbsoluteSizeSpan(mFontSizes.getMessageListSender()),
|
||||||
|
0,
|
||||||
|
message.sender.length() + 1,
|
||||||
|
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
|
|
||||||
|
// set span for preview message.
|
||||||
|
str.setSpan(new ForegroundColorSpan(Color.rgb(128, 128, 128)), // How do I can specify the android.R.attr.textColorTertiary
|
||||||
|
message.sender.length() + 1,
|
||||||
|
str.length(),
|
||||||
|
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
} else {
|
} else {
|
||||||
holder.from.setText(new SpannableStringBuilder(recipientSigil(message)).append(message.sender));
|
holder.from.setText(new SpannableStringBuilder(recipientSigil(message)).append(message.sender));
|
||||||
|
|
||||||
|
@ -17,12 +17,16 @@ import com.fsck.k9.*;
|
|||||||
import com.fsck.k9.controller.MessagingController;
|
import com.fsck.k9.controller.MessagingController;
|
||||||
import com.fsck.k9.controller.MessagingListener;
|
import com.fsck.k9.controller.MessagingListener;
|
||||||
import com.fsck.k9.crypto.PgpData;
|
import com.fsck.k9.crypto.PgpData;
|
||||||
|
import com.fsck.k9.helper.FileBrowserHelper;
|
||||||
|
import com.fsck.k9.helper.FileBrowserHelper.FileBrowserFailOverCallback;
|
||||||
import com.fsck.k9.mail.*;
|
import com.fsck.k9.mail.*;
|
||||||
import com.fsck.k9.mail.store.StorageManager;
|
import com.fsck.k9.mail.store.StorageManager;
|
||||||
import com.fsck.k9.view.AttachmentView;
|
import com.fsck.k9.view.AttachmentView;
|
||||||
import com.fsck.k9.view.ToggleScrollView;
|
import com.fsck.k9.view.ToggleScrollView;
|
||||||
import com.fsck.k9.view.SingleMessageView;
|
import com.fsck.k9.view.SingleMessageView;
|
||||||
|
import com.fsck.k9.view.AttachmentView.AttachmentFileDownloadCallback;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class MessageView extends K9Activity implements OnClickListener {
|
public class MessageView extends K9Activity implements OnClickListener {
|
||||||
@ -33,7 +37,7 @@ public class MessageView extends K9Activity implements OnClickListener {
|
|||||||
private static final String STATE_PGP_DATA = "pgpData";
|
private static final String STATE_PGP_DATA = "pgpData";
|
||||||
private static final int ACTIVITY_CHOOSE_FOLDER_MOVE = 1;
|
private static final int ACTIVITY_CHOOSE_FOLDER_MOVE = 1;
|
||||||
private static final int ACTIVITY_CHOOSE_FOLDER_COPY = 2;
|
private static final int ACTIVITY_CHOOSE_FOLDER_COPY = 2;
|
||||||
|
private static final int ACTIVITY_CHOOSE_DIRECTORY = 3;
|
||||||
|
|
||||||
private SingleMessageView mMessageView;
|
private SingleMessageView mMessageView;
|
||||||
|
|
||||||
@ -61,6 +65,12 @@ public class MessageView extends K9Activity implements OnClickListener {
|
|||||||
private MessageViewHandler mHandler = new MessageViewHandler();
|
private MessageViewHandler mHandler = new MessageViewHandler();
|
||||||
private StorageManager.StorageListener mStorageListener = new StorageListenerImplementation();
|
private StorageManager.StorageListener mStorageListener = new StorageListenerImplementation();
|
||||||
|
|
||||||
|
/** this variable is used to save the calling AttachmentView
|
||||||
|
* until the onActivityResult is called.
|
||||||
|
* => with this reference we can identity the caller
|
||||||
|
*/
|
||||||
|
private AttachmentView attachmentTmpStore;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to temporarily store the destination folder for refile operations if a confirmation
|
* Used to temporarily store the destination folder for refile operations if a confirmation
|
||||||
* dialog is shown.
|
* dialog is shown.
|
||||||
@ -295,6 +305,32 @@ public class MessageView extends K9Activity implements OnClickListener {
|
|||||||
mTopView = mToggleScrollView = (ToggleScrollView) findViewById(R.id.top_view);
|
mTopView = mToggleScrollView = (ToggleScrollView) findViewById(R.id.top_view);
|
||||||
mMessageView = (SingleMessageView) findViewById(R.id.message_view);
|
mMessageView = (SingleMessageView) findViewById(R.id.message_view);
|
||||||
|
|
||||||
|
//set a callback for the attachment view. With this callback the attachmentview
|
||||||
|
//request the start of a filebrowser activity.
|
||||||
|
mMessageView.setAttachmentCallback(new AttachmentFileDownloadCallback() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showFileBrowser(final AttachmentView caller) {
|
||||||
|
FileBrowserHelper.getInstance()
|
||||||
|
.showFileBrowserActivity(MessageView.this,
|
||||||
|
null,
|
||||||
|
MessageView.ACTIVITY_CHOOSE_DIRECTORY,
|
||||||
|
callback);
|
||||||
|
attachmentTmpStore = caller;
|
||||||
|
}
|
||||||
|
FileBrowserFailOverCallback callback = new FileBrowserFailOverCallback() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPathEntered(String path) {
|
||||||
|
attachmentTmpStore.writeFile(new File(path));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCancel() {
|
||||||
|
// canceled, do nothing
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
mMessageView.initialize(this);
|
mMessageView.initialize(this);
|
||||||
|
|
||||||
setTitle("");
|
setTitle("");
|
||||||
@ -712,6 +748,19 @@ public class MessageView extends K9Activity implements OnClickListener {
|
|||||||
if (resultCode != RESULT_OK)
|
if (resultCode != RESULT_OK)
|
||||||
return;
|
return;
|
||||||
switch (requestCode) {
|
switch (requestCode) {
|
||||||
|
case ACTIVITY_CHOOSE_DIRECTORY:
|
||||||
|
if (resultCode == RESULT_OK && data != null) {
|
||||||
|
// obtain the filename
|
||||||
|
Uri fileUri = data.getData();
|
||||||
|
if (fileUri != null) {
|
||||||
|
String filePath = fileUri.getPath();
|
||||||
|
if (filePath != null) {
|
||||||
|
attachmentTmpStore.writeFile(new File(filePath));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
case ACTIVITY_CHOOSE_FOLDER_MOVE:
|
case ACTIVITY_CHOOSE_FOLDER_MOVE:
|
||||||
case ACTIVITY_CHOOSE_FOLDER_COPY:
|
case ACTIVITY_CHOOSE_FOLDER_COPY:
|
||||||
if (data == null)
|
if (data == null)
|
||||||
@ -774,7 +823,7 @@ public class MessageView extends K9Activity implements OnClickListener {
|
|||||||
|
|
||||||
private void onMarkAsUnread() {
|
private void onMarkAsUnread() {
|
||||||
if (mMessage != null) {
|
if (mMessage != null) {
|
||||||
mController.setFlag(mAccount, mMessageReference.folderName, new String[] { mMessage.getUid() }, Flag.SEEN, false);
|
// (Issue 3319) mController.setFlag(mAccount, mMessageReference.folderName, new String[] { mMessage.getUid() }, Flag.SEEN, false);
|
||||||
try {
|
try {
|
||||||
mMessage.setFlag(Flag.SEEN, false);
|
mMessage.setFlag(Flag.SEEN, false);
|
||||||
mMessageView.setHeaders(mMessage, mAccount);
|
mMessageView.setHeaders(mMessage, mAccount);
|
||||||
|
@ -88,6 +88,7 @@ public class AccountSettings extends K9PreferenceActivity {
|
|||||||
private static final String PREFERENCE_MESSAGE_FORMAT = "message_format";
|
private static final String PREFERENCE_MESSAGE_FORMAT = "message_format";
|
||||||
private static final String PREFERENCE_QUOTE_PREFIX = "account_quote_prefix";
|
private static final String PREFERENCE_QUOTE_PREFIX = "account_quote_prefix";
|
||||||
private static final String PREFERENCE_QUOTE_STYLE = "quote_style";
|
private static final String PREFERENCE_QUOTE_STYLE = "quote_style";
|
||||||
|
private static final String PREFERENCE_DEFAULT_QUOTED_TEXT_SHOWN = "default_quoted_text_shown";
|
||||||
private static final String PREFERENCE_REPLY_AFTER_QUOTE = "reply_after_quote";
|
private static final String PREFERENCE_REPLY_AFTER_QUOTE = "reply_after_quote";
|
||||||
private static final String PREFERENCE_SYNC_REMOTE_DELETIONS = "account_sync_remote_deletetions";
|
private static final String PREFERENCE_SYNC_REMOTE_DELETIONS = "account_sync_remote_deletetions";
|
||||||
private static final String PREFERENCE_CRYPTO_APP = "crypto_app";
|
private static final String PREFERENCE_CRYPTO_APP = "crypto_app";
|
||||||
@ -145,6 +146,7 @@ public class AccountSettings extends K9PreferenceActivity {
|
|||||||
private ListPreference mMessageFormat;
|
private ListPreference mMessageFormat;
|
||||||
private ListPreference mQuoteStyle;
|
private ListPreference mQuoteStyle;
|
||||||
private EditTextPreference mAccountQuotePrefix;
|
private EditTextPreference mAccountQuotePrefix;
|
||||||
|
private CheckBoxPreference mAccountDefaultQuotedTextShown;
|
||||||
private CheckBoxPreference mReplyAfterQuote;
|
private CheckBoxPreference mReplyAfterQuote;
|
||||||
private CheckBoxPreference mSyncRemoteDeletions;
|
private CheckBoxPreference mSyncRemoteDeletions;
|
||||||
private CheckBoxPreference mSaveAllHeaders;
|
private CheckBoxPreference mSaveAllHeaders;
|
||||||
@ -226,6 +228,9 @@ public class AccountSettings extends K9PreferenceActivity {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
mAccountDefaultQuotedTextShown = (CheckBoxPreference) findPreference(PREFERENCE_DEFAULT_QUOTED_TEXT_SHOWN);
|
||||||
|
mAccountDefaultQuotedTextShown.setChecked(mAccount.isDefaultQuotedTextShown());
|
||||||
|
|
||||||
mReplyAfterQuote = (CheckBoxPreference) findPreference(PREFERENCE_REPLY_AFTER_QUOTE);
|
mReplyAfterQuote = (CheckBoxPreference) findPreference(PREFERENCE_REPLY_AFTER_QUOTE);
|
||||||
mReplyAfterQuote.setChecked(mAccount.isReplyAfterQuote());
|
mReplyAfterQuote.setChecked(mAccount.isReplyAfterQuote());
|
||||||
|
|
||||||
@ -695,12 +700,19 @@ public class AccountSettings extends K9PreferenceActivity {
|
|||||||
mAccount.setMessageFormat(Account.MessageFormat.valueOf(mMessageFormat.getValue()));
|
mAccount.setMessageFormat(Account.MessageFormat.valueOf(mMessageFormat.getValue()));
|
||||||
mAccount.setQuoteStyle(QuoteStyle.valueOf(mQuoteStyle.getValue()));
|
mAccount.setQuoteStyle(QuoteStyle.valueOf(mQuoteStyle.getValue()));
|
||||||
mAccount.setQuotePrefix(mAccountQuotePrefix.getText());
|
mAccount.setQuotePrefix(mAccountQuotePrefix.getText());
|
||||||
|
mAccount.setDefaultQuotedTextShown(mAccountDefaultQuotedTextShown.isChecked());
|
||||||
mAccount.setReplyAfterQuote(mReplyAfterQuote.isChecked());
|
mAccount.setReplyAfterQuote(mReplyAfterQuote.isChecked());
|
||||||
mAccount.setCryptoApp(mCryptoApp.getValue());
|
mAccount.setCryptoApp(mCryptoApp.getValue());
|
||||||
mAccount.setCryptoAutoSignature(mCryptoAutoSignature.isChecked());
|
mAccount.setCryptoAutoSignature(mCryptoAutoSignature.isChecked());
|
||||||
mAccount.setLocalStorageProviderId(mLocalStorageProvider.getValue());
|
mAccount.setLocalStorageProviderId(mLocalStorageProvider.getValue());
|
||||||
|
|
||||||
|
// In webdav account we use the exact folder name also for inbox,
|
||||||
|
// since it varies because of internationalization
|
||||||
|
if (mAccount.getStoreUri().startsWith("webdav"))
|
||||||
|
mAccount.setAutoExpandFolderName(mAutoExpandFolder.getValue());
|
||||||
|
else
|
||||||
mAccount.setAutoExpandFolderName(reverseTranslateFolder(mAutoExpandFolder.getValue()));
|
mAccount.setAutoExpandFolderName(reverseTranslateFolder(mAutoExpandFolder.getValue()));
|
||||||
|
|
||||||
mAccount.setArchiveFolderName(mArchiveFolder.getValue());
|
mAccount.setArchiveFolderName(mArchiveFolder.getValue());
|
||||||
mAccount.setDraftsFolderName(mDraftsFolder.getValue());
|
mAccount.setDraftsFolderName(mDraftsFolder.getValue());
|
||||||
mAccount.setSentFolderName(mSentFolder.getValue());
|
mAccount.setSentFolderName(mSentFolder.getValue());
|
||||||
@ -826,7 +838,7 @@ public class AccountSettings extends K9PreferenceActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String translateFolder(String in) {
|
private String translateFolder(String in) {
|
||||||
if (K9.INBOX.equalsIgnoreCase(in)) {
|
if (mAccount.getInboxFolderName().equalsIgnoreCase(in)) {
|
||||||
return getString(R.string.special_mailbox_name_inbox);
|
return getString(R.string.special_mailbox_name_inbox);
|
||||||
} else {
|
} else {
|
||||||
return in;
|
return in;
|
||||||
@ -835,7 +847,7 @@ public class AccountSettings extends K9PreferenceActivity {
|
|||||||
|
|
||||||
private String reverseTranslateFolder(String in) {
|
private String reverseTranslateFolder(String in) {
|
||||||
if (getString(R.string.special_mailbox_name_inbox).equals(in)) {
|
if (getString(R.string.special_mailbox_name_inbox).equals(in)) {
|
||||||
return K9.INBOX;
|
return mAccount.getInboxFolderName();
|
||||||
} else {
|
} else {
|
||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
@ -867,7 +879,7 @@ public class AccountSettings extends K9PreferenceActivity {
|
|||||||
Iterator <? extends Folder > iter = folders.iterator();
|
Iterator <? extends Folder > iter = folders.iterator();
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
Folder folder = iter.next();
|
Folder folder = iter.next();
|
||||||
if (mAccount.getOutboxFolderName().equalsIgnoreCase(folder.getName())) {
|
if (mAccount.getOutboxFolderName().equals(folder.getName())) {
|
||||||
iter.remove();
|
iter.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,6 @@ import android.widget.CheckBox;
|
|||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import com.fsck.k9.*;
|
import com.fsck.k9.*;
|
||||||
import com.fsck.k9.activity.K9Activity;
|
import com.fsck.k9.activity.K9Activity;
|
||||||
import com.fsck.k9.helper.Contacts;
|
|
||||||
import com.fsck.k9.helper.Utility;
|
import com.fsck.k9.helper.Utility;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
@ -133,18 +132,12 @@ public class AccountSetupBasics extends K9Activity
|
|||||||
|
|
||||||
private String getOwnerName() {
|
private String getOwnerName() {
|
||||||
String name = null;
|
String name = null;
|
||||||
try {
|
|
||||||
name = Contacts.getInstance(this).getOwnerName();
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(K9.LOG_TAG, "Could not get owner name, using default account name", e);
|
|
||||||
}
|
|
||||||
if (name == null || name.length() == 0) {
|
|
||||||
try {
|
try {
|
||||||
name = getDefaultAccountName();
|
name = getDefaultAccountName();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e(K9.LOG_TAG, "Could not get default account name", e);
|
Log.e(K9.LOG_TAG, "Could not get default account name", e);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (name == null) {
|
if (name == null) {
|
||||||
name = "";
|
name = "";
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import android.app.Activity;
|
|||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
@ -30,6 +31,8 @@ import java.security.cert.CertificateEncodingException;
|
|||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks the given settings to make sure that they can be used to send and
|
* Checks the given settings to make sure that they can be used to send and
|
||||||
@ -116,7 +119,7 @@ public class AccountSetupCheckSettings extends K9Activity implements OnClickList
|
|||||||
setMessage(R.string.account_setup_check_settings_fetch);
|
setMessage(R.string.account_setup_check_settings_fetch);
|
||||||
}
|
}
|
||||||
MessagingController.getInstance(getApplication()).listFoldersSynchronous(mAccount, true, null);
|
MessagingController.getInstance(getApplication()).listFoldersSynchronous(mAccount, true, null);
|
||||||
MessagingController.getInstance(getApplication()).synchronizeMailbox(mAccount, K9.INBOX , null, null);
|
MessagingController.getInstance(getApplication()).synchronizeMailbox(mAccount, mAccount.getInboxFolderName(), null, null);
|
||||||
}
|
}
|
||||||
if (mDestroyed) {
|
if (mDestroyed) {
|
||||||
return;
|
return;
|
||||||
@ -249,8 +252,78 @@ public class AccountSetupCheckSettings extends K9Activity implements OnClickList
|
|||||||
}
|
}
|
||||||
for (int i = 0; i < chain.length; i++) {
|
for (int i = 0; i < chain.length; i++) {
|
||||||
// display certificate chain information
|
// display certificate chain information
|
||||||
|
//TODO: localize this strings
|
||||||
chainInfo.append("Certificate chain[" + i + "]:\n");
|
chainInfo.append("Certificate chain[" + i + "]:\n");
|
||||||
chainInfo.append("Subject: " + chain[i].getSubjectDN().toString() + "\n");
|
chainInfo.append("Subject: " + chain[i].getSubjectDN().toString() + "\n");
|
||||||
|
|
||||||
|
// display SubjectAltNames too
|
||||||
|
// (the user may be mislead into mistrusting a certificate
|
||||||
|
// by a subjectDN not matching the server even though a
|
||||||
|
// SubjectAltName matches)
|
||||||
|
try {
|
||||||
|
final Collection < List<? >> subjectAlternativeNames = chain[i].getSubjectAlternativeNames();
|
||||||
|
if (subjectAlternativeNames != null) {
|
||||||
|
// The list of SubjectAltNames may be very long
|
||||||
|
//TODO: localize this string
|
||||||
|
StringBuffer altNamesText = new StringBuffer("Subject has " + subjectAlternativeNames.size() + " alternative names\n");
|
||||||
|
|
||||||
|
// we need these for matching
|
||||||
|
String storeURIHost = (Uri.parse(mAccount.getStoreUri())).getHost();
|
||||||
|
String transportURIHost = (Uri.parse(mAccount.getTransportUri())).getHost();
|
||||||
|
|
||||||
|
for (List<?> subjectAlternativeName : subjectAlternativeNames) {
|
||||||
|
Integer type = (Integer)subjectAlternativeName.get(0);
|
||||||
|
Object value = subjectAlternativeName.get(1);
|
||||||
|
String name = "";
|
||||||
|
switch (type.intValue()) {
|
||||||
|
case 0:
|
||||||
|
Log.w(K9.LOG_TAG, "SubjectAltName of type OtherName not supported.");
|
||||||
|
continue;
|
||||||
|
case 1: // RFC822Name
|
||||||
|
name = (String)value;
|
||||||
|
break;
|
||||||
|
case 2: // DNSName
|
||||||
|
name = (String)value;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
Log.w(K9.LOG_TAG, "unsupported SubjectAltName of type x400Address");
|
||||||
|
continue;
|
||||||
|
case 4:
|
||||||
|
Log.w(K9.LOG_TAG, "unsupported SubjectAltName of type directoryName");
|
||||||
|
continue;
|
||||||
|
case 5:
|
||||||
|
Log.w(K9.LOG_TAG, "unsupported SubjectAltName of type ediPartyName");
|
||||||
|
continue;
|
||||||
|
case 6: // Uri
|
||||||
|
name = (String)value;
|
||||||
|
break;
|
||||||
|
case 7: // ip-address
|
||||||
|
name = (String)value;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Log.w(K9.LOG_TAG, "unsupported SubjectAltName of unknown type");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if some of the SubjectAltNames match the store or transport -host,
|
||||||
|
// display them
|
||||||
|
if (name.equalsIgnoreCase(storeURIHost) || name.equalsIgnoreCase(transportURIHost)) {
|
||||||
|
//TODO: localize this string
|
||||||
|
altNamesText.append("Subject(alt): " + name + ",...\n");
|
||||||
|
} else if (name.startsWith("*.")) {
|
||||||
|
if (storeURIHost.endsWith(name.substring(2)) || transportURIHost.endsWith(name.substring(2))) {
|
||||||
|
//TODO: localize this string
|
||||||
|
altNamesText.append("Subject(alt): " + name + ",...\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
chainInfo.append(altNamesText);
|
||||||
|
}
|
||||||
|
} catch (Exception e1) {
|
||||||
|
// don't fail just because of subjectAltNames
|
||||||
|
Log.w(K9.LOG_TAG, "cannot display SubjectAltNames in dialog", e1);
|
||||||
|
}
|
||||||
|
|
||||||
chainInfo.append("Issuer: " + chain[i].getIssuerDN().toString() + "\n");
|
chainInfo.append("Issuer: " + chain[i].getIssuerDN().toString() + "\n");
|
||||||
if (sha1 != null) {
|
if (sha1 != null) {
|
||||||
sha1.reset();
|
sha1.reset();
|
||||||
|
@ -65,10 +65,10 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
|
|||||||
private Button mNextButton;
|
private Button mNextButton;
|
||||||
private Account mAccount;
|
private Account mAccount;
|
||||||
private boolean mMakeDefault;
|
private boolean mMakeDefault;
|
||||||
private CheckBox compressionMobile;
|
private CheckBox mCompressionMobile;
|
||||||
private CheckBox compressionWifi;
|
private CheckBox mCompressionWifi;
|
||||||
private CheckBox compressionOther;
|
private CheckBox mCompressionOther;
|
||||||
private CheckBox subscribedFoldersOnly;
|
private CheckBox mSubscribedFoldersOnly;
|
||||||
|
|
||||||
public static void actionIncomingSettings(Activity context, Account account, boolean makeDefault) {
|
public static void actionIncomingSettings(Activity context, Account account, boolean makeDefault) {
|
||||||
Intent i = new Intent(context, AccountSetupIncoming.class);
|
Intent i = new Intent(context, AccountSetupIncoming.class);
|
||||||
@ -101,10 +101,10 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
|
|||||||
mWebdavAuthPathView = (EditText)findViewById(R.id.webdav_auth_path);
|
mWebdavAuthPathView = (EditText)findViewById(R.id.webdav_auth_path);
|
||||||
mWebdavMailboxPathView = (EditText)findViewById(R.id.webdav_mailbox_path);
|
mWebdavMailboxPathView = (EditText)findViewById(R.id.webdav_mailbox_path);
|
||||||
mNextButton = (Button)findViewById(R.id.next);
|
mNextButton = (Button)findViewById(R.id.next);
|
||||||
compressionMobile = (CheckBox)findViewById(R.id.compression_mobile);
|
mCompressionMobile = (CheckBox)findViewById(R.id.compression_mobile);
|
||||||
compressionWifi = (CheckBox)findViewById(R.id.compression_wifi);
|
mCompressionWifi = (CheckBox)findViewById(R.id.compression_wifi);
|
||||||
compressionOther = (CheckBox)findViewById(R.id.compression_other);
|
mCompressionOther = (CheckBox)findViewById(R.id.compression_other);
|
||||||
subscribedFoldersOnly = (CheckBox)findViewById(R.id.subscribed_folders_only);
|
mSubscribedFoldersOnly = (CheckBox)findViewById(R.id.subscribed_folders_only);
|
||||||
|
|
||||||
mNextButton.setOnClickListener(this);
|
mNextButton.setOnClickListener(this);
|
||||||
|
|
||||||
@ -236,6 +236,7 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
|
|||||||
findViewById(R.id.webdav_auth_path_section).setVisibility(View.GONE);
|
findViewById(R.id.webdav_auth_path_section).setVisibility(View.GONE);
|
||||||
findViewById(R.id.compression_section).setVisibility(View.GONE);
|
findViewById(R.id.compression_section).setVisibility(View.GONE);
|
||||||
findViewById(R.id.compression_label).setVisibility(View.GONE);
|
findViewById(R.id.compression_label).setVisibility(View.GONE);
|
||||||
|
mSubscribedFoldersOnly.setVisibility(View.GONE);
|
||||||
mAccount.setDeletePolicy(Account.DELETE_POLICY_NEVER);
|
mAccount.setDeletePolicy(Account.DELETE_POLICY_NEVER);
|
||||||
} else if (uri.getScheme().startsWith("imap")) {
|
} else if (uri.getScheme().startsWith("imap")) {
|
||||||
serverLabelView.setText(R.string.account_setup_incoming_imap_server_label);
|
serverLabelView.setText(R.string.account_setup_incoming_imap_server_label);
|
||||||
@ -266,7 +267,7 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
|
|||||||
findViewById(R.id.account_auth_type).setVisibility(View.GONE);
|
findViewById(R.id.account_auth_type).setVisibility(View.GONE);
|
||||||
findViewById(R.id.compression_section).setVisibility(View.GONE);
|
findViewById(R.id.compression_section).setVisibility(View.GONE);
|
||||||
findViewById(R.id.compression_label).setVisibility(View.GONE);
|
findViewById(R.id.compression_label).setVisibility(View.GONE);
|
||||||
subscribedFoldersOnly.setVisibility(View.GONE);
|
mSubscribedFoldersOnly.setVisibility(View.GONE);
|
||||||
if (uri.getPath() != null && uri.getPath().length() > 0) {
|
if (uri.getPath() != null && uri.getPath().length() > 0) {
|
||||||
String[] pathParts = uri.getPath().split("\\|");
|
String[] pathParts = uri.getPath().split("\\|");
|
||||||
|
|
||||||
@ -299,9 +300,9 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
|
|||||||
SpinnerOption.setSpinnerOptionValue(mSecurityTypeView, i);
|
SpinnerOption.setSpinnerOptionValue(mSecurityTypeView, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
compressionMobile.setChecked(mAccount.useCompression(Account.TYPE_MOBILE));
|
mCompressionMobile.setChecked(mAccount.useCompression(Account.TYPE_MOBILE));
|
||||||
compressionWifi.setChecked(mAccount.useCompression(Account.TYPE_WIFI));
|
mCompressionWifi.setChecked(mAccount.useCompression(Account.TYPE_WIFI));
|
||||||
compressionOther.setChecked(mAccount.useCompression(Account.TYPE_OTHER));
|
mCompressionOther.setChecked(mAccount.useCompression(Account.TYPE_OTHER));
|
||||||
|
|
||||||
if (uri.getHost() != null) {
|
if (uri.getHost() != null) {
|
||||||
mServerView.setText(uri.getHost());
|
mServerView.setText(uri.getHost());
|
||||||
@ -313,7 +314,7 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
|
|||||||
updatePortFromSecurityType();
|
updatePortFromSecurityType();
|
||||||
}
|
}
|
||||||
|
|
||||||
subscribedFoldersOnly.setChecked(mAccount.subscribedFoldersOnly());
|
mSubscribedFoldersOnly.setChecked(mAccount.subscribedFoldersOnly());
|
||||||
|
|
||||||
validateFields();
|
validateFields();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -425,10 +426,10 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
|
|||||||
mAccount.setStoreUri(uri.toString());
|
mAccount.setStoreUri(uri.toString());
|
||||||
|
|
||||||
|
|
||||||
mAccount.setCompression(Account.TYPE_MOBILE, compressionMobile.isChecked());
|
mAccount.setCompression(Account.TYPE_MOBILE, mCompressionMobile.isChecked());
|
||||||
mAccount.setCompression(Account.TYPE_WIFI, compressionWifi.isChecked());
|
mAccount.setCompression(Account.TYPE_WIFI, mCompressionWifi.isChecked());
|
||||||
mAccount.setCompression(Account.TYPE_OTHER, compressionOther.isChecked());
|
mAccount.setCompression(Account.TYPE_OTHER, mCompressionOther.isChecked());
|
||||||
mAccount.setSubscribedFoldersOnly(subscribedFoldersOnly.isChecked());
|
mAccount.setSubscribedFoldersOnly(mSubscribedFoldersOnly.isChecked());
|
||||||
|
|
||||||
AccountSetupCheckSettings.actionCheckSettings(this, mAccount, true, false);
|
AccountSetupCheckSettings.actionCheckSettings(this, mAccount, true, false);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -16,6 +16,8 @@ import android.widget.CompoundButton.OnCheckedChangeListener;
|
|||||||
import com.fsck.k9.*;
|
import com.fsck.k9.*;
|
||||||
import com.fsck.k9.activity.K9Activity;
|
import com.fsck.k9.activity.K9Activity;
|
||||||
import com.fsck.k9.helper.Utility;
|
import com.fsck.k9.helper.Utility;
|
||||||
|
import com.fsck.k9.mail.transport.SmtpTransport;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
@ -45,10 +47,13 @@ public class AccountSetupOutgoing extends K9Activity implements OnClickListener,
|
|||||||
"webdav", "webdav+ssl", "webdav+ssl+", "webdav+tls", "webdav+tls+"
|
"webdav", "webdav+ssl", "webdav+ssl+", "webdav+tls", "webdav+tls+"
|
||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private static final String authTypes[] = {
|
private static final String authTypes[] = {
|
||||||
"PLAIN", "CRAM_MD5"
|
SmtpTransport.AUTH_AUTOMATIC,
|
||||||
|
SmtpTransport.AUTH_LOGIN,
|
||||||
|
SmtpTransport.AUTH_PLAIN,
|
||||||
|
SmtpTransport.AUTH_CRAM_MD5,
|
||||||
};
|
};
|
||||||
|
|
||||||
private EditText mUsernameView;
|
private EditText mUsernameView;
|
||||||
private EditText mPasswordView;
|
private EditText mPasswordView;
|
||||||
private EditText mServerView;
|
private EditText mServerView;
|
||||||
@ -117,14 +122,10 @@ public class AccountSetupOutgoing extends K9Activity implements OnClickListener,
|
|||||||
new SpinnerOption(4, getString(R.string.account_setup_incoming_security_tls_label)),
|
new SpinnerOption(4, getString(R.string.account_setup_incoming_security_tls_label)),
|
||||||
};
|
};
|
||||||
|
|
||||||
// This needs to be kept in sync with the list at the top of the file.
|
SpinnerOption authTypeSpinnerOptions[] = new SpinnerOption[authTypes.length];
|
||||||
// that makes me somewhat unhappy
|
for (int i = 0; i < authTypes.length; i++) {
|
||||||
SpinnerOption authTypeSpinnerOptions[] = {
|
authTypeSpinnerOptions[i] = new SpinnerOption(i, authTypes[i]);
|
||||||
new SpinnerOption(0, "PLAIN"),
|
}
|
||||||
new SpinnerOption(1, "CRAM_MD5")
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ArrayAdapter<SpinnerOption> securityTypesAdapter = new ArrayAdapter<SpinnerOption>(this,
|
ArrayAdapter<SpinnerOption> securityTypesAdapter = new ArrayAdapter<SpinnerOption>(this,
|
||||||
android.R.layout.simple_spinner_item, securityTypes);
|
android.R.layout.simple_spinner_item, securityTypes);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.fsck.k9.activity.setup;
|
package com.fsck.k9.activity.setup;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
@ -8,11 +9,13 @@ import android.content.Context;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.content.SharedPreferences.Editor;
|
import android.content.SharedPreferences.Editor;
|
||||||
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.preference.CheckBoxPreference;
|
import android.preference.CheckBoxPreference;
|
||||||
import android.preference.ListPreference;
|
import android.preference.ListPreference;
|
||||||
import android.preference.Preference;
|
import android.preference.Preference;
|
||||||
|
import android.preference.Preference.OnPreferenceClickListener;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
@ -23,6 +26,8 @@ import com.fsck.k9.activity.Accounts;
|
|||||||
import com.fsck.k9.activity.ColorPickerDialog;
|
import com.fsck.k9.activity.ColorPickerDialog;
|
||||||
import com.fsck.k9.activity.K9PreferenceActivity;
|
import com.fsck.k9.activity.K9PreferenceActivity;
|
||||||
import com.fsck.k9.helper.DateFormatter;
|
import com.fsck.k9.helper.DateFormatter;
|
||||||
|
import com.fsck.k9.helper.FileBrowserHelper;
|
||||||
|
import com.fsck.k9.helper.FileBrowserHelper.FileBrowserFailOverCallback;
|
||||||
import com.fsck.k9.preferences.CheckBoxListPreference;
|
import com.fsck.k9.preferences.CheckBoxListPreference;
|
||||||
import com.fsck.k9.preferences.TimePickerPreference;
|
import com.fsck.k9.preferences.TimePickerPreference;
|
||||||
|
|
||||||
@ -76,7 +81,9 @@ public class Prefs extends K9PreferenceActivity {
|
|||||||
private static final String PREFERENCE_DEBUG_LOGGING = "debug_logging";
|
private static final String PREFERENCE_DEBUG_LOGGING = "debug_logging";
|
||||||
private static final String PREFERENCE_SENSITIVE_LOGGING = "sensitive_logging";
|
private static final String PREFERENCE_SENSITIVE_LOGGING = "sensitive_logging";
|
||||||
|
|
||||||
|
private static final String PREFERENCE_ATTACHMENT_DEF_PATH = "attachment_default_path";
|
||||||
|
|
||||||
|
private static final int ACTIVITY_CHOOSE_FOLDER = 1;
|
||||||
private ListPreference mLanguage;
|
private ListPreference mLanguage;
|
||||||
private ListPreference mTheme;
|
private ListPreference mTheme;
|
||||||
private ListPreference mDateFormat;
|
private ListPreference mDateFormat;
|
||||||
@ -110,7 +117,7 @@ public class Prefs extends K9PreferenceActivity {
|
|||||||
private CheckBoxPreference mQuietTimeEnabled;
|
private CheckBoxPreference mQuietTimeEnabled;
|
||||||
private com.fsck.k9.preferences.TimePickerPreference mQuietTimeStarts;
|
private com.fsck.k9.preferences.TimePickerPreference mQuietTimeStarts;
|
||||||
private com.fsck.k9.preferences.TimePickerPreference mQuietTimeEnds;
|
private com.fsck.k9.preferences.TimePickerPreference mQuietTimeEnds;
|
||||||
|
private Preference mAttachmentPathPreference;
|
||||||
|
|
||||||
|
|
||||||
public static void actionPrefs(Context context) {
|
public static void actionPrefs(Context context) {
|
||||||
@ -298,6 +305,36 @@ public class Prefs extends K9PreferenceActivity {
|
|||||||
|
|
||||||
mDebugLogging.setChecked(K9.DEBUG);
|
mDebugLogging.setChecked(K9.DEBUG);
|
||||||
mSensitiveLogging.setChecked(K9.DEBUG_SENSITIVE);
|
mSensitiveLogging.setChecked(K9.DEBUG_SENSITIVE);
|
||||||
|
|
||||||
|
mAttachmentPathPreference = findPreference(PREFERENCE_ATTACHMENT_DEF_PATH);
|
||||||
|
mAttachmentPathPreference.setSummary(K9.getAttachmentDefaultPath());
|
||||||
|
mAttachmentPathPreference
|
||||||
|
.setOnPreferenceClickListener(new OnPreferenceClickListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onPreferenceClick(Preference preference) {
|
||||||
|
FileBrowserHelper
|
||||||
|
.getInstance()
|
||||||
|
.showFileBrowserActivity(Prefs.this,
|
||||||
|
new File(K9.getAttachmentDefaultPath()),
|
||||||
|
ACTIVITY_CHOOSE_FOLDER, callback);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileBrowserFailOverCallback callback = new FileBrowserFailOverCallback() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPathEntered(String path) {
|
||||||
|
mAttachmentPathPreference.setSummary(path);
|
||||||
|
K9.setAttachmentDefaultPath(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCancel() {
|
||||||
|
// canceled, do nothing
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void saveSettings() {
|
private void saveSettings() {
|
||||||
@ -336,7 +373,7 @@ public class Prefs extends K9PreferenceActivity {
|
|||||||
|
|
||||||
|
|
||||||
K9.setZoomControlsEnabled(mZoomControlsEnabled.isChecked());
|
K9.setZoomControlsEnabled(mZoomControlsEnabled.isChecked());
|
||||||
|
K9.setAttachmentDefaultPath(mAttachmentPathPreference.getSummary().toString());
|
||||||
boolean needsRefresh = K9.setBackgroundOps(mBackgroundOps.getValue());
|
boolean needsRefresh = K9.setBackgroundOps(mBackgroundOps.getValue());
|
||||||
K9.setUseGalleryBugWorkaround(mUseGalleryBugWorkaround.isChecked());
|
K9.setUseGalleryBugWorkaround(mUseGalleryBugWorkaround.isChecked());
|
||||||
|
|
||||||
@ -381,4 +418,25 @@ public class Prefs extends K9PreferenceActivity {
|
|||||||
},
|
},
|
||||||
K9.getContactNameColor()).show();
|
K9.getContactNameColor()).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
|
switch (requestCode) {
|
||||||
|
case ACTIVITY_CHOOSE_FOLDER:
|
||||||
|
if (resultCode == RESULT_OK && data != null) {
|
||||||
|
// obtain the filename
|
||||||
|
Uri fileUri = data.getData();
|
||||||
|
if (fileUri != null) {
|
||||||
|
String filePath = fileUri.getPath();
|
||||||
|
if (filePath != null) {
|
||||||
|
mAttachmentPathPreference.setSummary(filePath.toString());
|
||||||
|
K9.setAttachmentDefaultPath(filePath.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
super.onActivityResult(requestCode, resultCode, data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -719,7 +719,7 @@ public class MessagingController implements Runnable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Never exclude the INBOX (see issue 1817)
|
// Never exclude the INBOX (see issue 1817)
|
||||||
else if (noSpecialFolders && !localFolderName.equalsIgnoreCase(K9.INBOX) &&
|
else if (noSpecialFolders && !localFolderName.equalsIgnoreCase(account.getInboxFolderName()) &&
|
||||||
!localFolderName.equals(account.getArchiveFolderName()) && account.isSpecialFolder(localFolderName)) {
|
!localFolderName.equals(account.getArchiveFolderName()) && account.isSpecialFolder(localFolderName)) {
|
||||||
include = false;
|
include = false;
|
||||||
} else if (displayableOnly && modeMismatch(account.getFolderDisplayMode(), folder.getDisplayClass())) {
|
} else if (displayableOnly && modeMismatch(account.getFolderDisplayMode(), folder.getDisplayClass())) {
|
||||||
@ -793,7 +793,7 @@ public class MessagingController implements Runnable {
|
|||||||
LocalStore localStore = account.getLocalStore();
|
LocalStore localStore = account.getLocalStore();
|
||||||
LocalFolder localFolder = localStore.getFolder(folder);
|
LocalFolder localFolder = localStore.getFolder(folder);
|
||||||
if (localFolder.getVisibleLimit() > 0) {
|
if (localFolder.getVisibleLimit() > 0) {
|
||||||
localFolder.setVisibleLimit(localFolder.getVisibleLimit() + account.getDisplayCount());
|
localFolder.setVisibleLimit(localFolder.getVisibleLimit() + localFolder.getMessageCount());
|
||||||
}
|
}
|
||||||
synchronizeMailbox(account, folder, listener, null);
|
synchronizeMailbox(account, folder, listener, null);
|
||||||
} catch (MessagingException me) {
|
} catch (MessagingException me) {
|
||||||
@ -1161,12 +1161,32 @@ public class MessagingController implements Runnable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches the messages described by inputMessages from the remote store and writes them to
|
||||||
|
* local storage.
|
||||||
|
*
|
||||||
|
* @param account
|
||||||
|
* The account the remote store belongs to.
|
||||||
|
* @param remoteFolder
|
||||||
|
* The remote folder to download messages from.
|
||||||
|
* @param localFolder
|
||||||
|
* The {@link LocalFolder} instance corresponding to the remote folder.
|
||||||
|
* @param inputMessages
|
||||||
|
* A list of messages objects that store the UIDs of which messages to download.
|
||||||
|
* @param flagSyncOnly
|
||||||
|
* Only flags will be fetched from the remote store if this is {@code true}.
|
||||||
|
*
|
||||||
|
* @return The number of downloaded messages that are not flagged as {@link Flag#SEEN}.
|
||||||
|
*
|
||||||
|
* @throws MessagingException
|
||||||
|
*/
|
||||||
private int downloadMessages(final Account account, final Folder remoteFolder,
|
private int downloadMessages(final Account account, final Folder remoteFolder,
|
||||||
final LocalFolder localFolder, List<Message> inputMessages, boolean flagSyncOnly) throws MessagingException {
|
final LocalFolder localFolder, List<Message> inputMessages,
|
||||||
|
boolean flagSyncOnly) throws MessagingException {
|
||||||
|
|
||||||
final Date earliestDate = account.getEarliestPollDate();
|
final Date earliestDate = account.getEarliestPollDate();
|
||||||
Date downloadStarted = new Date(); // now
|
Date downloadStarted = new Date(); // now
|
||||||
|
|
||||||
|
|
||||||
if (earliestDate != null) {
|
if (earliestDate != null) {
|
||||||
if (K9.DEBUG) {
|
if (K9.DEBUG) {
|
||||||
Log.d(K9.LOG_TAG, "Only syncing messages after " + earliestDate);
|
Log.d(K9.LOG_TAG, "Only syncing messages after " + earliestDate);
|
||||||
@ -1541,7 +1561,7 @@ public class MessagingController implements Runnable {
|
|||||||
remoteFolder.fetch(smallMessages.toArray(new Message[smallMessages.size()]),
|
remoteFolder.fetch(smallMessages.toArray(new Message[smallMessages.size()]),
|
||||||
fp, new MessageRetrievalListener() {
|
fp, new MessageRetrievalListener() {
|
||||||
@Override
|
@Override
|
||||||
public void messageFinished(Message message, int number, int ofTotal) {
|
public void messageFinished(final Message message, int number, int ofTotal) {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
if (!shouldImportMessage(account, folder, message, progress, earliestDate)) {
|
if (!shouldImportMessage(account, folder, message, progress, earliestDate)) {
|
||||||
@ -1557,6 +1577,13 @@ public class MessagingController implements Runnable {
|
|||||||
progress.incrementAndGet();
|
progress.incrementAndGet();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Increment the number of "new messages" if the newly downloaded message is
|
||||||
|
// not marked as read.
|
||||||
|
if (!localMessage.isSet(Flag.SEEN)) {
|
||||||
|
newMessages.incrementAndGet();
|
||||||
|
}
|
||||||
|
|
||||||
if (K9.DEBUG)
|
if (K9.DEBUG)
|
||||||
Log.v(K9.LOG_TAG, "About to notify listeners that we got a new small message "
|
Log.v(K9.LOG_TAG, "About to notify listeners that we got a new small message "
|
||||||
+ account + ":" + folder + ":" + message.getUid());
|
+ account + ":" + folder + ":" + message.getUid());
|
||||||
@ -1572,7 +1599,6 @@ public class MessagingController implements Runnable {
|
|||||||
// Send a notification of this message
|
// Send a notification of this message
|
||||||
|
|
||||||
if (shouldNotifyForMessage(account, localFolder, message)) {
|
if (shouldNotifyForMessage(account, localFolder, message)) {
|
||||||
newMessages.incrementAndGet();
|
|
||||||
notifyAccount(mApplication, account, message, unreadBeforeStart, newMessages);
|
notifyAccount(mApplication, account, message, unreadBeforeStart, newMessages);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1691,6 +1717,13 @@ public class MessagingController implements Runnable {
|
|||||||
// Update the listener with what we've found
|
// Update the listener with what we've found
|
||||||
progress.incrementAndGet();
|
progress.incrementAndGet();
|
||||||
Message localMessage = localFolder.getMessage(message.getUid());
|
Message localMessage = localFolder.getMessage(message.getUid());
|
||||||
|
|
||||||
|
// Increment the number of "new messages" if the newly downloaded message is
|
||||||
|
// not marked as read.
|
||||||
|
if (!localMessage.isSet(Flag.SEEN)) {
|
||||||
|
newMessages.incrementAndGet();
|
||||||
|
}
|
||||||
|
|
||||||
for (MessagingListener l : getListeners()) {
|
for (MessagingListener l : getListeners()) {
|
||||||
l.synchronizeMailboxAddOrUpdateMessage(account, folder, localMessage);
|
l.synchronizeMailboxAddOrUpdateMessage(account, folder, localMessage);
|
||||||
l.synchronizeMailboxProgress(account, folder, progress.get(), todo);
|
l.synchronizeMailboxProgress(account, folder, progress.get(), todo);
|
||||||
@ -1701,7 +1734,6 @@ public class MessagingController implements Runnable {
|
|||||||
|
|
||||||
// Send a notification of this message
|
// Send a notification of this message
|
||||||
if (shouldNotifyForMessage(account, localFolder, message)) {
|
if (shouldNotifyForMessage(account, localFolder, message)) {
|
||||||
newMessages.incrementAndGet();
|
|
||||||
notifyAccount(mApplication, account, message, unreadBeforeStart, newMessages);
|
notifyAccount(mApplication, account, message, unreadBeforeStart, newMessages);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2174,14 +2206,7 @@ public class MessagingController implements Runnable {
|
|||||||
|
|
||||||
Store remoteStore = account.getRemoteStore();
|
Store remoteStore = account.getRemoteStore();
|
||||||
Folder remoteFolder = remoteStore.getFolder(folder);
|
Folder remoteFolder = remoteStore.getFolder(folder);
|
||||||
if (!remoteFolder.exists() ||
|
if (!remoteFolder.exists() || !remoteFolder.isFlagSupported(flag)) {
|
||||||
/*
|
|
||||||
* Don't proceed if the remote folder doesn't support flags and
|
|
||||||
* the flag to be changed isn't the deleted flag. This avoids
|
|
||||||
* unnecessary connections to POP3 servers.
|
|
||||||
*/
|
|
||||||
// TODO: This should actually call a supportsSettingFlag(flag) method.
|
|
||||||
(!remoteFolder.supportsFetchingFlags() && !Flag.DELETED.equals(flag))) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2385,7 +2410,7 @@ public class MessagingController implements Runnable {
|
|||||||
Store remoteStore = account.getRemoteStore();
|
Store remoteStore = account.getRemoteStore();
|
||||||
remoteFolder = remoteStore.getFolder(folder);
|
remoteFolder = remoteStore.getFolder(folder);
|
||||||
|
|
||||||
if (!remoteFolder.exists()) {
|
if (!remoteFolder.exists() || !remoteFolder.isFlagSupported(Flag.SEEN)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
remoteFolder.open(OpenMode.READ_WRITE);
|
remoteFolder.open(OpenMode.READ_WRITE);
|
||||||
@ -2880,7 +2905,7 @@ public class MessagingController implements Runnable {
|
|||||||
(NotificationManager)mApplication.getSystemService(Context.NOTIFICATION_SERVICE);
|
(NotificationManager)mApplication.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
Notification notif = new Notification(R.drawable.ic_menu_refresh,
|
Notification notif = new Notification(R.drawable.ic_menu_refresh,
|
||||||
mApplication.getString(R.string.notification_bg_send_ticker, account.getDescription()), System.currentTimeMillis());
|
mApplication.getString(R.string.notification_bg_send_ticker, account.getDescription()), System.currentTimeMillis());
|
||||||
Intent intent = MessageList.actionHandleFolderIntent(mApplication, account, K9.INBOX);
|
Intent intent = MessageList.actionHandleFolderIntent(mApplication, account, account.getInboxFolderName());
|
||||||
PendingIntent pi = PendingIntent.getActivity(mApplication, 0, intent, 0);
|
PendingIntent pi = PendingIntent.getActivity(mApplication, 0, intent, 0);
|
||||||
notif.setLatestEventInfo(mApplication, mApplication.getString(R.string.notification_bg_send_title),
|
notif.setLatestEventInfo(mApplication, mApplication.getString(R.string.notification_bg_send_title),
|
||||||
account.getDescription() , pi);
|
account.getDescription() , pi);
|
||||||
@ -2922,7 +2947,7 @@ public class MessagingController implements Runnable {
|
|||||||
Notification notif = new Notification(R.drawable.ic_menu_refresh,
|
Notification notif = new Notification(R.drawable.ic_menu_refresh,
|
||||||
mApplication.getString(R.string.notification_bg_sync_ticker, account.getDescription(), folder.getName()),
|
mApplication.getString(R.string.notification_bg_sync_ticker, account.getDescription(), folder.getName()),
|
||||||
System.currentTimeMillis());
|
System.currentTimeMillis());
|
||||||
Intent intent = MessageList.actionHandleFolderIntent(mApplication, account, K9.INBOX);
|
Intent intent = MessageList.actionHandleFolderIntent(mApplication, account, account.getInboxFolderName());
|
||||||
PendingIntent pi = PendingIntent.getActivity(mApplication, 0, intent, 0);
|
PendingIntent pi = PendingIntent.getActivity(mApplication, 0, intent, 0);
|
||||||
notif.setLatestEventInfo(mApplication, mApplication.getString(R.string.notification_bg_sync_title), account.getDescription()
|
notif.setLatestEventInfo(mApplication, mApplication.getString(R.string.notification_bg_sync_title), account.getDescription()
|
||||||
+ mApplication.getString(R.string.notification_bg_title_separator) + folder.getName(), pi);
|
+ mApplication.getString(R.string.notification_bg_title_separator) + folder.getName(), pi);
|
||||||
@ -3025,6 +3050,16 @@ public class MessagingController implements Runnable {
|
|||||||
|
|
||||||
localFolder.fetch(new Message[] { message }, fp, null);
|
localFolder.fetch(new Message[] { message }, fp, null);
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
|
||||||
|
if (message.getHeader(K9.IDENTITY_HEADER) != null) {
|
||||||
|
Log.v(K9.LOG_TAG, "The user has set the Outbox and Drafts folder to the same thing. " +
|
||||||
|
"This message appears to be a draft, so K-9 will not send it");
|
||||||
|
continue;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
message.setFlag(Flag.X_SEND_IN_PROGRESS, true);
|
message.setFlag(Flag.X_SEND_IN_PROGRESS, true);
|
||||||
if (K9.DEBUG)
|
if (K9.DEBUG)
|
||||||
Log.i(K9.LOG_TAG, "Sending message with UID " + message.getUid());
|
Log.i(K9.LOG_TAG, "Sending message with UID " + message.getUid());
|
||||||
@ -3856,18 +3891,31 @@ public class MessagingController implements Runnable {
|
|||||||
|
|
||||||
|
|
||||||
private boolean shouldNotifyForMessage(Account account, LocalFolder localFolder, Message message) {
|
private boolean shouldNotifyForMessage(Account account, LocalFolder localFolder, Message message) {
|
||||||
// Do not notify if the user does not have notifications
|
// If we don't even have an account name, don't show the notification.
|
||||||
// enabled or if the message has been read
|
// (This happens during initial account setup)
|
||||||
if (!account.isNotifyNewMail() || message.isSet(Flag.SEEN) || (account.getName() == null)) {
|
if (account.getName() == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do not notify if the user does not have notifications enabled or if the message has
|
||||||
|
// been read.
|
||||||
|
if (!account.isNotifyNewMail() || message.isSet(Flag.SEEN)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the account is a POP3 account and the message is older than the oldest message we've
|
||||||
|
// previously seen, then don't notify about it.
|
||||||
|
if (account.getStoreUri().startsWith("pop3") &&
|
||||||
|
message.olderThan(new Date(account.getLatestOldMessageSeenTime()))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Folder folder = message.getFolder();
|
|
||||||
if (folder != null) {
|
|
||||||
// No notification for new messages in Trash, Drafts, Spam or Sent folder.
|
// No notification for new messages in Trash, Drafts, Spam or Sent folder.
|
||||||
// But do notify if it's the INBOX (see issue 1817).
|
// But do notify if it's the INBOX (see issue 1817).
|
||||||
|
Folder folder = message.getFolder();
|
||||||
|
if (folder != null) {
|
||||||
String folderName = folder.getName();
|
String folderName = folder.getName();
|
||||||
if (!K9.INBOX.equals(folderName) &&
|
if (!account.getInboxFolderName().equals(folderName) &&
|
||||||
(account.getTrashFolderName().equals(folderName)
|
(account.getTrashFolderName().equals(folderName)
|
||||||
|| account.getDraftsFolderName().equals(folderName)
|
|| account.getDraftsFolderName().equals(folderName)
|
||||||
|| account.getSpamFolderName().equals(folderName)
|
|| account.getSpamFolderName().equals(folderName)
|
||||||
@ -3881,7 +3929,8 @@ public class MessagingController implements Runnable {
|
|||||||
Integer messageUid = Integer.parseInt(message.getUid());
|
Integer messageUid = Integer.parseInt(message.getUid());
|
||||||
if (messageUid <= localFolder.getLastUid()) {
|
if (messageUid <= localFolder.getLastUid()) {
|
||||||
if (K9.DEBUG)
|
if (K9.DEBUG)
|
||||||
Log.d(K9.LOG_TAG, "Message uid is " + messageUid + ", max message uid is " + localFolder.getLastUid() + ". Skipping notification.");
|
Log.d(K9.LOG_TAG, "Message uid is " + messageUid + ", max message uid is " +
|
||||||
|
localFolder.getLastUid() + ". Skipping notification.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
@ -3889,31 +3938,22 @@ public class MessagingController implements Runnable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Don't notify if the sender address matches one of our identities and the user chose not
|
||||||
|
// to be notified for such messages.
|
||||||
|
if (account.isAnIdentity(message.getFrom()) && !account.isNotifySelfNewMail()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** Creates a notification of new email messages
|
/**
|
||||||
* ringtone, lights, and vibration to be played
|
* Creates a notification of a newly received message.
|
||||||
*/
|
*/
|
||||||
private boolean notifyAccount(Context context, Account account, Message message, int previousUnreadMessageCount, AtomicInteger newMessageCount) {
|
private void notifyAccount(Context context, Account account, Message message,
|
||||||
// If we don't even have an account name, don't show the notification
|
int previousUnreadMessageCount, AtomicInteger newMessageCount) {
|
||||||
// (This happens during initial account setup)
|
|
||||||
//
|
|
||||||
if (account.getName() == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the account us a POP3 account and the message is older than
|
|
||||||
// the oldest message we've previously seen then don't notify about it
|
|
||||||
if (account.getStoreUri().startsWith("pop3")) {
|
|
||||||
if (message.olderThan(new Date(account.getLatestOldMessageSeenTime()))) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// If we have a message, set the notification to "<From>: <Subject>"
|
// If we have a message, set the notification to "<From>: <Subject>"
|
||||||
StringBuilder messageNotice = new StringBuilder();
|
StringBuilder messageNotice = new StringBuilder();
|
||||||
@ -3934,19 +3974,13 @@ public class MessagingController implements Runnable {
|
|||||||
}
|
}
|
||||||
// show To: if the message was sent from me
|
// show To: if the message was sent from me
|
||||||
else {
|
else {
|
||||||
if (!account.isNotifySelfNewMail()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Address[] rcpts = message.getRecipients(Message.RecipientType.TO);
|
Address[] rcpts = message.getRecipients(Message.RecipientType.TO);
|
||||||
String to = rcpts.length > 0 ? rcpts[0].toFriendly().toString() : null;
|
String to = rcpts.length > 0 ? rcpts[0].toFriendly().toString() : null;
|
||||||
if (to != null) {
|
if (to != null) {
|
||||||
messageNotice.append(String.format(context.getString(R.string.message_to_fmt), to)).append(": ").append(subject);
|
messageNotice.append(String.format(context.getString(R.string.message_to_fmt), to)).append(": ").append(subject);
|
||||||
} else {
|
} else {
|
||||||
messageNotice.append(context.getString(R.string.general_no_sender)).append(": ").append(subject);
|
messageNotice.append(context.getString(R.string.general_no_sender)).append(": ").append(subject);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3972,7 +4006,8 @@ public class MessagingController implements Runnable {
|
|||||||
Intent i = FolderList.actionHandleNotification(context, account, message.getFolder().getName());
|
Intent i = FolderList.actionHandleNotification(context, account, message.getFolder().getName());
|
||||||
PendingIntent pi = PendingIntent.getActivity(context, 0, i, 0);
|
PendingIntent pi = PendingIntent.getActivity(context, 0, i, 0);
|
||||||
|
|
||||||
String accountNotice = context.getString(R.string.notification_new_one_account_fmt, unreadCount, account.getDescription());
|
String accountDescr = (account.getDescription() != null) ? account.getDescription() : account.getEmail();
|
||||||
|
String accountNotice = context.getString(R.string.notification_new_one_account_fmt, unreadCount, accountDescr);
|
||||||
notif.setLatestEventInfo(context, accountNotice, messageNotice, pi);
|
notif.setLatestEventInfo(context, accountNotice, messageNotice, pi);
|
||||||
|
|
||||||
// Only ring or vibrate if we have not done so already on this
|
// Only ring or vibrate if we have not done so already on this
|
||||||
@ -3988,7 +4023,6 @@ public class MessagingController implements Runnable {
|
|||||||
configureNotification(notif, (n.shouldRing() ? n.getRingtone() : null), (n.shouldVibrate() ? n.getVibration() : null), (n.isLed() ? n.getLedColor() : null), K9.NOTIFICATION_LED_BLINK_SLOW, ringAndVibrate);
|
configureNotification(notif, (n.shouldRing() ? n.getRingtone() : null), (n.shouldVibrate() ? n.getVibration() : null), (n.isLed() ? n.getLedColor() : null), K9.NOTIFICATION_LED_BLINK_SLOW, ringAndVibrate);
|
||||||
|
|
||||||
notifMgr.notify(account.getAccountNumber(), notif);
|
notifMgr.notify(account.getAccountNumber(), notif);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -97,13 +97,6 @@ public abstract class Contacts {
|
|||||||
mContentResolver = context.getContentResolver();
|
mContentResolver = context.getContentResolver();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the name of the device's owner.
|
|
||||||
*
|
|
||||||
* @return The name of the owner if available. <tt>null</tt>, otherwise.
|
|
||||||
*/
|
|
||||||
public abstract String getOwnerName();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start the activity to add information to an existing contact or add a
|
* Start the activity to add information to an existing contact or add a
|
||||||
* new one.
|
* new one.
|
||||||
|
@ -85,27 +85,6 @@ public class ContactsSdk3_4 extends com.fsck.k9.helper.Contacts {
|
|||||||
mContext.startActivity(contactIntent);
|
mContext.startActivity(contactIntent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getOwnerName() {
|
|
||||||
String name = null;
|
|
||||||
final Cursor c = mContentResolver.query(
|
|
||||||
Uri.withAppendedPath(Contacts.People.CONTENT_URI, "owner"),
|
|
||||||
new String[] {Contacts.ContactMethods.DISPLAY_NAME},
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
null);
|
|
||||||
|
|
||||||
if (c != null) {
|
|
||||||
if (c.getCount() > 0) {
|
|
||||||
c.moveToFirst();
|
|
||||||
name = c.getString(0); // owner's display name
|
|
||||||
}
|
|
||||||
c.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInContacts(final String emailAddress) {
|
public boolean isInContacts(final String emailAddress) {
|
||||||
boolean result = false;
|
boolean result = false;
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
package com.fsck.k9.helper;
|
package com.fsck.k9.helper;
|
||||||
|
|
||||||
import android.accounts.Account;
|
|
||||||
import android.accounts.AccountManager;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
@ -87,22 +85,6 @@ public class ContactsSdk5 extends com.fsck.k9.helper.Contacts {
|
|||||||
mContext.startActivity(contactIntent);
|
mContext.startActivity(contactIntent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getOwnerName() {
|
|
||||||
String name = null;
|
|
||||||
|
|
||||||
// Get the name of the first account that has one.
|
|
||||||
Account[] accounts = AccountManager.get(mContext).getAccounts();
|
|
||||||
for (final Account account : accounts) {
|
|
||||||
if (account.name != null) {
|
|
||||||
name = account.name;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInContacts(final String emailAddress) {
|
public boolean isInContacts(final String emailAddress) {
|
||||||
boolean result = false;
|
boolean result = false;
|
||||||
|
134
src/com/fsck/k9/helper/FileBrowserHelper.java
Normal file
134
src/com/fsck/k9/helper/FileBrowserHelper.java
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
package com.fsck.k9.helper;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.content.ActivityNotFoundException;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.text.InputType;
|
||||||
|
import android.widget.EditText;
|
||||||
|
|
||||||
|
import com.fsck.k9.K9;
|
||||||
|
import com.fsck.k9.R;
|
||||||
|
|
||||||
|
public class FileBrowserHelper {
|
||||||
|
/**
|
||||||
|
* A string array that specifies the name of the intent to use, and the scheme to use with it
|
||||||
|
* when setting the data for the intent.
|
||||||
|
*/
|
||||||
|
private static final String[][] PICK_DIRECTORY_INTENTS = {
|
||||||
|
{ "org.openintents.action.PICK_DIRECTORY", "file://" }, // OI File Manager (maybe others)
|
||||||
|
{ "com.estrongs.action.PICK_DIRECTORY", "file://" }, // ES File Explorer
|
||||||
|
{ Intent.ACTION_PICK, "folder://" }, // Blackmoon File Browser (maybe others)
|
||||||
|
{ "com.androidworkz.action.PICK_DIRECTORY", "file://" }
|
||||||
|
}; // SystemExplorer
|
||||||
|
|
||||||
|
private static FileBrowserHelper sInstance;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* callback class to provide the result of the fallback textedit path dialog
|
||||||
|
*/
|
||||||
|
public interface FileBrowserFailOverCallback {
|
||||||
|
/**
|
||||||
|
* the user has entered a path
|
||||||
|
* @param path the path as String
|
||||||
|
*/
|
||||||
|
public void onPathEntered(String path);
|
||||||
|
/**
|
||||||
|
* the user has cancel the inputtext dialog
|
||||||
|
*/
|
||||||
|
public void onCancel();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* factory method
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private FileBrowserHelper() {
|
||||||
|
}
|
||||||
|
public synchronized static FileBrowserHelper getInstance() {
|
||||||
|
if (sInstance == null) {
|
||||||
|
sInstance = new FileBrowserHelper();
|
||||||
|
}
|
||||||
|
return sInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tries to open known filebrowsers.
|
||||||
|
* If no filebrowser is found and fallback textdialog is shown
|
||||||
|
* @param c the context as activity
|
||||||
|
* @param startPath: the default value, where the filebrowser will start.
|
||||||
|
* if startPath = null => the default path is used
|
||||||
|
* @param requestcode: the int you will get as requestcode in onActivityResult
|
||||||
|
* (only used if there is a filebrowser installed)
|
||||||
|
* @param callback: the callback (only used when no filebrowser is installed.
|
||||||
|
* if a filebrowser is installed => override the onActivtyResult Method
|
||||||
|
*
|
||||||
|
* @return true: if a filebrowser has been found (the result will be in the onActivityResult
|
||||||
|
* false: a fallback textinput has been shown. The Result will be sent with the callback method
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public boolean showFileBrowserActivity(Activity c, File startPath, int requestcode, FileBrowserFailOverCallback callback) {
|
||||||
|
boolean success = false;
|
||||||
|
|
||||||
|
if (startPath == null) {
|
||||||
|
startPath = new File(K9.getAttachmentDefaultPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
int listIndex = 0;
|
||||||
|
do {
|
||||||
|
String intentAction = PICK_DIRECTORY_INTENTS[listIndex][0];
|
||||||
|
String uriPrefix = PICK_DIRECTORY_INTENTS[listIndex][1];
|
||||||
|
Intent intent = new Intent(intentAction);
|
||||||
|
intent.setData(Uri.parse(uriPrefix + startPath.getPath()));
|
||||||
|
|
||||||
|
try {
|
||||||
|
c.startActivityForResult(intent, requestcode);
|
||||||
|
success = true;
|
||||||
|
} catch (ActivityNotFoundException e) {
|
||||||
|
// Try the next intent in the list
|
||||||
|
listIndex++;
|
||||||
|
};
|
||||||
|
} while (!success && (listIndex < PICK_DIRECTORY_INTENTS.length));
|
||||||
|
|
||||||
|
if (listIndex == PICK_DIRECTORY_INTENTS.length) {
|
||||||
|
//No Filebrowser is installed => show a fallback textdialog
|
||||||
|
showPathTextInput(c, startPath, callback);
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showPathTextInput(final Activity c, final File startPath, final FileBrowserFailOverCallback callback) {
|
||||||
|
AlertDialog.Builder alert = new AlertDialog.Builder(c);
|
||||||
|
|
||||||
|
alert.setTitle(c.getString(R.string.attachment_save_title));
|
||||||
|
alert.setMessage(c.getString(R.string.attachment_save_desc));
|
||||||
|
final EditText input = new EditText(c);
|
||||||
|
input.setInputType(InputType.TYPE_CLASS_TEXT);
|
||||||
|
if (startPath != null)
|
||||||
|
input.setText(startPath.toString());
|
||||||
|
alert.setView(input);
|
||||||
|
|
||||||
|
alert.setPositiveButton(c.getString(R.string.okay_action), new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int whichButton) {
|
||||||
|
String path = input.getText().toString();
|
||||||
|
callback.onPathEntered(path);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
alert.setNegativeButton(c.getString(R.string.cancel_action),
|
||||||
|
new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int whichButton) {
|
||||||
|
callback.onCancel();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
alert.show();
|
||||||
|
}
|
||||||
|
}
|
@ -123,6 +123,45 @@ public class HtmlConverter {
|
|||||||
|
|
||||||
private static final int MAX_SMART_HTMLIFY_MESSAGE_LENGTH = 1024 * 256 ;
|
private static final int MAX_SMART_HTMLIFY_MESSAGE_LENGTH = 1024 * 256 ;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Naively convert a text string into an HTML document. This method avoids using regular expressions on the entire
|
||||||
|
* message body to save memory.
|
||||||
|
* @param text Plain text string.
|
||||||
|
* @return HTML string.
|
||||||
|
*/
|
||||||
|
private static String simpleTextToHtml(String text) {
|
||||||
|
// Encode HTML entities to make sure we don't display something evil.
|
||||||
|
text = TextUtils.htmlEncode(text);
|
||||||
|
|
||||||
|
StringReader reader = new StringReader(text);
|
||||||
|
StringBuilder buff = new StringBuilder(text.length() + TEXT_TO_HTML_EXTRA_BUFFER_LENGTH);
|
||||||
|
buff.append("<html><head/><body>");
|
||||||
|
|
||||||
|
int c;
|
||||||
|
try {
|
||||||
|
while ((c = reader.read()) != -1) {
|
||||||
|
switch (c) {
|
||||||
|
case '\n':
|
||||||
|
// pine treats <br> as two newlines, but <br/> as one newline. Use <br/> so our messages aren't
|
||||||
|
// doublespaced.
|
||||||
|
buff.append("<br />");
|
||||||
|
break;
|
||||||
|
case '\r':
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
buff.append((char)c);
|
||||||
|
}//switch
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
//Should never happen
|
||||||
|
Log.e(K9.LOG_TAG, "Could not read string to convert text to HTML:", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
buff.append("</body></html>");
|
||||||
|
|
||||||
|
return buff.toString();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert a text string into an HTML document. Attempts to do smart replacement for large
|
* Convert a text string into an HTML document. Attempts to do smart replacement for large
|
||||||
* documents to prevent OOM errors. This method adds headers and footers to create a proper HTML
|
* documents to prevent OOM errors. This method adds headers and footers to create a proper HTML
|
||||||
@ -136,11 +175,7 @@ public class HtmlConverter {
|
|||||||
// if the message is big and plain text, just do
|
// if the message is big and plain text, just do
|
||||||
// a trivial htmlification
|
// a trivial htmlification
|
||||||
if (text.length() > MAX_SMART_HTMLIFY_MESSAGE_LENGTH) {
|
if (text.length() > MAX_SMART_HTMLIFY_MESSAGE_LENGTH) {
|
||||||
return "<html><head/><body>" +
|
return simpleTextToHtml(text);
|
||||||
htmlifyMessageHeader() +
|
|
||||||
text +
|
|
||||||
htmlifyMessageFooter() +
|
|
||||||
"</body></html>";
|
|
||||||
}
|
}
|
||||||
StringReader reader = new StringReader(text);
|
StringReader reader = new StringReader(text);
|
||||||
StringBuilder buff = new StringBuilder(text.length() + TEXT_TO_HTML_EXTRA_BUFFER_LENGTH);
|
StringBuilder buff = new StringBuilder(text.length() + TEXT_TO_HTML_EXTRA_BUFFER_LENGTH);
|
||||||
@ -148,6 +183,11 @@ public class HtmlConverter {
|
|||||||
try {
|
try {
|
||||||
while ((c = reader.read()) != -1) {
|
while ((c = reader.read()) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
case '\n':
|
||||||
|
// pine treats <br> as two newlines, but <br/> as one newline. Use <br/> so our messages aren't
|
||||||
|
// doublespaced.
|
||||||
|
buff.append("<br />");
|
||||||
|
break;
|
||||||
case '&':
|
case '&':
|
||||||
buff.append("&");
|
buff.append("&");
|
||||||
break;
|
break;
|
||||||
@ -168,8 +208,14 @@ public class HtmlConverter {
|
|||||||
Log.e(K9.LOG_TAG, "Could not read string to convert text to HTML:", e);
|
Log.e(K9.LOG_TAG, "Could not read string to convert text to HTML:", e);
|
||||||
}
|
}
|
||||||
text = buff.toString();
|
text = buff.toString();
|
||||||
|
|
||||||
|
// Replace lines of -,= or _ with horizontal rules
|
||||||
text = text.replaceAll("\\s*([-=_]{30,}+)\\s*", "<hr />");
|
text = text.replaceAll("\\s*([-=_]{30,}+)\\s*", "<hr />");
|
||||||
|
|
||||||
|
// TODO: reverse engineer (or troll history) and document
|
||||||
text = text.replaceAll("(?m)^([^\r\n]{4,}[\\s\\w,:;+/])(?:\r\n|\n|\r)(?=[a-z]\\S{0,10}[\\s\\n\\r])", "$1 ");
|
text = text.replaceAll("(?m)^([^\r\n]{4,}[\\s\\w,:;+/])(?:\r\n|\n|\r)(?=[a-z]\\S{0,10}[\\s\\n\\r])", "$1 ");
|
||||||
|
|
||||||
|
// Compress four or more newlines down to two newlines
|
||||||
text = text.replaceAll("(?m)(\r\n|\n|\r){4,}", "\n\n");
|
text = text.replaceAll("(?m)(\r\n|\n|\r){4,}", "\n\n");
|
||||||
|
|
||||||
StringBuffer sb = new StringBuffer(text.length() + TEXT_TO_HTML_EXTRA_BUFFER_LENGTH);
|
StringBuffer sb = new StringBuffer(text.length() + TEXT_TO_HTML_EXTRA_BUFFER_LENGTH);
|
||||||
|
@ -99,4 +99,9 @@ public class MessageHelper {
|
|||||||
return mDateFormat.format(date);
|
return mDateFormat.format(date);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void refresh() {
|
||||||
|
mDateFormat = DateFormatter.getDateFormat(mContext);
|
||||||
|
mTodayDateFormat = android.text.format.DateFormat.getTimeFormat(mContext);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,24 +57,25 @@ public class Utility {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Combines the given array of Objects into a single string using the
|
* Combines the given array of Objects into a single String using
|
||||||
* seperator character and each Object's toString() method. between each
|
* each Object's toString() method and the separator character
|
||||||
* part.
|
* between each part.
|
||||||
*
|
*
|
||||||
* @param parts
|
* @param parts
|
||||||
* @param seperator
|
* @param separator
|
||||||
* @return
|
* @return new String
|
||||||
*/
|
*/
|
||||||
public static String combine(Object[] parts, char seperator) {
|
public static String combine(Object[] parts, char separator) {
|
||||||
if (parts == null) {
|
if (parts == null) {
|
||||||
return null;
|
return null;
|
||||||
|
} else if (parts.length == 0) {
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
StringBuffer sb = new StringBuffer();
|
StringBuilder sb = new StringBuilder();
|
||||||
for (int i = 0; i < parts.length; i++) {
|
sb.append(parts[0]);
|
||||||
sb.append(parts[i].toString());
|
for (int i = 1; i < parts.length; ++i) {
|
||||||
if (i < parts.length - 1) {
|
sb.append(separator);
|
||||||
sb.append(seperator);
|
sb.append(parts[i]);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
@ -153,9 +153,13 @@ public abstract class Folder {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isFlagSupported(Flag flag) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean supportsFetchingFlags() {
|
public boolean supportsFetchingFlags() {
|
||||||
return true;
|
return true;
|
||||||
}//isFlagSupported
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
@ -20,8 +20,7 @@ package com.fsck.k9.mail.filter;
|
|||||||
* This code was copied from the Apache Commons project.
|
* This code was copied from the Apache Commons project.
|
||||||
* The unnecessary parts have been left out.
|
* The unnecessary parts have been left out.
|
||||||
*/
|
*/
|
||||||
public class Hex
|
public class Hex {
|
||||||
{
|
|
||||||
/**
|
/**
|
||||||
* Used building output as Hex
|
* Used building output as Hex
|
||||||
*/
|
*/
|
||||||
|
@ -30,7 +30,7 @@ public class PeekableInputStream extends InputStream {
|
|||||||
|
|
||||||
public int peek() throws IOException {
|
public int peek() throws IOException {
|
||||||
if (!mPeeked) {
|
if (!mPeeked) {
|
||||||
mPeekedByte = read();
|
mPeekedByte = mIn.read();
|
||||||
mPeeked = true;
|
mPeeked = true;
|
||||||
}
|
}
|
||||||
return mPeekedByte;
|
return mPeekedByte;
|
||||||
|
@ -14,6 +14,7 @@ import java.io.OutputStream;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
|
import java.nio.charset.IllegalCharsetNameException;
|
||||||
|
|
||||||
|
|
||||||
public class MimeUtility {
|
public class MimeUtility {
|
||||||
@ -1381,13 +1382,19 @@ public class MimeUtility {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* See if there is conversion from the MIME charset to the Java one.
|
* See if there is conversion from the MIME charset to the Java one.
|
||||||
|
* this function may also throw an exception if the charset name is not known
|
||||||
*/
|
*/
|
||||||
if (!Charset.isSupported(charset)) {
|
boolean supported;
|
||||||
|
try {
|
||||||
|
supported = Charset.isSupported(charset);
|
||||||
|
} catch (IllegalCharsetNameException e) {
|
||||||
|
supported = false;
|
||||||
|
}
|
||||||
|
if (!supported) {
|
||||||
Log.e(K9.LOG_TAG, "I don't know how to deal with the charset " + charset +
|
Log.e(K9.LOG_TAG, "I don't know how to deal with the charset " + charset +
|
||||||
". Falling back to US-ASCII");
|
". Falling back to US-ASCII");
|
||||||
charset = "US-ASCII";
|
charset = "US-ASCII";
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Convert and return as new String
|
* Convert and return as new String
|
||||||
*/
|
*/
|
||||||
|
@ -15,6 +15,7 @@ public class ImapResponseParser {
|
|||||||
private static final SimpleDateFormat mDateTimeFormat = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss Z", Locale.US);
|
private static final SimpleDateFormat mDateTimeFormat = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss Z", Locale.US);
|
||||||
private static final SimpleDateFormat badDateTimeFormat = new SimpleDateFormat("dd MMM yyyy HH:mm:ss Z", Locale.US);
|
private static final SimpleDateFormat badDateTimeFormat = new SimpleDateFormat("dd MMM yyyy HH:mm:ss Z", Locale.US);
|
||||||
private static final SimpleDateFormat badDateTimeFormat2 = new SimpleDateFormat("E, dd MMM yyyy HH:mm:ss Z", Locale.US);
|
private static final SimpleDateFormat badDateTimeFormat2 = new SimpleDateFormat("E, dd MMM yyyy HH:mm:ss Z", Locale.US);
|
||||||
|
private static final SimpleDateFormat badDateTimeFormat3 = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss", Locale.US);
|
||||||
|
|
||||||
private PeekableInputStream mIn;
|
private PeekableInputStream mIn;
|
||||||
private ImapResponse mResponse;
|
private ImapResponse mResponse;
|
||||||
@ -194,7 +195,7 @@ public class ImapResponseParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String parseAtom() throws IOException {
|
private String parseAtom() throws IOException {
|
||||||
StringBuffer sb = new StringBuffer();
|
StringBuilder sb = new StringBuilder();
|
||||||
int ch;
|
int ch;
|
||||||
while (true) {
|
while (true) {
|
||||||
ch = mIn.peek();
|
ch = mIn.peek();
|
||||||
@ -426,9 +427,15 @@ public class ImapResponseParser {
|
|||||||
return badDateTimeFormat.parse(value);
|
return badDateTimeFormat.parse(value);
|
||||||
}
|
}
|
||||||
} catch (Exception e2) {
|
} catch (Exception e2) {
|
||||||
|
try {
|
||||||
synchronized (badDateTimeFormat2) {
|
synchronized (badDateTimeFormat2) {
|
||||||
return badDateTimeFormat2.parse(value);
|
return badDateTimeFormat2.parse(value);
|
||||||
}
|
}
|
||||||
|
} catch (Exception e3) {
|
||||||
|
synchronized (badDateTimeFormat3) {
|
||||||
|
return badDateTimeFormat3.parse(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,10 @@ import java.net.URISyntaxException;
|
|||||||
import java.net.URLDecoder;
|
import java.net.URLDecoder;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.CharBuffer;
|
import java.nio.CharBuffer;
|
||||||
|
import java.nio.charset.CharacterCodingException;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
|
import java.nio.charset.CharsetDecoder;
|
||||||
|
import java.nio.charset.CodingErrorAction;
|
||||||
import java.security.GeneralSecurityException;
|
import java.security.GeneralSecurityException;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
import java.security.Security;
|
import java.security.Security;
|
||||||
@ -373,16 +376,31 @@ public class ImapStore extends Store {
|
|||||||
for (ImapResponse response : responses) {
|
for (ImapResponse response : responses) {
|
||||||
if (ImapResponseParser.equalsIgnoreCase(response.get(0), commandResponse)) {
|
if (ImapResponseParser.equalsIgnoreCase(response.get(0), commandResponse)) {
|
||||||
boolean includeFolder = true;
|
boolean includeFolder = true;
|
||||||
String folder = decodeFolderName(response.getString(3));
|
|
||||||
|
String decodedFolderName;
|
||||||
|
try {
|
||||||
|
decodedFolderName = decodeFolderName(response.getString(3));
|
||||||
|
} catch (CharacterCodingException e) {
|
||||||
|
Log.w(K9.LOG_TAG, "Folder name not correctly encoded with the UTF-7 variant " +
|
||||||
|
"as defined by RFC 3501: " + response.getString(3), e);
|
||||||
|
|
||||||
|
//TODO: Use the raw name returned by the server for all commands that require
|
||||||
|
// a folder name. Use the decoded name only for showing it to the user.
|
||||||
|
|
||||||
|
// We currently just skip folders with malformed names.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String folder = decodedFolderName;
|
||||||
|
|
||||||
if (mPathDelimeter == null) {
|
if (mPathDelimeter == null) {
|
||||||
mPathDelimeter = response.getString(2);
|
mPathDelimeter = response.getString(2);
|
||||||
mCombinedPrefix = null;
|
mCombinedPrefix = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (folder.equalsIgnoreCase(K9.INBOX)) {
|
if (folder.equalsIgnoreCase(mAccount.getInboxFolderName())) {
|
||||||
continue;
|
continue;
|
||||||
} else if (folder.equalsIgnoreCase(K9.OUTBOX)) {
|
} else if (folder.equals(mAccount.getOutboxFolderName())) {
|
||||||
/*
|
/*
|
||||||
* There is a folder on the server with the same name as our local
|
* There is a folder on the server with the same name as our local
|
||||||
* outbox. Until we have a good plan to deal with this situation
|
* outbox. Until we have a good plan to deal with this situation
|
||||||
@ -390,12 +408,13 @@ public class ImapStore extends Store {
|
|||||||
*/
|
*/
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
|
int prefixLength = getCombinedPrefix().length();
|
||||||
if (getCombinedPrefix().length() > 0) {
|
if (prefixLength > 0) {
|
||||||
if (folder.length() >= getCombinedPrefix().length()) {
|
// Strip prefix from the folder name
|
||||||
folder = folder.substring(getCombinedPrefix().length());
|
if (folder.length() >= prefixLength) {
|
||||||
|
folder = folder.substring(prefixLength);
|
||||||
}
|
}
|
||||||
if (!decodeFolderName(response.getString(3)).equalsIgnoreCase(getCombinedPrefix() + folder)) {
|
if (!decodedFolderName.equalsIgnoreCase(getCombinedPrefix() + folder)) {
|
||||||
includeFolder = false;
|
includeFolder = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -413,7 +432,7 @@ public class ImapStore extends Store {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
folders.add(getFolder("INBOX"));
|
folders.add(getFolder(mAccount.getInboxFolderName()));
|
||||||
return folders;
|
return folders;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -492,14 +511,15 @@ public class ImapStore extends Store {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String decodeFolderName(String name) {
|
private String decodeFolderName(String name) throws CharacterCodingException {
|
||||||
/*
|
/*
|
||||||
* Convert the encoded name to US-ASCII, then pass it through the modified UTF-7
|
* Convert the encoded name to US-ASCII, then pass it through the modified UTF-7
|
||||||
* decoder and return the Unicode String.
|
* decoder and return the Unicode String.
|
||||||
*/
|
*/
|
||||||
try {
|
try {
|
||||||
byte[] encoded = name.getBytes("US-ASCII");
|
// Make sure the decoder throws an exception if it encounters an invalid encoding.
|
||||||
CharBuffer cb = mModifiedUtf7Charset.decode(ByteBuffer.wrap(encoded));
|
CharsetDecoder decoder = mModifiedUtf7Charset.newDecoder().onMalformedInput(CodingErrorAction.REPORT);
|
||||||
|
CharBuffer cb = decoder.decode(ByteBuffer.wrap(name.getBytes("US-ASCII")));
|
||||||
return cb.toString();
|
return cb.toString();
|
||||||
} catch (UnsupportedEncodingException uee) {
|
} catch (UnsupportedEncodingException uee) {
|
||||||
/*
|
/*
|
||||||
@ -548,7 +568,7 @@ public class ImapStore extends Store {
|
|||||||
|
|
||||||
public String getPrefixedName() throws MessagingException {
|
public String getPrefixedName() throws MessagingException {
|
||||||
String prefixedName = "";
|
String prefixedName = "";
|
||||||
if (!K9.INBOX.equalsIgnoreCase(mName)) {
|
if (!mAccount.getInboxFolderName().equalsIgnoreCase(mName)) {
|
||||||
ImapConnection connection = null;
|
ImapConnection connection = null;
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
if (mConnection == null) {
|
if (mConnection == null) {
|
||||||
|
@ -10,6 +10,7 @@ import java.util.HashMap;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
@ -366,7 +367,7 @@ public class LocalStore extends Store implements Serializable {
|
|||||||
Folder.FolderClass pushClass = Folder.FolderClass.SECOND_CLASS;
|
Folder.FolderClass pushClass = Folder.FolderClass.SECOND_CLASS;
|
||||||
boolean inTopGroup = false;
|
boolean inTopGroup = false;
|
||||||
boolean integrate = false;
|
boolean integrate = false;
|
||||||
if (K9.INBOX.equals(name)) {
|
if (mAccount.getInboxFolderName().equals(name)) {
|
||||||
displayClass = Folder.FolderClass.FIRST_CLASS;
|
displayClass = Folder.FolderClass.FIRST_CLASS;
|
||||||
syncClass = Folder.FolderClass.FIRST_CLASS;
|
syncClass = Folder.FolderClass.FIRST_CLASS;
|
||||||
pushClass = Folder.FolderClass.FIRST_CLASS;
|
pushClass = Folder.FolderClass.FIRST_CLASS;
|
||||||
@ -484,9 +485,6 @@ public class LocalStore extends Store implements Serializable {
|
|||||||
cursor = db.rawQuery("SELECT COUNT(*) FROM messages", null);
|
cursor = db.rawQuery("SELECT COUNT(*) FROM messages", null);
|
||||||
cursor.moveToFirst();
|
cursor.moveToFirst();
|
||||||
return cursor.getInt(0); // message count
|
return cursor.getInt(0); // message count
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
if (cursor != null) {
|
if (cursor != null) {
|
||||||
cursor.close();
|
cursor.close();
|
||||||
@ -496,8 +494,6 @@ public class LocalStore extends Store implements Serializable {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void getMessageCounts(final AccountStats stats) throws MessagingException {
|
public void getMessageCounts(final AccountStats stats) throws MessagingException {
|
||||||
final Account.FolderMode displayMode = mAccount.getFolderDisplayMode();
|
final Account.FolderMode displayMode = mAccount.getFolderDisplayMode();
|
||||||
|
|
||||||
@ -506,65 +502,61 @@ public class LocalStore extends Store implements Serializable {
|
|||||||
public Integer doDbWork(final SQLiteDatabase db) {
|
public Integer doDbWork(final SQLiteDatabase db) {
|
||||||
Cursor cursor = null;
|
Cursor cursor = null;
|
||||||
try {
|
try {
|
||||||
String baseQuery = "SELECT SUM(unread_count), SUM(flagged_count) FROM folders WHERE ( name != ? AND name != ? AND name != ? AND name != ? AND name != ? ) ";
|
// Always count messages in the INBOX but exclude special folders and possibly
|
||||||
if (displayMode == Account.FolderMode.NONE) {
|
// more (depending on the folder display mode)
|
||||||
cursor = db.rawQuery(baseQuery + "AND (name = ? )", new String[] {
|
String baseQuery = "SELECT SUM(unread_count), SUM(flagged_count) " +
|
||||||
|
"FROM folders " +
|
||||||
|
"WHERE (name = ?)" + /* INBOX */
|
||||||
|
" OR (" +
|
||||||
|
"name NOT IN (?, ?, ?, ?, ?)" + /* special folders */
|
||||||
|
"%s)"; /* placeholder for additional constraints */
|
||||||
|
|
||||||
mAccount.getTrashFolderName() != null ? mAccount.getTrashFolderName() : "" ,
|
List<String> queryParam = new ArrayList<String>();
|
||||||
mAccount.getDraftsFolderName() != null ? mAccount.getDraftsFolderName() : "",
|
queryParam.add(mAccount.getInboxFolderName());
|
||||||
mAccount.getSpamFolderName() != null ? mAccount.getSpamFolderName() : "",
|
|
||||||
mAccount.getOutboxFolderName() != null ? mAccount.getOutboxFolderName() : "",
|
|
||||||
mAccount.getSentFolderName() != null ? mAccount.getSentFolderName() : "",
|
|
||||||
K9.INBOX
|
|
||||||
}
|
|
||||||
|
|
||||||
);
|
queryParam.add((mAccount.getTrashFolderName() != null) ?
|
||||||
} else if (displayMode == Account.FolderMode.FIRST_CLASS) {
|
mAccount.getTrashFolderName() : "");
|
||||||
cursor = db.rawQuery(baseQuery + " AND ( name = ? OR display_class = ?)", new String[] {
|
queryParam.add((mAccount.getDraftsFolderName() != null) ?
|
||||||
mAccount.getTrashFolderName() != null ? mAccount.getTrashFolderName() : "" ,
|
mAccount.getDraftsFolderName() : "");
|
||||||
mAccount.getDraftsFolderName() != null ? mAccount.getDraftsFolderName() : "",
|
queryParam.add((mAccount.getSpamFolderName() != null) ?
|
||||||
mAccount.getSpamFolderName() != null ? mAccount.getSpamFolderName() : "",
|
mAccount.getSpamFolderName() : "");
|
||||||
mAccount.getOutboxFolderName() != null ? mAccount.getOutboxFolderName() : "",
|
queryParam.add((mAccount.getOutboxFolderName() != null) ?
|
||||||
mAccount.getSentFolderName() != null ? mAccount.getSentFolderName() : "",
|
mAccount.getOutboxFolderName() : "");
|
||||||
K9.INBOX, Folder.FolderClass.FIRST_CLASS.name()
|
queryParam.add((mAccount.getSentFolderName() != null) ?
|
||||||
});
|
mAccount.getSentFolderName() : "");
|
||||||
|
|
||||||
|
final String extraWhere;
|
||||||
} else if (displayMode == Account.FolderMode.FIRST_AND_SECOND_CLASS) {
|
switch (displayMode) {
|
||||||
cursor = db.rawQuery(baseQuery + " AND ( name = ? OR display_class = ? OR display_class = ? )", new String[] {
|
case FIRST_CLASS:
|
||||||
mAccount.getTrashFolderName() != null ? mAccount.getTrashFolderName() : "" ,
|
// Count messages in the INBOX and non-special first class folders
|
||||||
mAccount.getDraftsFolderName() != null ? mAccount.getDraftsFolderName() : "",
|
extraWhere = " AND (display_class = ?)";
|
||||||
mAccount.getSpamFolderName() != null ? mAccount.getSpamFolderName() : "",
|
queryParam.add(Folder.FolderClass.FIRST_CLASS.name());
|
||||||
mAccount.getOutboxFolderName() != null ? mAccount.getOutboxFolderName() : "",
|
break;
|
||||||
mAccount.getSentFolderName() != null ? mAccount.getSentFolderName() : "",
|
case FIRST_AND_SECOND_CLASS:
|
||||||
K9.INBOX, Folder.FolderClass.FIRST_CLASS.name(), Folder.FolderClass.SECOND_CLASS.name()
|
// Count messages in the INBOX and non-special first and second class folders
|
||||||
});
|
extraWhere = " AND (display_class IN (?, ?))";
|
||||||
} else if (displayMode == Account.FolderMode.NOT_SECOND_CLASS) {
|
queryParam.add(Folder.FolderClass.FIRST_CLASS.name());
|
||||||
cursor = db.rawQuery(baseQuery + " AND ( name = ? OR display_class != ?)", new String[] {
|
queryParam.add(Folder.FolderClass.SECOND_CLASS.name());
|
||||||
|
break;
|
||||||
mAccount.getTrashFolderName() != null ? mAccount.getTrashFolderName() : "" ,
|
case NOT_SECOND_CLASS:
|
||||||
mAccount.getDraftsFolderName() != null ? mAccount.getDraftsFolderName() : "",
|
// Count messages in the INBOX and non-special non-second-class folders
|
||||||
mAccount.getSpamFolderName() != null ? mAccount.getSpamFolderName() : "",
|
extraWhere = " AND (display_class != ?)";
|
||||||
mAccount.getOutboxFolderName() != null ? mAccount.getOutboxFolderName() : "",
|
queryParam.add(Folder.FolderClass.SECOND_CLASS.name());
|
||||||
mAccount.getSentFolderName() != null ? mAccount.getSentFolderName() : "",
|
break;
|
||||||
K9.INBOX, Folder.FolderClass.SECOND_CLASS.name()
|
case ALL:
|
||||||
});
|
// Count messages in the INBOX and non-special folders
|
||||||
} else if (displayMode == Account.FolderMode.ALL) {
|
extraWhere = "";
|
||||||
cursor = db.rawQuery(baseQuery, new String[] {
|
break;
|
||||||
|
default:
|
||||||
mAccount.getTrashFolderName() != null ? mAccount.getTrashFolderName() : "" ,
|
|
||||||
mAccount.getDraftsFolderName() != null ? mAccount.getDraftsFolderName() : "",
|
|
||||||
mAccount.getSpamFolderName() != null ? mAccount.getSpamFolderName() : "",
|
|
||||||
mAccount.getOutboxFolderName() != null ? mAccount.getOutboxFolderName() : "",
|
|
||||||
mAccount.getSentFolderName() != null ? mAccount.getSentFolderName() : "",
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
Log.e(K9.LOG_TAG, "asked to compute account statistics for an impossible folder mode " + displayMode);
|
Log.e(K9.LOG_TAG, "asked to compute account statistics for an impossible folder mode " + displayMode);
|
||||||
stats.unreadMessageCount = 0;
|
stats.unreadMessageCount = 0;
|
||||||
stats.flaggedMessageCount = 0;
|
stats.flaggedMessageCount = 0;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String query = String.format(Locale.US, baseQuery, extraWhere);
|
||||||
|
cursor = db.rawQuery(query, queryParam.toArray(EMPTY_STRING_ARRAY));
|
||||||
|
|
||||||
cursor.moveToFirst();
|
cursor.moveToFirst();
|
||||||
stats.unreadMessageCount = cursor.getInt(0);
|
stats.unreadMessageCount = cursor.getInt(0);
|
||||||
stats.flaggedMessageCount = cursor.getInt(1);
|
stats.flaggedMessageCount = cursor.getInt(1);
|
||||||
@ -1047,14 +1039,14 @@ public class LocalStore extends Store implements Serializable {
|
|||||||
if (mAccount.isSpecialFolder(name)) {
|
if (mAccount.isSpecialFolder(name)) {
|
||||||
prefHolder.inTopGroup = true;
|
prefHolder.inTopGroup = true;
|
||||||
prefHolder.displayClass = LocalFolder.FolderClass.FIRST_CLASS;
|
prefHolder.displayClass = LocalFolder.FolderClass.FIRST_CLASS;
|
||||||
if (name.equalsIgnoreCase(K9.INBOX)) {
|
if (name.equalsIgnoreCase(mAccount.getInboxFolderName())) {
|
||||||
prefHolder.integrate = true;
|
prefHolder.integrate = true;
|
||||||
prefHolder.pushClass = LocalFolder.FolderClass.FIRST_CLASS;
|
prefHolder.pushClass = LocalFolder.FolderClass.FIRST_CLASS;
|
||||||
} else {
|
} else {
|
||||||
prefHolder.pushClass = LocalFolder.FolderClass.INHERITED;
|
prefHolder.pushClass = LocalFolder.FolderClass.INHERITED;
|
||||||
|
|
||||||
}
|
}
|
||||||
if (name.equalsIgnoreCase(K9.INBOX) ||
|
if (name.equalsIgnoreCase(mAccount.getInboxFolderName()) ||
|
||||||
name.equalsIgnoreCase(mAccount.getDraftsFolderName())) {
|
name.equalsIgnoreCase(mAccount.getDraftsFolderName())) {
|
||||||
prefHolder.syncClass = LocalFolder.FolderClass.FIRST_CLASS;
|
prefHolder.syncClass = LocalFolder.FolderClass.FIRST_CLASS;
|
||||||
} else {
|
} else {
|
||||||
@ -1104,7 +1096,8 @@ public class LocalStore extends Store implements Serializable {
|
|||||||
super(LocalStore.this.mAccount);
|
super(LocalStore.this.mAccount);
|
||||||
this.mName = name;
|
this.mName = name;
|
||||||
|
|
||||||
if (K9.INBOX.equals(getName())) {
|
if (LocalStore.this.mAccount.getInboxFolderName().equals(getName())) {
|
||||||
|
|
||||||
mSyncClass = FolderClass.FIRST_CLASS;
|
mSyncClass = FolderClass.FIRST_CLASS;
|
||||||
mPushClass = FolderClass.FIRST_CLASS;
|
mPushClass = FolderClass.FIRST_CLASS;
|
||||||
mInTopGroup = true;
|
mInTopGroup = true;
|
||||||
@ -1271,7 +1264,7 @@ public class LocalStore extends Store implements Serializable {
|
|||||||
}
|
}
|
||||||
Cursor cursor = null;
|
Cursor cursor = null;
|
||||||
try {
|
try {
|
||||||
cursor = db.rawQuery("SELECT COUNT(*) FROM messages WHERE folder_id = ?",
|
cursor = db.rawQuery("SELECT COUNT(*) FROM messages WHERE deleted = 0 and folder_id = ?",
|
||||||
new String[] {
|
new String[] {
|
||||||
Long.toString(mFolderId)
|
Long.toString(mFolderId)
|
||||||
});
|
});
|
||||||
@ -1484,19 +1477,19 @@ public class LocalStore extends Store implements Serializable {
|
|||||||
String id = getPrefId();
|
String id = getPrefId();
|
||||||
|
|
||||||
// there can be a lot of folders. For the defaults, let's not save prefs, saving space, except for INBOX
|
// there can be a lot of folders. For the defaults, let's not save prefs, saving space, except for INBOX
|
||||||
if (mDisplayClass == FolderClass.NO_CLASS && !K9.INBOX.equals(getName())) {
|
if (mDisplayClass == FolderClass.NO_CLASS && !mAccount.getInboxFolderName().equals(getName())) {
|
||||||
editor.remove(id + ".displayMode");
|
editor.remove(id + ".displayMode");
|
||||||
} else {
|
} else {
|
||||||
editor.putString(id + ".displayMode", mDisplayClass.name());
|
editor.putString(id + ".displayMode", mDisplayClass.name());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mSyncClass == FolderClass.INHERITED && !K9.INBOX.equals(getName())) {
|
if (mSyncClass == FolderClass.INHERITED && !mAccount.getInboxFolderName().equals(getName())) {
|
||||||
editor.remove(id + ".syncMode");
|
editor.remove(id + ".syncMode");
|
||||||
} else {
|
} else {
|
||||||
editor.putString(id + ".syncMode", mSyncClass.name());
|
editor.putString(id + ".syncMode", mSyncClass.name());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mPushClass == FolderClass.SECOND_CLASS && !K9.INBOX.equals(getName())) {
|
if (mPushClass == FolderClass.SECOND_CLASS && !mAccount.getInboxFolderName().equals(getName())) {
|
||||||
editor.remove(id + ".pushMode");
|
editor.remove(id + ".pushMode");
|
||||||
} else {
|
} else {
|
||||||
editor.putString(id + ".pushMode", mPushClass.name());
|
editor.putString(id + ".pushMode", mPushClass.name());
|
||||||
@ -1674,20 +1667,22 @@ public class LocalStore extends Store implements Serializable {
|
|||||||
body = new LocalAttachmentBody(Uri.parse(contentUri), mApplication);
|
body = new LocalAttachmentBody(Uri.parse(contentUri), mApplication);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MimeBodyPart bp = new LocalAttachmentBodyPart(body, id);
|
||||||
|
bp.setHeader(MimeHeader.HEADER_CONTENT_TRANSFER_ENCODING, "base64");
|
||||||
|
if (name != null) {
|
||||||
String encoded_name = EncoderUtil.encodeIfNecessary(name,
|
String encoded_name = EncoderUtil.encodeIfNecessary(name,
|
||||||
EncoderUtil.Usage.WORD_ENTITY, 7);
|
EncoderUtil.Usage.WORD_ENTITY, 7);
|
||||||
|
|
||||||
MimeBodyPart bp = new LocalAttachmentBodyPart(body, id);
|
|
||||||
bp.setHeader(MimeHeader.HEADER_CONTENT_TYPE,
|
bp.setHeader(MimeHeader.HEADER_CONTENT_TYPE,
|
||||||
String.format("%s;\n name=\"%s\"",
|
String.format("%s;\n name=\"%s\"",
|
||||||
type,
|
type,
|
||||||
encoded_name));
|
encoded_name));
|
||||||
bp.setHeader(MimeHeader.HEADER_CONTENT_TRANSFER_ENCODING, "base64");
|
|
||||||
bp.setHeader(MimeHeader.HEADER_CONTENT_DISPOSITION,
|
bp.setHeader(MimeHeader.HEADER_CONTENT_DISPOSITION,
|
||||||
String.format("%s;\n filename=\"%s\";\n size=%d",
|
String.format("%s;\n filename=\"%s\";\n size=%d",
|
||||||
contentDisposition,
|
contentDisposition,
|
||||||
encoded_name, // TODO: Should use encoded word defined in RFC 2231.
|
encoded_name, // TODO: Should use encoded word defined in RFC 2231.
|
||||||
size));
|
size));
|
||||||
|
}
|
||||||
|
|
||||||
bp.setHeader(MimeHeader.HEADER_CONTENT_ID, contentId);
|
bp.setHeader(MimeHeader.HEADER_CONTENT_ID, contentId);
|
||||||
/*
|
/*
|
||||||
@ -2076,6 +2071,15 @@ public class LocalStore extends Store implements Serializable {
|
|||||||
for (Part viewable : viewables) {
|
for (Part viewable : viewables) {
|
||||||
try {
|
try {
|
||||||
String text = MimeUtility.getTextFromPart(viewable);
|
String text = MimeUtility.getTextFromPart(viewable);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Small hack to make sure the string "null" doesn't end up
|
||||||
|
* in one of the StringBuffers.
|
||||||
|
*/
|
||||||
|
if (text == null) {
|
||||||
|
text = "";
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Anything with MIME type text/html will be stored as such. Anything
|
* Anything with MIME type text/html will be stored as such. Anything
|
||||||
* else will be stored as text/plain.
|
* else will be stored as text/plain.
|
||||||
@ -2181,6 +2185,15 @@ public class LocalStore extends Store implements Serializable {
|
|||||||
Part viewable = viewables.get(i);
|
Part viewable = viewables.get(i);
|
||||||
try {
|
try {
|
||||||
String text = MimeUtility.getTextFromPart(viewable);
|
String text = MimeUtility.getTextFromPart(viewable);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Small hack to make sure the string "null" doesn't end up
|
||||||
|
* in one of the StringBuffers.
|
||||||
|
*/
|
||||||
|
if (text == null) {
|
||||||
|
text = "";
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Anything with MIME type text/html will be stored as such. Anything
|
* Anything with MIME type text/html will be stored as such. Anything
|
||||||
* else will be stored as text/plain.
|
* else will be stored as text/plain.
|
||||||
@ -2427,17 +2440,19 @@ public class LocalStore extends Store implements Serializable {
|
|||||||
{ Long.toString(messageId) }, null, null, null);
|
{ Long.toString(messageId) }, null, null, null);
|
||||||
try {
|
try {
|
||||||
if (cursor.moveToNext()) {
|
if (cursor.moveToNext()) {
|
||||||
String new_html;
|
String htmlContent = cursor.getString(0);
|
||||||
|
|
||||||
new_html = cursor.getString(0);
|
if (htmlContent != null) {
|
||||||
new_html = new_html.replaceAll(Pattern.quote("cid:" + contentId),
|
String newHtmlContent = htmlContent.replaceAll(
|
||||||
|
Pattern.quote("cid:" + contentId),
|
||||||
contentUri.toString());
|
contentUri.toString());
|
||||||
|
|
||||||
ContentValues cv = new ContentValues();
|
ContentValues cv = new ContentValues();
|
||||||
cv.put("html_content", new_html);
|
cv.put("html_content", newHtmlContent);
|
||||||
db.update("messages", cv, "id = ?", new String[]
|
db.update("messages", cv, "id = ?", new String[]
|
||||||
{ Long.toString(messageId) });
|
{ Long.toString(messageId) });
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
if (cursor != null) {
|
if (cursor != null) {
|
||||||
cursor.close();
|
cursor.close();
|
||||||
@ -2552,6 +2567,7 @@ public class LocalStore extends Store implements Serializable {
|
|||||||
setPushState(null);
|
setPushState(null);
|
||||||
setLastPush(0);
|
setLastPush(0);
|
||||||
setLastChecked(0);
|
setLastChecked(0);
|
||||||
|
setVisibleLimit(mAccount.getDisplayCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resetUnreadAndFlaggedCounts() {
|
private void resetUnreadAndFlaggedCounts() {
|
||||||
@ -2707,19 +2723,26 @@ public class LocalStore extends Store implements Serializable {
|
|||||||
text = text.substring(0, 8192);
|
text = text.substring(0, 8192);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// try to remove lines of dashes in the preview
|
||||||
text = text.replaceAll("(?m)^----.*?$", "");
|
text = text.replaceAll("(?m)^----.*?$", "");
|
||||||
|
// remove quoted text from the preview
|
||||||
text = text.replaceAll("(?m)^[#>].*$", "");
|
text = text.replaceAll("(?m)^[#>].*$", "");
|
||||||
|
// Remove a common quote header from the preview
|
||||||
text = text.replaceAll("(?m)^On .*wrote.?$", "");
|
text = text.replaceAll("(?m)^On .*wrote.?$", "");
|
||||||
|
// Remove a more generic quote header from the preview
|
||||||
text = text.replaceAll("(?m)^.*\\w+:$", "");
|
text = text.replaceAll("(?m)^.*\\w+:$", "");
|
||||||
|
|
||||||
|
// URLs in the preview should just be shown as "..." - They're not
|
||||||
|
// clickable and they usually overwhelm the preview
|
||||||
text = text.replaceAll("https?://\\S+", "...");
|
text = text.replaceAll("https?://\\S+", "...");
|
||||||
|
// Don't show newlines in the preview
|
||||||
text = text.replaceAll("(\\r|\\n)+", " ");
|
text = text.replaceAll("(\\r|\\n)+", " ");
|
||||||
|
// Collapse whitespace in the preview
|
||||||
text = text.replaceAll("\\s+", " ");
|
text = text.replaceAll("\\s+", " ");
|
||||||
if (text.length() <= 512) {
|
if (text.length() <= 512) {
|
||||||
return text;
|
return text;
|
||||||
} else {
|
} else {
|
||||||
text = text.substring(0, 512);
|
return text.substring(0, 512);
|
||||||
return text;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -43,6 +43,13 @@ public class Pop3Store extends Store {
|
|||||||
private HashMap<String, Folder> mFolders = new HashMap<String, Folder>();
|
private HashMap<String, Folder> mFolders = new HashMap<String, Folder>();
|
||||||
private Pop3Capabilities mCapabilities;
|
private Pop3Capabilities mCapabilities;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This value is {@code true} if the server supports the CAPA command but doesn't advertise
|
||||||
|
* support for the TOP command OR if the server doesn't support the CAPA command and we
|
||||||
|
* already unsuccessfully tried to use the TOP command.
|
||||||
|
*/
|
||||||
|
private boolean mTopNotSupported;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pop3://user:password@server:port CONNECTION_SECURITY_NONE
|
* pop3://user:password@server:port CONNECTION_SECURITY_NONE
|
||||||
* pop3+tls://user:password@server:port CONNECTION_SECURITY_TLS_OPTIONAL
|
* pop3+tls://user:password@server:port CONNECTION_SECURITY_TLS_OPTIONAL
|
||||||
@ -91,8 +98,7 @@ public class Pop3Store extends Store {
|
|||||||
try {
|
try {
|
||||||
int userIndex = 0, passwordIndex = 1;
|
int userIndex = 0, passwordIndex = 1;
|
||||||
String[] userInfoParts = uri.getUserInfo().split(":");
|
String[] userInfoParts = uri.getUserInfo().split(":");
|
||||||
if (userInfoParts.length > 2)
|
if (userInfoParts.length > 2) {
|
||||||
{
|
|
||||||
userIndex++;
|
userIndex++;
|
||||||
passwordIndex++;
|
passwordIndex++;
|
||||||
useCramMd5 = true;
|
useCramMd5 = true;
|
||||||
@ -121,13 +127,13 @@ public class Pop3Store extends Store {
|
|||||||
@Override
|
@Override
|
||||||
public List <? extends Folder > getPersonalNamespaces(boolean forceListAll) throws MessagingException {
|
public List <? extends Folder > getPersonalNamespaces(boolean forceListAll) throws MessagingException {
|
||||||
List<Folder> folders = new LinkedList<Folder>();
|
List<Folder> folders = new LinkedList<Folder>();
|
||||||
folders.add(getFolder("INBOX"));
|
folders.add(getFolder(mAccount.getInboxFolderName()));
|
||||||
return folders;
|
return folders;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void checkSettings() throws MessagingException {
|
public void checkSettings() throws MessagingException {
|
||||||
Pop3Folder folder = new Pop3Folder("INBOX");
|
Pop3Folder folder = new Pop3Folder(mAccount.getInboxFolderName());
|
||||||
folder.open(OpenMode.READ_WRITE);
|
folder.open(OpenMode.READ_WRITE);
|
||||||
if (!mCapabilities.uidl) {
|
if (!mCapabilities.uidl) {
|
||||||
/*
|
/*
|
||||||
@ -158,8 +164,9 @@ public class Pop3Store extends Store {
|
|||||||
public Pop3Folder(String name) {
|
public Pop3Folder(String name) {
|
||||||
super(Pop3Store.this.mAccount);
|
super(Pop3Store.this.mAccount);
|
||||||
this.mName = name;
|
this.mName = name;
|
||||||
if (mName.equalsIgnoreCase("INBOX")) {
|
|
||||||
mName = "INBOX";
|
if (mName.equalsIgnoreCase(mAccount.getInboxFolderName())) {
|
||||||
|
mName = mAccount.getInboxFolderName();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,7 +176,7 @@ public class Pop3Store extends Store {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mName.equalsIgnoreCase("INBOX")) {
|
if (!mName.equalsIgnoreCase(mAccount.getInboxFolderName())) {
|
||||||
throw new MessagingException("Folder does not exist");
|
throw new MessagingException("Folder does not exist");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,8 +231,7 @@ public class Pop3Store extends Store {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (useCramMd5)
|
if (useCramMd5) {
|
||||||
{
|
|
||||||
try {
|
try {
|
||||||
String b64Nonce = executeSimpleCommand("AUTH CRAM-MD5").replace("+ ", "");
|
String b64Nonce = executeSimpleCommand("AUTH CRAM-MD5").replace("+ ", "");
|
||||||
|
|
||||||
@ -235,9 +241,7 @@ public class Pop3Store extends Store {
|
|||||||
} catch (MessagingException me) {
|
} catch (MessagingException me) {
|
||||||
throw new AuthenticationFailedException(null, me);
|
throw new AuthenticationFailedException(null, me);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
try {
|
try {
|
||||||
executeSimpleCommand("USER " + mUsername);
|
executeSimpleCommand("USER " + mUsername);
|
||||||
executeSimpleCommand("PASS " + mPassword, true);
|
executeSimpleCommand("PASS " + mPassword, true);
|
||||||
@ -279,7 +283,9 @@ public class Pop3Store extends Store {
|
|||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
try {
|
try {
|
||||||
|
if (isOpen()) {
|
||||||
executeSimpleCommand("QUIT");
|
executeSimpleCommand("QUIT");
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
/*
|
/*
|
||||||
* QUIT may fail if the connection is already closed. We don't care. It's just
|
* QUIT may fail if the connection is already closed. We don't care. It's just
|
||||||
@ -329,7 +335,7 @@ public class Pop3Store extends Store {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean exists() throws MessagingException {
|
public boolean exists() throws MessagingException {
|
||||||
return mName.equalsIgnoreCase("INBOX");
|
return mName.equalsIgnoreCase(mAccount.getInboxFolderName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -659,28 +665,55 @@ public class Pop3Store extends Store {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetches the body of the given message, limiting the stored data
|
* Fetches the body of the given message, limiting the downloaded data to the specified
|
||||||
* to the specified number of lines. If lines is -1 the entire message
|
* number of lines if possible.
|
||||||
* is fetched. This is implemented with RETR for lines = -1 or TOP
|
*
|
||||||
* for any other value. If the server does not support TOP it is
|
* If lines is -1 the entire message is fetched. This is implemented with RETR for
|
||||||
* emulated with RETR and extra lines are thrown away.
|
* lines = -1 or TOP for any other value. If the server does not support TOP, RETR is used
|
||||||
* @param message
|
* instead.
|
||||||
* @param lines
|
|
||||||
*/
|
*/
|
||||||
private void fetchBody(Pop3Message message, int lines)
|
private void fetchBody(Pop3Message message, int lines)
|
||||||
throws IOException, MessagingException {
|
throws IOException, MessagingException {
|
||||||
String response = null;
|
String response = null;
|
||||||
if (lines == -1 || !mCapabilities.top) {
|
|
||||||
|
// Try hard to use the TOP command if we're not asked to download the whole message.
|
||||||
|
if (lines != -1 && (!mTopNotSupported || mCapabilities.top)) {
|
||||||
|
try {
|
||||||
|
if (K9.DEBUG && K9.DEBUG_PROTOCOL_POP3 && !mCapabilities.top) {
|
||||||
|
Log.d(K9.LOG_TAG, "This server doesn't support the CAPA command. " +
|
||||||
|
"Checking to see if the TOP command is supported nevertheless.");
|
||||||
|
}
|
||||||
|
|
||||||
|
response = executeSimpleCommand(String.format("TOP %d %d",
|
||||||
|
mUidToMsgNumMap.get(message.getUid()), lines));
|
||||||
|
|
||||||
|
// TOP command is supported. Remember this for the next time.
|
||||||
|
mCapabilities.top = true;
|
||||||
|
} catch (Pop3ErrorResponse e) {
|
||||||
|
if (mCapabilities.top) {
|
||||||
|
// The TOP command should be supported but something went wrong.
|
||||||
|
throw e;
|
||||||
|
} else {
|
||||||
|
if (K9.DEBUG && K9.DEBUG_PROTOCOL_POP3) {
|
||||||
|
Log.d(K9.LOG_TAG, "The server really doesn't support the TOP " +
|
||||||
|
"command. Using RETR instead.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't try to use the TOP command again.
|
||||||
|
mTopNotSupported = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response == null) {
|
||||||
response = executeSimpleCommand(String.format("RETR %d",
|
response = executeSimpleCommand(String.format("RETR %d",
|
||||||
mUidToMsgNumMap.get(message.getUid())));
|
mUidToMsgNumMap.get(message.getUid())));
|
||||||
} else {
|
|
||||||
response = executeSimpleCommand(String.format("TOP %d %d",
|
|
||||||
mUidToMsgNumMap.get(message.getUid()),
|
|
||||||
lines));
|
|
||||||
}
|
}
|
||||||
if (response != null) {
|
|
||||||
try {
|
try {
|
||||||
message.parse(new Pop3ResponseInputStream(mIn));
|
message.parse(new Pop3ResponseInputStream(mIn));
|
||||||
|
|
||||||
|
// TODO: if we've received fewer lines than requested we also have the complete message.
|
||||||
if (lines == -1 || !mCapabilities.top) {
|
if (lines == -1 || !mCapabilities.top) {
|
||||||
message.setFlag(Flag.X_DOWNLOADED_FULL, true);
|
message.setFlag(Flag.X_DOWNLOADED_FULL, true);
|
||||||
}
|
}
|
||||||
@ -696,7 +729,6 @@ public class Pop3Store extends Store {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Flag[] getPermanentFlags() {
|
public Flag[] getPermanentFlags() {
|
||||||
@ -722,10 +754,8 @@ public class Pop3Store extends Store {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setFlags(Flag[] flags, boolean value)
|
public void setFlags(Flag[] flags, boolean value) throws MessagingException {
|
||||||
throws MessagingException {
|
throw new UnsupportedOperationException("POP3: No setFlags(Flag[],boolean)");
|
||||||
Message[] messages = getMessages(null);
|
|
||||||
setFlags(messages, flags, value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -809,6 +839,14 @@ public class Pop3Store extends Store {
|
|||||||
capabilities.top = true;
|
capabilities.top = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!capabilities.top) {
|
||||||
|
/*
|
||||||
|
* If the CAPA command is supported but it doesn't advertise support for the
|
||||||
|
* TOP command, we won't check for it manually.
|
||||||
|
*/
|
||||||
|
mTopNotSupported = true;
|
||||||
|
}
|
||||||
} catch (MessagingException me) {
|
} catch (MessagingException me) {
|
||||||
/*
|
/*
|
||||||
* The server may not support the CAPA command, so we just eat this Exception
|
* The server may not support the CAPA command, so we just eat this Exception
|
||||||
@ -841,7 +879,7 @@ public class Pop3Store extends Store {
|
|||||||
|
|
||||||
String response = readLine();
|
String response = readLine();
|
||||||
if (response.length() > 1 && response.charAt(0) == '-') {
|
if (response.length() > 1 && response.charAt(0) == '-') {
|
||||||
throw new MessagingException(response);
|
throw new Pop3ErrorResponse(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
@ -853,6 +891,11 @@ public class Pop3Store extends Store {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isFlagSupported(Flag flag) {
|
||||||
|
return (flag == Flag.DELETED);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsFetchingFlags() {
|
public boolean supportsFetchingFlags() {
|
||||||
return false;
|
return false;
|
||||||
@ -956,4 +999,13 @@ public class Pop3Store extends Store {
|
|||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception that is thrown if the server returns an error response.
|
||||||
|
*/
|
||||||
|
static class Pop3ErrorResponse extends MessagingException {
|
||||||
|
public Pop3ErrorResponse(String message) {
|
||||||
|
super(message, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@ import android.util.Log;
|
|||||||
|
|
||||||
import com.fsck.k9.Account;
|
import com.fsck.k9.Account;
|
||||||
import com.fsck.k9.K9;
|
import com.fsck.k9.K9;
|
||||||
import com.fsck.k9.R;
|
|
||||||
import com.fsck.k9.controller.MessageRetrievalListener;
|
import com.fsck.k9.controller.MessageRetrievalListener;
|
||||||
import com.fsck.k9.helper.Utility;
|
import com.fsck.k9.helper.Utility;
|
||||||
import com.fsck.k9.mail.*;
|
import com.fsck.k9.mail.*;
|
||||||
@ -51,6 +50,7 @@ import java.util.Date;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.Stack;
|
import java.util.Stack;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
@ -79,8 +79,15 @@ public class WebDavStore extends Store {
|
|||||||
|
|
||||||
private static final Message[] EMPTY_MESSAGE_ARRAY = new Message[0];
|
private static final Message[] EMPTY_MESSAGE_ARRAY = new Message[0];
|
||||||
|
|
||||||
|
// These are the ids used from Exchange server to identify the special folders
|
||||||
|
// http://social.technet.microsoft.com/Forums/en/exchangesvrdevelopment/thread/1cd2e98c-8a12-44bd-a3e3-9c5ee9e4e14d
|
||||||
|
private static final String DAV_MAIL_INBOX_FOLDER = "inbox";
|
||||||
|
private static final String DAV_MAIL_DRAFTS_FOLDER = "drafts";
|
||||||
|
private static final String DAV_MAIL_SPAM_FOLDER = "junkemail";
|
||||||
private static final String DAV_MAIL_SEND_FOLDER = "##DavMailSubmissionURI##";
|
private static final String DAV_MAIL_SEND_FOLDER = "##DavMailSubmissionURI##";
|
||||||
private static final String DAV_MAIL_TMP_FOLDER = "drafts";
|
private static final String DAV_MAIL_TRASH_FOLDER = "deleteditems";
|
||||||
|
private static final String DAV_MAIL_OUTBOX_FOLDER = "outbox";
|
||||||
|
private static final String DAV_MAIL_SENT_FOLDER = "sentitems";
|
||||||
|
|
||||||
private short mConnectionSecurity;
|
private short mConnectionSecurity;
|
||||||
private String mUsername; /* Stores the username for authentications */
|
private String mUsername; /* Stores the username for authentications */
|
||||||
@ -101,6 +108,7 @@ public class WebDavStore extends Store {
|
|||||||
private short mAuthentication = AUTH_TYPE_NONE;
|
private short mAuthentication = AUTH_TYPE_NONE;
|
||||||
private String mCachedLoginUrl;
|
private String mCachedLoginUrl;
|
||||||
|
|
||||||
|
private Folder mSendFolder = null;
|
||||||
private HashMap<String, WebDavFolder> mFolderList = new HashMap<String, WebDavFolder>();
|
private HashMap<String, WebDavFolder> mFolderList = new HashMap<String, WebDavFolder>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -231,63 +239,136 @@ public class WebDavStore extends Store {
|
|||||||
@Override
|
@Override
|
||||||
public List <? extends Folder > getPersonalNamespaces(boolean forceListAll) throws MessagingException {
|
public List <? extends Folder > getPersonalNamespaces(boolean forceListAll) throws MessagingException {
|
||||||
LinkedList<Folder> folderList = new LinkedList<Folder>();
|
LinkedList<Folder> folderList = new LinkedList<Folder>();
|
||||||
HashMap<String, String> headers = new HashMap<String, String>();
|
|
||||||
DataSet dataset = new DataSet();
|
|
||||||
String messageBody;
|
|
||||||
String[] folderUrls;
|
|
||||||
int urlLength;
|
|
||||||
|
|
||||||
String translatedInbox = K9.app.getString(R.string.special_mailbox_name_inbox);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We have to check authentication here so we have the proper URL stored
|
* We have to check authentication here so we have the proper URL stored
|
||||||
*/
|
*/
|
||||||
getHttpClient();
|
getHttpClient();
|
||||||
messageBody = getFolderListXml();
|
|
||||||
|
/**
|
||||||
|
* Firstly we get the "special" folders list (inbox, outbox, etc)
|
||||||
|
* and setup the account accordingly
|
||||||
|
*/
|
||||||
|
HashMap<String, String> headers = new HashMap<String, String>();
|
||||||
|
DataSet dataset = new DataSet();
|
||||||
|
headers.put("Depth", "0");
|
||||||
headers.put("Brief", "t");
|
headers.put("Brief", "t");
|
||||||
dataset = processRequest(this.mUrl, "SEARCH", messageBody, headers);
|
dataset = processRequest(this.mUrl, "PROPFIND", getSpecialFoldersList(), headers);
|
||||||
|
|
||||||
folderUrls = dataset.getHrefs();
|
HashMap<String, String> specialFoldersMap = dataset.getSpecialFolderToUrl();
|
||||||
urlLength = folderUrls.length;
|
String folderName = getFolderName(specialFoldersMap.get(DAV_MAIL_INBOX_FOLDER));
|
||||||
|
if (folderName != null) {
|
||||||
for (int i = 0; i < urlLength; i++) {
|
mAccount.setAutoExpandFolderName(folderName);
|
||||||
String[] urlParts = folderUrls[i].split("/");
|
mAccount.setInboxFolderName(folderName);
|
||||||
String folderName = urlParts[urlParts.length - 1];
|
|
||||||
String fullPathName = "";
|
|
||||||
WebDavFolder wdFolder;
|
|
||||||
|
|
||||||
// Check each Exchange folder name to see if it is the user's inbox.
|
|
||||||
// We will check for the default English inbox ("Inbox"), and the user's
|
|
||||||
// translation for "Inbox", in case the user is using a non-English
|
|
||||||
// version of Exchange.
|
|
||||||
if (folderName.equalsIgnoreCase("Inbox") ||
|
|
||||||
folderName.equalsIgnoreCase(translatedInbox)) {
|
|
||||||
folderName = K9.INBOX;
|
|
||||||
} else {
|
|
||||||
for (int j = 5, count = urlParts.length; j < count; j++) {
|
|
||||||
if (j != 5) {
|
|
||||||
fullPathName = fullPathName + "/" + urlParts[j];
|
|
||||||
} else {
|
|
||||||
fullPathName = urlParts[j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
folderName = java.net.URLDecoder.decode(fullPathName, "UTF-8");
|
|
||||||
} catch (UnsupportedEncodingException uee) {
|
|
||||||
/** If we don't support UTF-8 there's a problem, don't decode it then */
|
|
||||||
folderName = fullPathName;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wdFolder = new WebDavFolder(this, folderName);
|
folderName = getFolderName(specialFoldersMap.get(DAV_MAIL_DRAFTS_FOLDER));
|
||||||
wdFolder.setUrl(folderUrls[i]);
|
if (folderName != null)
|
||||||
folderList.add(wdFolder);
|
mAccount.setDraftsFolderName(folderName);
|
||||||
this.mFolderList.put(folderName, wdFolder);
|
|
||||||
|
folderName = getFolderName(specialFoldersMap.get(DAV_MAIL_TRASH_FOLDER));
|
||||||
|
if (folderName != null)
|
||||||
|
mAccount.setTrashFolderName(folderName);
|
||||||
|
|
||||||
|
folderName = getFolderName(specialFoldersMap.get(DAV_MAIL_SPAM_FOLDER));
|
||||||
|
if (folderName != null)
|
||||||
|
mAccount.setSpamFolderName(folderName);
|
||||||
|
|
||||||
|
// K-9 Mail's outbox is a special local folder and different from Exchange/WebDAV's outbox.
|
||||||
|
/*
|
||||||
|
folderName = getFolderName(specialFoldersMap.get(DAV_MAIL_OUTBOX_FOLDER));
|
||||||
|
if (folderName != null)
|
||||||
|
mAccount.setOutboxFolderName(folderName);
|
||||||
|
*/
|
||||||
|
|
||||||
|
folderName = getFolderName(specialFoldersMap.get(DAV_MAIL_SENT_FOLDER));
|
||||||
|
if (folderName != null)
|
||||||
|
mAccount.setSentFolderName(folderName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Next we get all the folders (including "special" ones)
|
||||||
|
*/
|
||||||
|
headers = new HashMap<String, String>();
|
||||||
|
dataset = new DataSet();
|
||||||
|
headers.put("Brief", "t");
|
||||||
|
dataset = processRequest(this.mUrl, "SEARCH", getFolderListXml(), headers);
|
||||||
|
String[] folderUrls = dataset.getHrefs();
|
||||||
|
|
||||||
|
for (int i = 0; i < folderUrls.length; i++) {
|
||||||
|
String tempUrl = folderUrls[i];
|
||||||
|
WebDavFolder folder = createFolder(tempUrl);
|
||||||
|
if (folder != null)
|
||||||
|
folderList.add(folder);
|
||||||
}
|
}
|
||||||
|
|
||||||
return folderList;
|
return folderList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a folder using the URL passed as parameter (only if it has not been
|
||||||
|
* already created) and adds this to our store folder map.
|
||||||
|
*
|
||||||
|
* @param folderUrl
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private WebDavFolder createFolder(String folderUrl) {
|
||||||
|
if (folderUrl == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
WebDavFolder wdFolder = null;
|
||||||
|
String folderName = getFolderName(folderUrl);
|
||||||
|
if (folderName != null) {
|
||||||
|
if (!this.mFolderList.containsKey(folderName)) {
|
||||||
|
wdFolder = new WebDavFolder(this, folderName);
|
||||||
|
wdFolder.setUrl(folderUrl);
|
||||||
|
mFolderList.put(folderName, wdFolder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// else: Unknown URL format => NO Folder created
|
||||||
|
|
||||||
|
return wdFolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getFolderName(String folderUrl) {
|
||||||
|
if (folderUrl == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
// Here we extract the folder name starting from the complete url.
|
||||||
|
// folderUrl is in the form http://mail.domain.com/exchange/username/foldername
|
||||||
|
// so we need "foldername" which is the string after the fifth slash
|
||||||
|
int folderSlash = -1;
|
||||||
|
for (int j = 0; j < 5; j++) {
|
||||||
|
folderSlash = folderUrl.indexOf('/', folderSlash + 1);
|
||||||
|
if (folderSlash < 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (folderSlash > 0) {
|
||||||
|
String folderName;
|
||||||
|
String fullPathName;
|
||||||
|
|
||||||
|
// Removes the final slash if present
|
||||||
|
if (folderUrl.charAt(folderUrl.length() - 1) == '/')
|
||||||
|
fullPathName = folderUrl.substring(folderSlash + 1, folderUrl.length() - 1);
|
||||||
|
else
|
||||||
|
fullPathName = folderUrl.substring(folderSlash + 1);
|
||||||
|
|
||||||
|
// Decodes the url-encoded folder name (i.e. "My%20folder" => "My Folder"
|
||||||
|
try {
|
||||||
|
folderName = java.net.URLDecoder.decode(fullPathName, "UTF-8");
|
||||||
|
} catch (UnsupportedEncodingException uee) {
|
||||||
|
/**
|
||||||
|
* If we don't support UTF-8 there's a problem, don't decode
|
||||||
|
* it then
|
||||||
|
*/
|
||||||
|
folderName = fullPathName;
|
||||||
|
}
|
||||||
|
|
||||||
|
return folderName;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Folder getFolder(String name) {
|
public Folder getFolder(String name) {
|
||||||
WebDavFolder folder;
|
WebDavFolder folder;
|
||||||
@ -300,7 +381,10 @@ public class WebDavStore extends Store {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Folder getSendSpoolFolder() throws MessagingException {
|
public Folder getSendSpoolFolder() throws MessagingException {
|
||||||
return getFolder(DAV_MAIL_SEND_FOLDER);
|
if (mSendFolder == null)
|
||||||
|
mSendFolder = getFolder(DAV_MAIL_SEND_FOLDER);
|
||||||
|
|
||||||
|
return mSendFolder;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -313,6 +397,26 @@ public class WebDavStore extends Store {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getSpecialFoldersList() {
|
||||||
|
StringBuffer buffer = new StringBuffer(200);
|
||||||
|
buffer.append("<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\"?>");
|
||||||
|
buffer.append("<propfind xmlns=\"DAV:\">");
|
||||||
|
buffer.append("<prop>");
|
||||||
|
buffer.append("<").append(DAV_MAIL_INBOX_FOLDER).append(" xmlns=\"urn:schemas:httpmail:\"/>");
|
||||||
|
buffer.append("<").append(DAV_MAIL_DRAFTS_FOLDER).append(" xmlns=\"urn:schemas:httpmail:\"/>");
|
||||||
|
buffer.append("<").append(DAV_MAIL_OUTBOX_FOLDER).append(" xmlns=\"urn:schemas:httpmail:\"/>");
|
||||||
|
buffer.append("<").append(DAV_MAIL_SENT_FOLDER).append(" xmlns=\"urn:schemas:httpmail:\"/>");
|
||||||
|
buffer.append("<").append(DAV_MAIL_TRASH_FOLDER).append(" xmlns=\"urn:schemas:httpmail:\"/>");
|
||||||
|
// This should always be ##DavMailSubmissionURI## for which we already have a constant
|
||||||
|
// buffer.append("<sendmsg xmlns=\"urn:schemas:httpmail:\"/>");
|
||||||
|
|
||||||
|
buffer.append("<").append(DAV_MAIL_SPAM_FOLDER).append(" xmlns=\"urn:schemas:httpmail:\"/>");
|
||||||
|
|
||||||
|
buffer.append("</prop>");
|
||||||
|
buffer.append("</propfind>");
|
||||||
|
return buffer.toString();
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************
|
/***************************************************************
|
||||||
* WebDAV XML Request body retrieval functions
|
* WebDAV XML Request body retrieval functions
|
||||||
*/
|
*/
|
||||||
@ -980,7 +1084,7 @@ public class WebDavStore extends Store {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendMessages(Message[] messages) throws MessagingException {
|
public void sendMessages(Message[] messages) throws MessagingException {
|
||||||
WebDavFolder tmpFolder = (WebDavStore.WebDavFolder) getFolder(DAV_MAIL_TMP_FOLDER);
|
WebDavFolder tmpFolder = (WebDavStore.WebDavFolder) getFolder(mAccount.getDraftsFolderName());
|
||||||
try {
|
try {
|
||||||
tmpFolder.open(OpenMode.READ_WRITE);
|
tmpFolder.open(OpenMode.READ_WRITE);
|
||||||
Message[] retMessages = tmpFolder.appendWebDavMessages(messages);
|
Message[] retMessages = tmpFolder.appendWebDavMessages(messages);
|
||||||
@ -1017,9 +1121,6 @@ public class WebDavStore extends Store {
|
|||||||
store = nStore;
|
store = nStore;
|
||||||
this.mName = name;
|
this.mName = name;
|
||||||
|
|
||||||
if (DAV_MAIL_SEND_FOLDER.equals(name)) {
|
|
||||||
this.mFolderUrl = getUrl() + "/" + name + "/";
|
|
||||||
} else {
|
|
||||||
String encodedName = "";
|
String encodedName = "";
|
||||||
try {
|
try {
|
||||||
String[] urlParts = name.split("/");
|
String[] urlParts = name.split("/");
|
||||||
@ -1039,16 +1140,12 @@ public class WebDavStore extends Store {
|
|||||||
|
|
||||||
encodedName = encodedName.replaceAll("\\+", "%20");
|
encodedName = encodedName.replaceAll("\\+", "%20");
|
||||||
|
|
||||||
if (encodedName.equals(K9.INBOX)) {
|
|
||||||
encodedName = "Inbox";
|
|
||||||
}
|
|
||||||
this.mFolderUrl = WebDavStore.this.mUrl;
|
this.mFolderUrl = WebDavStore.this.mUrl;
|
||||||
if (!WebDavStore.this.mUrl.endsWith("/")) {
|
if (!WebDavStore.this.mUrl.endsWith("/")) {
|
||||||
this.mFolderUrl += "/";
|
this.mFolderUrl += "/";
|
||||||
}
|
}
|
||||||
this.mFolderUrl += encodedName;
|
this.mFolderUrl += encodedName;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public void setUrl(String url) {
|
public void setUrl(String url) {
|
||||||
if (url != null) {
|
if (url != null) {
|
||||||
@ -1977,6 +2074,17 @@ public class WebDavStore extends Store {
|
|||||||
mTempData = new HashMap<String, String>();
|
mTempData = new HashMap<String, String>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a hashmap of special folder name => special folder url
|
||||||
|
*/
|
||||||
|
public HashMap<String, String> getSpecialFolderToUrl() {
|
||||||
|
// We return the first (and only) map
|
||||||
|
for (HashMap<String, String> folderMap : mData.values()) {
|
||||||
|
return folderMap;
|
||||||
|
}
|
||||||
|
return new HashMap<String, String>();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a hashmap of Message UID => Message Url
|
* Returns a hashmap of Message UID => Message Url
|
||||||
*/
|
*/
|
||||||
@ -2088,8 +2196,8 @@ public class WebDavStore extends Store {
|
|||||||
String date = data.get(header);
|
String date = data.get(header);
|
||||||
date = date.substring(0, date.length() - 1);
|
date = date.substring(0, date.length() - 1);
|
||||||
|
|
||||||
DateFormat dfInput = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
|
DateFormat dfInput = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.US);
|
||||||
DateFormat dfOutput = new SimpleDateFormat("EEE, d MMM yy HH:mm:ss Z");
|
DateFormat dfOutput = new SimpleDateFormat("EEE, d MMM yy HH:mm:ss Z", Locale.US);
|
||||||
String tempDate = "";
|
String tempDate = "";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -39,6 +39,14 @@ public class SmtpTransport extends Transport {
|
|||||||
|
|
||||||
public static final int CONNECTION_SECURITY_SSL_OPTIONAL = 4;
|
public static final int CONNECTION_SECURITY_SSL_OPTIONAL = 4;
|
||||||
|
|
||||||
|
public static final String AUTH_PLAIN = "PLAIN";
|
||||||
|
|
||||||
|
public static final String AUTH_CRAM_MD5 = "CRAM_MD5";
|
||||||
|
|
||||||
|
public static final String AUTH_LOGIN = "LOGIN";
|
||||||
|
|
||||||
|
public static final String AUTH_AUTOMATIC = "AUTOMATIC";
|
||||||
|
|
||||||
String mHost;
|
String mHost;
|
||||||
|
|
||||||
int mPort;
|
int mPort;
|
||||||
@ -163,7 +171,7 @@ public class SmtpTransport extends Transport {
|
|||||||
executeSimpleCommand(null);
|
executeSimpleCommand(null);
|
||||||
|
|
||||||
InetAddress localAddress = mSocket.getLocalAddress();
|
InetAddress localAddress = mSocket.getLocalAddress();
|
||||||
String localHost = localAddress.getHostName();
|
String localHost = localAddress.getCanonicalHostName();
|
||||||
String ipAddr = localAddress.getHostAddress();
|
String ipAddr = localAddress.getHostAddress();
|
||||||
|
|
||||||
if (localHost.equals("") || localHost.equals(ipAddr) || localHost.contains("_")) {
|
if (localHost.equals("") || localHost.equals(ipAddr) || localHost.contains("_")) {
|
||||||
@ -221,9 +229,13 @@ public class SmtpTransport extends Transport {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
boolean useAuthLogin = AUTH_LOGIN.equals(mAuthType);
|
||||||
* result contains the results of the EHLO in concatenated form
|
boolean useAuthPlain = AUTH_PLAIN.equals(mAuthType);
|
||||||
*/
|
boolean useAuthCramMD5 = AUTH_CRAM_MD5.equals(mAuthType);
|
||||||
|
|
||||||
|
// Automatically choose best authentication method if none was explicitly selected
|
||||||
|
boolean useAutomaticAuth = !(useAuthLogin || useAuthPlain || useAuthCramMD5);
|
||||||
|
|
||||||
boolean authLoginSupported = false;
|
boolean authLoginSupported = false;
|
||||||
boolean authPlainSupported = false;
|
boolean authPlainSupported = false;
|
||||||
boolean authCramMD5Supported = false;
|
boolean authCramMD5Supported = false;
|
||||||
@ -234,7 +246,7 @@ public class SmtpTransport extends Transport {
|
|||||||
if (result.matches(".*AUTH.*PLAIN.*$")) {
|
if (result.matches(".*AUTH.*PLAIN.*$")) {
|
||||||
authPlainSupported = true;
|
authPlainSupported = true;
|
||||||
}
|
}
|
||||||
if (result.matches(".*AUTH.*CRAM-MD5.*$") && mAuthType != null && mAuthType.equals("CRAM_MD5")) {
|
if (result.matches(".*AUTH.*CRAM-MD5.*$")) {
|
||||||
authCramMD5Supported = true;
|
authCramMD5Supported = true;
|
||||||
}
|
}
|
||||||
if (result.matches(".*SIZE \\d*$")) {
|
if (result.matches(".*SIZE \\d*$")) {
|
||||||
@ -248,13 +260,40 @@ public class SmtpTransport extends Transport {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mUsername != null && mUsername.length() > 0 && mPassword != null
|
if (mUsername != null && mUsername.length() > 0 &&
|
||||||
&& mPassword.length() > 0) {
|
mPassword != null && mPassword.length() > 0) {
|
||||||
if (authCramMD5Supported) {
|
if (useAuthCramMD5 || (useAutomaticAuth && authCramMD5Supported)) {
|
||||||
|
if (!authCramMD5Supported && K9.DEBUG && K9.DEBUG_PROTOCOL_SMTP) {
|
||||||
|
Log.d(K9.LOG_TAG, "Using CRAM_MD5 as authentication method although the " +
|
||||||
|
"server didn't advertise support for it in EHLO response.");
|
||||||
|
}
|
||||||
saslAuthCramMD5(mUsername, mPassword);
|
saslAuthCramMD5(mUsername, mPassword);
|
||||||
} else if (authPlainSupported) {
|
} else if (useAuthPlain || (useAutomaticAuth && authPlainSupported)) {
|
||||||
|
if (!authPlainSupported && K9.DEBUG && K9.DEBUG_PROTOCOL_SMTP) {
|
||||||
|
Log.d(K9.LOG_TAG, "Using PLAIN as authentication method although the " +
|
||||||
|
"server didn't advertise support for it in EHLO response.");
|
||||||
|
}
|
||||||
|
try {
|
||||||
saslAuthPlain(mUsername, mPassword);
|
saslAuthPlain(mUsername, mPassword);
|
||||||
} else if (authLoginSupported) {
|
} catch (MessagingException ex) {
|
||||||
|
// PLAIN is a special case. Historically, PLAIN has represented both PLAIN and LOGIN; only the
|
||||||
|
// protocol being advertised by the server would be used, with PLAIN taking precedence. Instead
|
||||||
|
// of using only the requested protocol, we'll try PLAIN and then try LOGIN.
|
||||||
|
if (useAuthPlain && authLoginSupported) {
|
||||||
|
if (K9.DEBUG && K9.DEBUG_PROTOCOL_SMTP) {
|
||||||
|
Log.d(K9.LOG_TAG, "Using legacy PLAIN authentication behavior and trying LOGIN.");
|
||||||
|
}
|
||||||
|
saslAuthLogin(mUsername, mPassword);
|
||||||
|
} else {
|
||||||
|
// If it was auto detected and failed, continue throwing the exception back up.
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (useAuthLogin || (useAutomaticAuth && authLoginSupported)) {
|
||||||
|
if (!authPlainSupported && K9.DEBUG && K9.DEBUG_PROTOCOL_SMTP) {
|
||||||
|
Log.d(K9.LOG_TAG, "Using LOGIN as authentication method although the " +
|
||||||
|
"server didn't advertise support for it in EHLO response.");
|
||||||
|
}
|
||||||
saslAuthLogin(mUsername, mPassword);
|
saslAuthLogin(mUsername, mPassword);
|
||||||
} else {
|
} else {
|
||||||
throw new MessagingException("No valid authentication mechanism found.");
|
throw new MessagingException("No valid authentication mechanism found.");
|
||||||
@ -313,11 +352,20 @@ public class SmtpTransport extends Transport {
|
|||||||
// If the message has attachments and our server has told us about a limit on
|
// If the message has attachments and our server has told us about a limit on
|
||||||
// the size of messages, count the message's size before sending it
|
// the size of messages, count the message's size before sending it
|
||||||
if (mLargestAcceptableMessage > 0 && ((LocalMessage)message).hasAttachments()) {
|
if (mLargestAcceptableMessage > 0 && ((LocalMessage)message).hasAttachments()) {
|
||||||
if (message.calculateSize() > mLargestAcceptableMessage) {
|
if (K9.DEBUG_PROTOCOL_SMTP) {
|
||||||
|
Log.d(K9.LOG_TAG, "calculating message size");
|
||||||
|
}
|
||||||
|
close(); // (prevent timeouts while calculating the size)
|
||||||
|
final long calculatedSize = message.calculateSize();
|
||||||
|
if (calculatedSize > mLargestAcceptableMessage) {
|
||||||
MessagingException me = new MessagingException("Message too large for server");
|
MessagingException me = new MessagingException("Message too large for server");
|
||||||
me.setPermanentFailure(possibleSend);
|
me.setPermanentFailure(possibleSend);
|
||||||
throw me;
|
throw me;
|
||||||
}
|
}
|
||||||
|
open(); // (prevent timeouts while calculating the size)
|
||||||
|
if (K9.DEBUG_PROTOCOL_SMTP) {
|
||||||
|
Log.d(K9.LOG_TAG, "calculating message size DONE size=" + calculatedSize + " max allowed=" + mLargestAcceptableMessage);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Address[] from = message.getFrom();
|
Address[] from = message.getFrom();
|
||||||
@ -344,6 +392,14 @@ public class SmtpTransport extends Transport {
|
|||||||
executeSimpleCommand("\r\n.");
|
executeSimpleCommand("\r\n.");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
MessagingException me = new MessagingException("Unable to send message", e);
|
MessagingException me = new MessagingException("Unable to send message", e);
|
||||||
|
|
||||||
|
// "5xx text" -responses are permanent failures
|
||||||
|
String msg = e.getMessage();
|
||||||
|
if (msg != null && msg.startsWith("5")) {
|
||||||
|
Log.w(K9.LOG_TAG, "handling 5xx SMTP error code as a permanent failure");
|
||||||
|
possibleSend = false;
|
||||||
|
}
|
||||||
|
|
||||||
me.setPermanentFailure(possibleSend);
|
me.setPermanentFailure(possibleSend);
|
||||||
throw me;
|
throw me;
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -6,6 +6,7 @@ package com.fsck.k9.preferences;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.preference.DialogPreference;
|
import android.preference.DialogPreference;
|
||||||
|
import android.text.format.DateFormat;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.TimePicker;
|
import android.widget.TimePicker;
|
||||||
@ -25,12 +26,23 @@ public class TimePickerPreference extends DialogPreference implements
|
|||||||
* The default value for this preference
|
* The default value for this preference
|
||||||
*/
|
*/
|
||||||
private String defaultValue;
|
private String defaultValue;
|
||||||
|
/**
|
||||||
|
* Store the original value, in case the user
|
||||||
|
* chooses to abort the {@link DialogPreference}
|
||||||
|
* after making a change.
|
||||||
|
*/
|
||||||
|
private int originalHour = 0;
|
||||||
|
/**
|
||||||
|
* Store the original value, in case the user
|
||||||
|
* chooses to abort the {@link DialogPreference}
|
||||||
|
* after making a change.
|
||||||
|
*/
|
||||||
|
private int originalMinute = 0;
|
||||||
/**
|
/**
|
||||||
* @param context
|
* @param context
|
||||||
* @param attrs
|
* @param attrs
|
||||||
*/
|
*/
|
||||||
public TimePickerPreference(Context context, AttributeSet attrs) {
|
public TimePickerPreference(final Context context, final AttributeSet attrs) {
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
initialize();
|
initialize();
|
||||||
}
|
}
|
||||||
@ -40,8 +52,8 @@ public class TimePickerPreference extends DialogPreference implements
|
|||||||
* @param attrs
|
* @param attrs
|
||||||
* @param defStyle
|
* @param defStyle
|
||||||
*/
|
*/
|
||||||
public TimePickerPreference(Context context, AttributeSet attrs,
|
public TimePickerPreference(final Context context, final AttributeSet attrs,
|
||||||
int defStyle) {
|
final int defStyle) {
|
||||||
super(context, attrs, defStyle);
|
super(context, attrs, defStyle);
|
||||||
initialize();
|
initialize();
|
||||||
}
|
}
|
||||||
@ -62,39 +74,49 @@ public class TimePickerPreference extends DialogPreference implements
|
|||||||
protected View onCreateDialogView() {
|
protected View onCreateDialogView() {
|
||||||
|
|
||||||
TimePicker tp = new TimePicker(getContext());
|
TimePicker tp = new TimePicker(getContext());
|
||||||
|
tp.setIs24HourView(DateFormat.is24HourFormat(getContext()));
|
||||||
tp.setOnTimeChangedListener(this);
|
tp.setOnTimeChangedListener(this);
|
||||||
|
originalHour = getHour();
|
||||||
int h = getHour();
|
originalMinute = getMinute();
|
||||||
int m = getMinute();
|
if (originalHour >= 0 && originalMinute >= 0) {
|
||||||
if (h >= 0 && m >= 0) {
|
tp.setCurrentHour(originalHour);
|
||||||
tp.setCurrentHour(h);
|
tp.setCurrentMinute(originalMinute);
|
||||||
tp.setCurrentMinute(m);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return tp;
|
return tp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see
|
* @see
|
||||||
* android.widget.TimePicker.OnTimeChangedListener#onTimeChanged(android
|
* android.widget.TimePicker.OnTimeChangedListener#onTimeChanged(android
|
||||||
* .widget.TimePicker, int, int)
|
* .widget.TimePicker, int, int)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onTimeChanged(TimePicker view, int hour, int minute) {
|
public void onTimeChanged(final TimePicker view, final int hour, final int minute) {
|
||||||
|
|
||||||
persistString(String.format("%02d:%02d", hour, minute));
|
persistString(String.format("%02d:%02d", hour, minute));
|
||||||
callChangeListener(String.format("%02d:%02d", hour, minute));
|
callChangeListener(String.format("%02d:%02d", hour, minute));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* (non-Javadoc)
|
* If not a positive result, restore the original value
|
||||||
*
|
* before going to super.onDialogClosed(positiveResult).
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void onDialogClosed(boolean positiveResult) {
|
||||||
|
|
||||||
|
if (!positiveResult) {
|
||||||
|
persistString(String.format("%02d:%02d", originalHour, originalMinute));
|
||||||
|
callChangeListener(String.format("%02d:%02d", originalHour, originalMinute));
|
||||||
|
}
|
||||||
|
super.onDialogClosed(positiveResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
* @see android.preference.Preference#setDefaultValue(java.lang.Object)
|
* @see android.preference.Preference#setDefaultValue(java.lang.Object)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void setDefaultValue(Object defaultValue) {
|
public void setDefaultValue(final Object defaultValue) {
|
||||||
// BUG this method is never called if you use the 'android:defaultValue' attribute in your XML preference file, not sure why it isn't
|
// BUG this method is never called if you use the 'android:defaultValue' attribute in your XML preference file, not sure why it isn't
|
||||||
|
|
||||||
super.setDefaultValue(defaultValue);
|
super.setDefaultValue(defaultValue);
|
||||||
@ -113,10 +135,10 @@ public class TimePickerPreference extends DialogPreference implements
|
|||||||
/**
|
/**
|
||||||
* Get the hour value (in 24 hour time)
|
* Get the hour value (in 24 hour time)
|
||||||
*
|
*
|
||||||
* @return The hour value, will be 0 to 23 (inclusive)
|
* @return The hour value, will be 0 to 23 (inclusive) or -1 if illegal
|
||||||
*/
|
*/
|
||||||
private int getHour() {
|
private int getHour() {
|
||||||
String time = getPersistedString(this.defaultValue);
|
String time = getTime();
|
||||||
if (time == null || !time.matches(VALIDATION_EXPRESSION)) {
|
if (time == null || !time.matches(VALIDATION_EXPRESSION)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -127,10 +149,10 @@ public class TimePickerPreference extends DialogPreference implements
|
|||||||
/**
|
/**
|
||||||
* Get the minute value
|
* Get the minute value
|
||||||
*
|
*
|
||||||
* @return the minute value, will be 0 to 59 (inclusive)
|
* @return the minute value, will be 0 to 59 (inclusive) or -1 if illegal
|
||||||
*/
|
*/
|
||||||
private int getMinute() {
|
private int getMinute() {
|
||||||
String time = getPersistedString(this.defaultValue);
|
String time = getTime();
|
||||||
if (time == null || !time.matches(VALIDATION_EXPRESSION)) {
|
if (time == null || !time.matches(VALIDATION_EXPRESSION)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -138,6 +160,12 @@ public class TimePickerPreference extends DialogPreference implements
|
|||||||
return Integer.valueOf(time.split(":")[1]);
|
return Integer.valueOf(time.split(":")[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the time. It is only legal, if it matches
|
||||||
|
* {@link #VALIDATION_EXPRESSION}.
|
||||||
|
*
|
||||||
|
* @return the time as hh:mm
|
||||||
|
*/
|
||||||
public String getTime() {
|
public String getTime() {
|
||||||
return getPersistedString(this.defaultValue);
|
return getPersistedString(this.defaultValue);
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,14 @@ public class AttachmentProvider extends ContentProvider {
|
|||||||
* We use the cache dir as a temporary directory (since Android doesn't give us one) so
|
* We use the cache dir as a temporary directory (since Android doesn't give us one) so
|
||||||
* on startup we'll clean up any .tmp files from the last run.
|
* on startup we'll clean up any .tmp files from the last run.
|
||||||
*/
|
*/
|
||||||
File[] files = getContext().getCacheDir().listFiles();
|
final File cacheDir = getContext().getCacheDir();
|
||||||
|
if (cacheDir == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
File[] files = cacheDir.listFiles();
|
||||||
|
if (files == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
for (File file : files) {
|
for (File file : files) {
|
||||||
if (file.getName().endsWith(".tmp")) {
|
if (file.getName().endsWith(".tmp")) {
|
||||||
file.delete();
|
file.delete();
|
||||||
|
@ -1,7 +1,16 @@
|
|||||||
package com.fsck.k9.view;
|
package com.fsck.k9.view;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.BitmapFactory;
|
import android.graphics.BitmapFactory;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
@ -9,7 +18,12 @@ import android.os.Environment;
|
|||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.*;
|
import android.widget.Button;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.fsck.k9.Account;
|
import com.fsck.k9.Account;
|
||||||
import com.fsck.k9.K9;
|
import com.fsck.k9.K9;
|
||||||
import com.fsck.k9.R;
|
import com.fsck.k9.R;
|
||||||
@ -23,9 +37,6 @@ import com.fsck.k9.mail.Part;
|
|||||||
import com.fsck.k9.mail.internet.MimeUtility;
|
import com.fsck.k9.mail.internet.MimeUtility;
|
||||||
import com.fsck.k9.mail.store.LocalStore.LocalAttachmentBodyPart;
|
import com.fsck.k9.mail.store.LocalStore.LocalAttachmentBodyPart;
|
||||||
import com.fsck.k9.provider.AttachmentProvider;
|
import com.fsck.k9.provider.AttachmentProvider;
|
||||||
import org.apache.commons.io.IOUtils;
|
|
||||||
|
|
||||||
import java.io.*;
|
|
||||||
|
|
||||||
public class AttachmentView extends FrameLayout {
|
public class AttachmentView extends FrameLayout {
|
||||||
|
|
||||||
@ -42,6 +53,8 @@ public class AttachmentView extends FrameLayout {
|
|||||||
public long size;
|
public long size;
|
||||||
public ImageView iconView;
|
public ImageView iconView;
|
||||||
|
|
||||||
|
private AttachmentFileDownloadCallback callback;
|
||||||
|
|
||||||
public AttachmentView(Context context, AttributeSet attrs, int defStyle) {
|
public AttachmentView(Context context, AttributeSet attrs, int defStyle) {
|
||||||
super(context, attrs, defStyle);
|
super(context, attrs, defStyle);
|
||||||
mContext = context;
|
mContext = context;
|
||||||
@ -56,7 +69,18 @@ public class AttachmentView extends FrameLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public interface AttachmentFileDownloadCallback {
|
||||||
|
/**
|
||||||
|
* this method i called by the attachmentview when
|
||||||
|
* he wants to show a filebrowser
|
||||||
|
* the provider should show the filebrowser activity
|
||||||
|
* and save the reference to the attachment view for later.
|
||||||
|
* in his onActivityResult he can get the saved reference and
|
||||||
|
* call the saveFile method of AttachmentView
|
||||||
|
* @param view
|
||||||
|
*/
|
||||||
|
public void showFileBrowser(AttachmentView caller);
|
||||||
|
}
|
||||||
public boolean populateFromPart(Part inputPart, Message message, Account account, MessagingController controller, MessagingListener listener) {
|
public boolean populateFromPart(Part inputPart, Message message, Account account, MessagingController controller, MessagingListener listener) {
|
||||||
try {
|
try {
|
||||||
part = (LocalAttachmentBodyPart) inputPart;
|
part = (LocalAttachmentBodyPart) inputPart;
|
||||||
@ -113,6 +137,14 @@ public class AttachmentView extends FrameLayout {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
downloadButton.setOnLongClickListener(new OnLongClickListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onLongClick(View v) {
|
||||||
|
callback.showFileBrowser(AttachmentView.this);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
attachmentName.setText(name);
|
attachmentName.setText(name);
|
||||||
attachmentInfo.setText(SizeFormatter.formatSize(mContext, size));
|
attachmentInfo.setText(SizeFormatter.formatSize(mContext, size));
|
||||||
@ -158,9 +190,13 @@ public class AttachmentView extends FrameLayout {
|
|||||||
saveFile();
|
saveFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writeFile() {
|
/**
|
||||||
|
* Writes the attachment onto the given path
|
||||||
|
* @param directory: the base dir where the file should be saved.
|
||||||
|
*/
|
||||||
|
public void writeFile(File directory) {
|
||||||
try {
|
try {
|
||||||
File file = Utility.createUniqueFile(Environment.getExternalStorageDirectory(), name);
|
File file = Utility.createUniqueFile(directory, name);
|
||||||
Uri uri = AttachmentProvider.getAttachmentUri(mAccount, part.getAttachmentId());
|
Uri uri = AttachmentProvider.getAttachmentUri(mAccount, part.getAttachmentId());
|
||||||
InputStream in = mContext.getContentResolver().openInputStream(uri);
|
InputStream in = mContext.getContentResolver().openInputStream(uri);
|
||||||
OutputStream out = new FileOutputStream(file);
|
OutputStream out = new FileOutputStream(file);
|
||||||
@ -168,14 +204,22 @@ public class AttachmentView extends FrameLayout {
|
|||||||
out.flush();
|
out.flush();
|
||||||
out.close();
|
out.close();
|
||||||
in.close();
|
in.close();
|
||||||
attachmentSaved(file.getName());
|
attachmentSaved(file.toString());
|
||||||
new MediaScannerNotifier(mContext, file);
|
new MediaScannerNotifier(mContext, file);
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
attachmentNotSaved();
|
attachmentNotSaved();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* saves the file to the defaultpath setting in the config, or if the config
|
||||||
|
* is not set => to the Environment
|
||||||
|
*/
|
||||||
|
public void writeFile() {
|
||||||
|
writeFile(new File(K9.getAttachmentDefaultPath()));
|
||||||
|
}
|
||||||
|
|
||||||
public void saveFile() {
|
public void saveFile() {
|
||||||
|
//TODO: Can the user save attachments on the internal filesystem or sd card only?
|
||||||
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
|
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
|
||||||
/*
|
/*
|
||||||
* Abort early if there's no place to save the attachment. We don't want to spend
|
* Abort early if there's no place to save the attachment. We don't want to spend
|
||||||
@ -248,4 +292,11 @@ public class AttachmentView extends FrameLayout {
|
|||||||
mContext.getString(R.string.message_view_status_attachment_not_saved),
|
mContext.getString(R.string.message_view_status_attachment_not_saved),
|
||||||
Toast.LENGTH_LONG).show();
|
Toast.LENGTH_LONG).show();
|
||||||
}
|
}
|
||||||
|
public AttachmentFileDownloadCallback getCallback() {
|
||||||
|
return callback;
|
||||||
|
}
|
||||||
|
public void setCallback(AttachmentFileDownloadCallback callback) {
|
||||||
|
this.callback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ public class SingleMessageView extends LinearLayout {
|
|||||||
private Button mDownloadRemainder;
|
private Button mDownloadRemainder;
|
||||||
private LayoutInflater mInflater;
|
private LayoutInflater mInflater;
|
||||||
private Contacts mContacts;
|
private Contacts mContacts;
|
||||||
|
private AttachmentView.AttachmentFileDownloadCallback attachmentCallback;
|
||||||
|
|
||||||
public void initialize(Activity activity) {
|
public void initialize(Activity activity) {
|
||||||
mMessageContentView = (MessageWebView) findViewById(R.id.message_content);
|
mMessageContentView = (MessageWebView) findViewById(R.id.message_content);
|
||||||
@ -265,6 +265,7 @@ public class SingleMessageView extends LinearLayout {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
AttachmentView view = (AttachmentView)mInflater.inflate(R.layout.message_view_attachment, null);
|
AttachmentView view = (AttachmentView)mInflater.inflate(R.layout.message_view_attachment, null);
|
||||||
|
view.setCallback(attachmentCallback);
|
||||||
if (view.populateFromPart(part, message, account, controller, listener)) {
|
if (view.populateFromPart(part, message, account, controller, listener)) {
|
||||||
addAttachment(view);
|
addAttachment(view);
|
||||||
}
|
}
|
||||||
@ -299,4 +300,14 @@ public class SingleMessageView extends LinearLayout {
|
|||||||
mMessageContentView.clearView();
|
mMessageContentView.clearView();
|
||||||
mAttachments.removeAllViews();
|
mAttachments.removeAllViews();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AttachmentView.AttachmentFileDownloadCallback getAttachmentCallback() {
|
||||||
|
return attachmentCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAttachmentCallback(
|
||||||
|
AttachmentView.AttachmentFileDownloadCallback attachmentCallback) {
|
||||||
|
this.attachmentCallback = attachmentCallback;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package com.fsck.k9;
|
package com.fsck.k9.activity;
|
||||||
|
|
||||||
import android.test.ActivityInstrumentationTestCase2;
|
import android.test.ActivityInstrumentationTestCase2;
|
||||||
import com.fsck.k9.activity.Accounts;
|
import com.fsck.k9.activity.Accounts;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user