mirror of
https://github.com/moparisthebest/k-9
synced 2025-02-11 12:40:22 -05:00
Merge commit '4.112' into issue-162-new
This commit is contained in:
commit
47b6eee6df
@ -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="15010"
|
android:versionCode="15011"
|
||||||
android:versionName="4.110" package="com.fsck.k9"
|
android:versionName="4.112" package="com.fsck.k9"
|
||||||
>
|
>
|
||||||
<uses-sdk
|
<uses-sdk
|
||||||
android:minSdkVersion="7"
|
android:minSdkVersion="7"
|
||||||
|
@ -285,6 +285,8 @@ Willkommen zum \"K-9 Mail\"-Setup. K-9 ist eine quelloffene E-Mail-Anwendung fü
|
|||||||
<string name="message_view_status_attachment_not_saved">Anhang konnte nicht auf SD-Karte gespeichert werden.</string>
|
<string name="message_view_status_attachment_not_saved">Anhang konnte nicht auf SD-Karte gespeichert werden.</string>
|
||||||
<string name="message_view_show_pictures_instructions">Wählen Sie \"Bilder anzeigen\", um eingebettete Bilder abzurufen.</string>
|
<string name="message_view_show_pictures_instructions">Wählen Sie \"Bilder anzeigen\", um eingebettete Bilder abzurufen.</string>
|
||||||
<string name="message_view_show_pictures_action">Bilder anzeigen</string>
|
<string name="message_view_show_pictures_action">Bilder anzeigen</string>
|
||||||
|
<string name="message_view_show_attachments_action">Zeige Anhänge</string>
|
||||||
|
<string name="message_view_show_more_attachments_action">Mehr…</string>
|
||||||
<string name="message_view_fetching_attachment_toast">Lade Anhang.</string>
|
<string name="message_view_fetching_attachment_toast">Lade Anhang.</string>
|
||||||
<string name="message_view_no_viewer">Es wurde kein Anzeigeprogramm für <xliff:g id="mimetype">%s</xliff:g> gefunden.</string>
|
<string name="message_view_no_viewer">Es wurde kein Anzeigeprogramm für <xliff:g id="mimetype">%s</xliff:g> gefunden.</string>
|
||||||
|
|
||||||
|
@ -2040,6 +2040,17 @@ public class MimeUtility {
|
|||||||
return DEFAULT_ATTACHMENT_MIME_TYPE;
|
return DEFAULT_ATTACHMENT_MIME_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getExtensionByMimeType(String mimeType) {
|
||||||
|
String lowerCaseMimeType = mimeType.toLowerCase(Locale.US);
|
||||||
|
for (String[] contentTypeMapEntry : MIME_TYPE_BY_EXTENSION_MAP) {
|
||||||
|
if (contentTypeMapEntry[1].equals(lowerCaseMimeType)) {
|
||||||
|
return contentTypeMapEntry[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert some wrong MIME types encountered in the wild to canonical MIME types.
|
* Convert some wrong MIME types encountered in the wild to canonical MIME types.
|
||||||
*
|
*
|
||||||
|
@ -1866,6 +1866,12 @@ Log.v("ASH", mAccount.getDescription() + ":" + name + " is " + (localOnly == 1 ?
|
|||||||
contentDisposition,
|
contentDisposition,
|
||||||
name, // TODO: Should use encoded word defined in RFC 2231.
|
name, // TODO: Should use encoded word defined in RFC 2231.
|
||||||
size));
|
size));
|
||||||
|
} else {
|
||||||
|
bp.setHeader(MimeHeader.HEADER_CONTENT_TYPE, type);
|
||||||
|
bp.setHeader(MimeHeader.HEADER_CONTENT_DISPOSITION,
|
||||||
|
String.format("%s;\n size=%d",
|
||||||
|
contentDisposition,
|
||||||
|
size));
|
||||||
}
|
}
|
||||||
|
|
||||||
bp.setHeader(MimeHeader.HEADER_CONTENT_ID, contentId);
|
bp.setHeader(MimeHeader.HEADER_CONTENT_ID, contentId);
|
||||||
|
@ -18,6 +18,8 @@ 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.view.View.OnClickListener;
|
||||||
|
import android.view.View.OnLongClickListener;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
@ -33,12 +35,14 @@ import com.fsck.k9.helper.MediaScannerNotifier;
|
|||||||
import com.fsck.k9.helper.SizeFormatter;
|
import com.fsck.k9.helper.SizeFormatter;
|
||||||
import com.fsck.k9.helper.Utility;
|
import com.fsck.k9.helper.Utility;
|
||||||
import com.fsck.k9.mail.Message;
|
import com.fsck.k9.mail.Message;
|
||||||
|
import com.fsck.k9.mail.MessagingException;
|
||||||
import com.fsck.k9.mail.Part;
|
import com.fsck.k9.mail.Part;
|
||||||
|
import com.fsck.k9.mail.internet.MimeHeader;
|
||||||
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;
|
||||||
|
|
||||||
public class AttachmentView extends FrameLayout {
|
public class AttachmentView extends FrameLayout implements OnClickListener, OnLongClickListener {
|
||||||
/**
|
/**
|
||||||
* Regular expression that represents characters we won't allow in file names.
|
* Regular expression that represents characters we won't allow in file names.
|
||||||
*
|
*
|
||||||
@ -101,86 +105,125 @@ public class AttachmentView extends FrameLayout {
|
|||||||
*/
|
*/
|
||||||
public void showFileBrowser(AttachmentView caller);
|
public void showFileBrowser(AttachmentView caller);
|
||||||
}
|
}
|
||||||
public boolean populateFromPart(Part inputPart, Message message, Account account, MessagingController controller, MessagingListener listener) {
|
|
||||||
try {
|
|
||||||
part = (LocalAttachmentBodyPart) inputPart;
|
|
||||||
|
|
||||||
contentType = MimeUtility.unfoldAndDecode(part.getContentType());
|
/**
|
||||||
String contentDisposition = MimeUtility.unfoldAndDecode(part.getDisposition());
|
* Populates this view with information about the attachment.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* This method also decides which attachments are displayed when the "show attachments" button
|
||||||
|
* is pressed, and which attachments are only displayed after the "show more attachments"
|
||||||
|
* button was pressed.<br>
|
||||||
|
* Inline attachments with content ID and unnamed attachments fall into the second category.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param inputPart
|
||||||
|
* @param message
|
||||||
|
* @param account
|
||||||
|
* @param controller
|
||||||
|
* @param listener
|
||||||
|
*
|
||||||
|
* @return {@code true} for a regular attachment. {@code false}, otherwise.
|
||||||
|
*
|
||||||
|
* @throws MessagingException
|
||||||
|
* In case of an error
|
||||||
|
*/
|
||||||
|
public boolean populateFromPart(Part inputPart, Message message, Account account,
|
||||||
|
MessagingController controller, MessagingListener listener) throws MessagingException {
|
||||||
|
boolean firstClassAttachment = true;
|
||||||
|
part = (LocalAttachmentBodyPart) inputPart;
|
||||||
|
|
||||||
name = MimeUtility.getHeaderParameter(contentType, "name");
|
contentType = MimeUtility.unfoldAndDecode(part.getContentType());
|
||||||
if (name == null) {
|
String contentDisposition = MimeUtility.unfoldAndDecode(part.getDisposition());
|
||||||
name = MimeUtility.getHeaderParameter(contentDisposition, "filename");
|
|
||||||
}
|
|
||||||
if (name == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
mAccount = account;
|
name = MimeUtility.getHeaderParameter(contentType, "name");
|
||||||
mMessage = message;
|
if (name == null) {
|
||||||
mController = controller;
|
name = MimeUtility.getHeaderParameter(contentDisposition, "filename");
|
||||||
mListener = listener;
|
|
||||||
|
|
||||||
size = Integer.parseInt(MimeUtility.getHeaderParameter(contentDisposition, "size"));
|
|
||||||
contentType = MimeUtility.getMimeTypeForViewing(part.getMimeType(), name);
|
|
||||||
TextView attachmentName = (TextView) findViewById(R.id.attachment_name);
|
|
||||||
TextView attachmentInfo = (TextView) findViewById(R.id.attachment_info);
|
|
||||||
ImageView attachmentIcon = (ImageView) findViewById(R.id.attachment_icon);
|
|
||||||
viewButton = (Button) findViewById(R.id.view);
|
|
||||||
downloadButton = (Button) findViewById(R.id.download);
|
|
||||||
if ((!MimeUtility.mimeTypeMatches(contentType, K9.ACCEPTABLE_ATTACHMENT_VIEW_TYPES))
|
|
||||||
|| (MimeUtility.mimeTypeMatches(contentType, K9.UNACCEPTABLE_ATTACHMENT_VIEW_TYPES))) {
|
|
||||||
viewButton.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
if ((!MimeUtility.mimeTypeMatches(contentType, K9.ACCEPTABLE_ATTACHMENT_DOWNLOAD_TYPES))
|
|
||||||
|| (MimeUtility.mimeTypeMatches(contentType, K9.UNACCEPTABLE_ATTACHMENT_DOWNLOAD_TYPES))) {
|
|
||||||
downloadButton.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
if (size > K9.MAX_ATTACHMENT_DOWNLOAD_SIZE) {
|
|
||||||
viewButton.setVisibility(View.GONE);
|
|
||||||
downloadButton.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
viewButton.setOnClickListener(new OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
onViewButtonClicked();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
downloadButton.setOnClickListener(new OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
onSaveButtonClicked();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
downloadButton.setOnLongClickListener(new OnLongClickListener() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onLongClick(View v) {
|
|
||||||
callback.showFileBrowser(AttachmentView.this);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
attachmentName.setText(name);
|
|
||||||
attachmentInfo.setText(SizeFormatter.formatSize(mContext, size));
|
|
||||||
Bitmap previewIcon = getPreviewIcon();
|
|
||||||
if (previewIcon != null) {
|
|
||||||
attachmentIcon.setImageBitmap(previewIcon);
|
|
||||||
} else {
|
|
||||||
attachmentIcon.setImageResource(R.drawable.attached_image_placeholder);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (Exception e) {
|
if (name == null) {
|
||||||
Log.e(K9.LOG_TAG, "error ", e);
|
firstClassAttachment = false;
|
||||||
|
String extension = MimeUtility.getExtensionByMimeType(contentType);
|
||||||
|
name = "noname" + ((extension != null) ? "." + extension : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
// Inline parts with a content-id are almost certainly components of an HTML message
|
||||||
|
// not attachments. Only show them if the user pressed the button to show more
|
||||||
|
// attachments.
|
||||||
|
if (contentDisposition != null &&
|
||||||
|
MimeUtility.getHeaderParameter(contentDisposition, null).matches("^(?i:inline)")
|
||||||
|
&& part.getHeader(MimeHeader.HEADER_CONTENT_ID) != null) {
|
||||||
|
firstClassAttachment = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mAccount = account;
|
||||||
|
mMessage = message;
|
||||||
|
mController = controller;
|
||||||
|
mListener = listener;
|
||||||
|
|
||||||
|
String sizeParam = MimeUtility.getHeaderParameter(contentDisposition, "size");
|
||||||
|
if (sizeParam != null) {
|
||||||
|
try {
|
||||||
|
size = Integer.parseInt(sizeParam);
|
||||||
|
} catch (NumberFormatException e) { /* ignore */ }
|
||||||
|
}
|
||||||
|
|
||||||
|
contentType = MimeUtility.getMimeTypeForViewing(part.getMimeType(), name);
|
||||||
|
TextView attachmentName = (TextView) findViewById(R.id.attachment_name);
|
||||||
|
TextView attachmentInfo = (TextView) findViewById(R.id.attachment_info);
|
||||||
|
ImageView attachmentIcon = (ImageView) findViewById(R.id.attachment_icon);
|
||||||
|
viewButton = (Button) findViewById(R.id.view);
|
||||||
|
downloadButton = (Button) findViewById(R.id.download);
|
||||||
|
if ((!MimeUtility.mimeTypeMatches(contentType, K9.ACCEPTABLE_ATTACHMENT_VIEW_TYPES))
|
||||||
|
|| (MimeUtility.mimeTypeMatches(contentType, K9.UNACCEPTABLE_ATTACHMENT_VIEW_TYPES))) {
|
||||||
|
viewButton.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
if ((!MimeUtility.mimeTypeMatches(contentType, K9.ACCEPTABLE_ATTACHMENT_DOWNLOAD_TYPES))
|
||||||
|
|| (MimeUtility.mimeTypeMatches(contentType, K9.UNACCEPTABLE_ATTACHMENT_DOWNLOAD_TYPES))) {
|
||||||
|
downloadButton.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
if (size > K9.MAX_ATTACHMENT_DOWNLOAD_SIZE) {
|
||||||
|
viewButton.setVisibility(View.GONE);
|
||||||
|
downloadButton.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
viewButton.setOnClickListener(this);
|
||||||
|
downloadButton.setOnClickListener(this);
|
||||||
|
downloadButton.setOnLongClickListener(this);
|
||||||
|
|
||||||
|
attachmentName.setText(name);
|
||||||
|
attachmentInfo.setText(SizeFormatter.formatSize(mContext, size));
|
||||||
|
Bitmap previewIcon = getPreviewIcon();
|
||||||
|
if (previewIcon != null) {
|
||||||
|
attachmentIcon.setImageBitmap(previewIcon);
|
||||||
|
} else {
|
||||||
|
attachmentIcon.setImageResource(R.drawable.attached_image_placeholder);
|
||||||
|
}
|
||||||
|
|
||||||
|
return firstClassAttachment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
switch (view.getId()) {
|
||||||
|
case R.id.view: {
|
||||||
|
onViewButtonClicked();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case R.id.download: {
|
||||||
|
onSaveButtonClicked();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onLongClick(View view) {
|
||||||
|
if (view.getId() == R.id.download) {
|
||||||
|
callback.showFileBrowser(this);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Bitmap getPreviewIcon() {
|
private Bitmap getPreviewIcon() {
|
||||||
|
@ -398,10 +398,14 @@ public class SingleMessageView extends LinearLayout implements OnClickListener {
|
|||||||
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);
|
view.setCallback(attachmentCallback);
|
||||||
|
|
||||||
if (view.populateFromPart(part, message, account, controller, listener)) {
|
try {
|
||||||
addAttachment(view);
|
if (view.populateFromPart(part, message, account, controller, listener)) {
|
||||||
} else {
|
addAttachment(view);
|
||||||
addHiddenAttachment(view);
|
} else {
|
||||||
|
addHiddenAttachment(view);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(K9.LOG_TAG, "Error adding attachment view", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user