From 258b0039d58fd5d93afab2cbda619d572fda4b84 Mon Sep 17 00:00:00 2001 From: cketti Date: Sat, 14 Jan 2012 06:30:22 +0100 Subject: [PATCH 01/18] IMAP: also get the Message-ID when fetching the message "envelope" This should fix issue 3994 --- src/com/fsck/k9/mail/store/ImapStore.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/com/fsck/k9/mail/store/ImapStore.java b/src/com/fsck/k9/mail/store/ImapStore.java index ec217eab0..bddbf8940 100644 --- a/src/com/fsck/k9/mail/store/ImapStore.java +++ b/src/com/fsck/k9/mail/store/ImapStore.java @@ -1360,8 +1360,8 @@ public class ImapStore extends Store { if (fp.contains(FetchProfile.Item.ENVELOPE)) { fetchFields.add("INTERNALDATE"); fetchFields.add("RFC822.SIZE"); - fetchFields.add("BODY.PEEK[HEADER.FIELDS (date subject from content-type to cc reply-to " - + K9.IDENTITY_HEADER + ")]"); + fetchFields.add("BODY.PEEK[HEADER.FIELDS (date subject from content-type to cc " + + "reply-to message-id " + K9.IDENTITY_HEADER + ")]"); } if (fp.contains(FetchProfile.Item.STRUCTURE)) { fetchFields.add("BODYSTRUCTURE"); From 5c9b1db459e558d41c494a69fc84af7c24f52493 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 17 Jan 2012 17:47:20 -0800 Subject: [PATCH 02/18] fix the push-tags target --- build.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.xml b/build.xml index 5eac31a6e..7b830a0e5 100644 --- a/build.xml +++ b/build.xml @@ -130,7 +130,7 @@ - + From da7f2a2943814d90e36327bcbc808cd6aa1f217a Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 17 Jan 2012 17:50:25 -0800 Subject: [PATCH 03/18] update our upload target for sdk 16 --- build.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.xml b/build.xml index 7b830a0e5..04502dfc8 100644 --- a/build.xml +++ b/build.xml @@ -142,7 +142,7 @@ Uploading to Google Code using Google::Code::Upload - + From 96b0a7b28bf9a124c9d14ff85c613480f4be446b Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Tue, 17 Jan 2012 17:51:43 -0800 Subject: [PATCH 04/18] Bumped manifest to 4.105 --- AndroidManifest.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 142b098c8..0aae9755b 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1,8 +1,8 @@ Date: Wed, 18 Jan 2012 16:17:37 -0200 Subject: [PATCH 05/18] Correction of few translation errors and translating some of the NEW strings. --- res/values-pt-rBR/strings.xml | 76 +++++++++++++++++------------------ 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/res/values-pt-rBR/strings.xml b/res/values-pt-rBR/strings.xml index 4a4813ed3..7af2f917a 100644 --- a/res/values-pt-rBR/strings.xml +++ b/res/values-pt-rBR/strings.xml @@ -40,7 +40,7 @@ \u0020%s/%s \u0020(Nova verif. às @ %s) - + \u0020(Sincronização desabilitada) Próximo @@ -73,7 +73,7 @@ Marcar todas as como lidas Incluir conta Escrever - Peaquisar + Pesquisar Resultado da pesquisa Configurações Abrir @@ -108,9 +108,9 @@ Ver/esconder detalhes Incluir Cc/Bcc Editar assunto - - - + Confirmação de leitura + Confirmação de leitura será requisitada + Confirmação de leitura não será requisitada Incluir anexo Incluir anexo (Imagem) Incluir anexo (Video) @@ -127,7 +127,7 @@ Opções de pasta (Sem assunto) - + Sem data Sem remetente Verificando (Verificar %s%s) @@ -201,7 +201,7 @@ Bem-vindo à configuração do K-9 Mail. K-9 é um cliente de e-mail com código aberto para Android e é originalmente baseado no cliente de e-mail padrão do Android. \n -\n\nK-9\'s recursor aprimorados incluídos: +\n\nK-9\'s recursos aprimorados incluídos: \n * Puxar e-mail usando IMAP IDLE \n * Melhor performance \n * Reclassificação de mensagens @@ -253,19 +253,19 @@ Bem-vindo à configuração do K-9 Mail. K-9 é um cliente de e-mail com código Bcc Assunto Texto da mensagem - - - - - - + ........ Mensagem Original ........ + Assunto: + Enviado: + De: + Para: + Cc: %s escreveu:\n\n Texto citado Você deve incluir ao menos um destinatário. - + Não foi possível encontrar o endereço de e-mail. Alguns anexos não foram incluídos. Eles poderão ser incluídos automaticamente antes desta mensagem ser enviada. Alguns anexos não podem ser encaminhados porque não foram inclusos na mensagem. - + Mensagem citada De: %s <%s> Para: @@ -281,7 +281,7 @@ Bem-vindo à configuração do K-9 Mail. K-9 é um cliente de e-mail com código Anexo salvo no cartão de memória como %s. Impossível salvar anexo no cartão de memória. Selecione \"Mostrar imagens\" para mostrar imagens incorporadas. - Mostar imagens + Mostrar imagens Buscando anexo. Não foi possível encontrar um visualizador para %s. @@ -318,8 +318,8 @@ Bem-vindo à configuração do K-9 Mail. K-9 é um cliente de e-mail com código Visualizar mensagens Itens mais espaçosos da lista com vizualização Linhas de visualização - - + Mostrar nomes correspondentes + Mostrar nomes correspondentes ao invés de seus e-mails. Mostar nomes dos contatos Quando disponível, utilizar nomes dos contatos para destinitário Colorir contatos @@ -330,15 +330,15 @@ Bem-vindo à configuração do K-9 Mail. K-9 é um cliente de e-mail com código Use um tamanho fixo de fonte quando mostrar mensagens com texto simples Retornar para lista após exclusão Retornar para lista de mensagem após exclusão de mensagens - - + Mostrar próxima mensagem após exclusão + Mostrar próxima mensagem por padrão após exclusão de mensagens Confirmar ações Mostrar diálogo sempre quando for disparada uma ação Arquivo Excluir (apenas visualização) Spam - + Marcar todas como lidas Enviar Notificações de bloqueio de tela @@ -420,7 +420,7 @@ Bem-vindo à configuração do K-9 Mail. K-9 é um cliente de e-mail com código Quando verificado Apenas manualmente - + Autodetectar o namespace do IMAP Prefixo do diretório IMAP Pasta de rascunhos @@ -536,8 +536,8 @@ Bem-vindo à configuração do K-9 Mail. K-9 é um cliente de e-mail com código Mostar avisos para mensagens que eu envio Avisos abrem mensagens não lidas Procurar por mensagens não lidas quando o aviso for aberto - - + Mostrar contagem de não lidas + Mostrar o número de mensagens não lidas na barra de notificação. Navegação com botões de scroll Nunca @@ -555,22 +555,22 @@ Bem-vindo à configuração do K-9 Mail. K-9 é um cliente de e-mail com código Enviando e-mails - - + Citar a mensagem original ao responder + Ao responder mensagens, a mensagem original é colocada na sua resposta. Resposta após texto da mensagem Quando respondendo mensagens, o texto original deverá aparecer acima da minha resposta. - - - + Formato da Mensagem + Texto (imagens e formatação serão removidas) + HTML (imagens e formatação serão preservadas) - - + Confirmação de leitura + Sempre solicitar confirmação de leitura - - - + Estilo de citação ao responder + Prefixo (como Gmail, Pine) + Cabeçalho (como Outlook, Yahoo!, Hotmail) Configurações gerais Exibição @@ -894,8 +894,8 @@ Bem-vindo à configuração do K-9 Mail. K-9 é um cliente de e-mail com código Gestos Aceitar controle de gestos - - + Layout compacto + Ajusta o layout para mostrar mais em cada página Tecla de volume para navegação Percorrer itens usando controle de volume @@ -914,8 +914,8 @@ Bem-vindo à configuração do K-9 Mail. K-9 é um cliente de e-mail com código Contador para resultados de pesquisa Desligar visualização rápida - - + Esconder contas especiais + Esconde a Caixa de Entrada Unificada e todas as contas de mensagens %s %s - Favorito From 1a01c10fc505d6a500bb70106bcda9cb047973d1 Mon Sep 17 00:00:00 2001 From: Nick Nikolaou Date: Fri, 20 Jan 2012 17:02:35 +0000 Subject: [PATCH 06/18] Don't save to drafts if drafts folder is -NONE- --- src/com/fsck/k9/activity/MessageCompose.java | 24 +++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/com/fsck/k9/activity/MessageCompose.java b/src/com/fsck/k9/activity/MessageCompose.java index faeca1b2c..fbd96fdb6 100644 --- a/src/com/fsck/k9/activity/MessageCompose.java +++ b/src/com/fsck/k9/activity/MessageCompose.java @@ -1530,7 +1530,9 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc } mDraftNeedsSaving = false; - saveMessage(); + + if (!draftsDisabled()) + saveMessage(); } public void onEncryptionKeySelectionDone() { @@ -2009,6 +2011,10 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc super.onCreateOptionsMenu(menu); getMenuInflater().inflate(R.menu.message_compose_option, menu); + // Disable the 'Save' menu option if folder is set to NONE + if (draftsDisabled()) + menu.findItem(R.id.save).setEnabled(false); + /* * Show the menu items "Add attachment (Image)" and "Add attachment (Video)" * if the work-around for the Gallery bug is enabled (see Issue 1186). @@ -2034,12 +2040,18 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc public void onBackPressed() { if (mEncryptCheckbox.isChecked()) { showDialog(DIALOG_REFUSE_TO_SAVE_DRAFT_MARKED_ENCRYPTED); - } - else if (mDraftNeedsSaving) { - showDialog(DIALOG_SAVE_OR_DISCARD_DRAFT_MESSAGE); - } else { + } else if (!mDraftNeedsSaving || (mDraftNeedsSaving && draftsDisabled())) { + Toast.makeText(MessageCompose.this, getString(R.string.message_discarded_toast), Toast.LENGTH_LONG).show(); super.onBackPressed(); - } + } else + showDialog(DIALOG_SAVE_OR_DISCARD_DRAFT_MESSAGE); + } + + private boolean draftsDisabled() { + if (mAccount.getDraftsFolderName().equals(K9.FOLDER_NONE)) + return true; + else + return false; } @Override From 32a29f131b0baa694d705d0866030354f7414019 Mon Sep 17 00:00:00 2001 From: cketti Date: Fri, 20 Jan 2012 19:50:07 +0100 Subject: [PATCH 07/18] Make sure an IOException is always passed through as MessagingException This is important for the code handling pending actions in MessagingController. If a non-permantent MessagingException is encountered, the pending action is retried later. Fixes issue 3696 --- src/com/fsck/k9/mail/store/ImapStore.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/com/fsck/k9/mail/store/ImapStore.java b/src/com/fsck/k9/mail/store/ImapStore.java index bddbf8940..17441a600 100644 --- a/src/com/fsck/k9/mail/store/ImapStore.java +++ b/src/com/fsck/k9/mail/store/ImapStore.java @@ -989,7 +989,8 @@ public class ImapStore extends Store { return true; } catch (IOException ioe) { throw ioExceptionHandler(mConnection, ioe); - } catch (MessagingException me) { + } catch (ImapException ie) { + // We got a response, but it was not "OK" return false; } } @@ -1017,7 +1018,8 @@ public class ImapStore extends Store { encodeString(encodeFolderName(getPrefixedName())))); mExists = true; return true; - } catch (MessagingException me) { + } catch (ImapException ie) { + // We got a response, but it was not "OK" return false; } catch (IOException ioe) { throw ioExceptionHandler(connection, ioe); @@ -1047,7 +1049,8 @@ public class ImapStore extends Store { connection.executeSimpleCommand(String.format("CREATE %s", encodeString(encodeFolderName(getPrefixedName())))); return true; - } catch (MessagingException me) { + } catch (ImapException ie) { + // We got a response, but it was not "OK" return false; } catch (IOException ioe) { throw ioExceptionHandler(mConnection, ioe); From 773d1e30f118c3284d229bc0c78c5982edd35fa9 Mon Sep 17 00:00:00 2001 From: Nick Nikolaou Date: Fri, 20 Jan 2012 19:10:11 +0000 Subject: [PATCH 08/18] Simplied code and added curly brackets to if/else --- src/com/fsck/k9/activity/MessageCompose.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/com/fsck/k9/activity/MessageCompose.java b/src/com/fsck/k9/activity/MessageCompose.java index fbd96fdb6..2782e41d2 100644 --- a/src/com/fsck/k9/activity/MessageCompose.java +++ b/src/com/fsck/k9/activity/MessageCompose.java @@ -1531,8 +1531,9 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc mDraftNeedsSaving = false; - if (!draftsDisabled()) + if (!draftsDisabled()) { saveMessage(); + } } public void onEncryptionKeySelectionDone() { @@ -2012,8 +2013,9 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc getMenuInflater().inflate(R.menu.message_compose_option, menu); // Disable the 'Save' menu option if folder is set to NONE - if (draftsDisabled()) + if (draftsDisabled()) { menu.findItem(R.id.save).setEnabled(false); + } /* * Show the menu items "Add attachment (Image)" and "Add attachment (Video)" @@ -2040,7 +2042,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc public void onBackPressed() { if (mEncryptCheckbox.isChecked()) { showDialog(DIALOG_REFUSE_TO_SAVE_DRAFT_MARKED_ENCRYPTED); - } else if (!mDraftNeedsSaving || (mDraftNeedsSaving && draftsDisabled())) { + } else if (!mDraftNeedsSaving || draftsDisabled()) { Toast.makeText(MessageCompose.this, getString(R.string.message_discarded_toast), Toast.LENGTH_LONG).show(); super.onBackPressed(); } else From 457e65010e03a309ae2709d8a77e0d2d42882700 Mon Sep 17 00:00:00 2001 From: wcb Date: Fri, 20 Jan 2012 11:55:04 -0800 Subject: [PATCH 09/18] Issue 3139: notifications of new messages removed when unified inbox is selected --- src/com/fsck/k9/activity/MessageList.java | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/com/fsck/k9/activity/MessageList.java b/src/com/fsck/k9/activity/MessageList.java index 7627a9b34..82b6785e6 100644 --- a/src/com/fsck/k9/activity/MessageList.java +++ b/src/com/fsck/k9/activity/MessageList.java @@ -800,9 +800,20 @@ public class MessageList sortDateAscending = mController.isSortAscending(SORT_TYPE.SORT_DATE); mController.addListener(mAdapter.mListener); + + Account[] accountsWithNotification = null; + if (mAccount != null) { - mController.notifyAccountCancel(this, mAccount); - MessagingController.getInstance(getApplication()).notifyAccountCancel(this, mAccount); + accountsWithNotification = new Account[1]; + accountsWithNotification[0] = mAccount; + } else { + Preferences preferences = Preferences.getPreferences(this); + accountsWithNotification = preferences.getAccounts(); + } + + for (Account accountWithNotification : accountsWithNotification) { + mController.notifyAccountCancel(this, accountWithNotification); + MessagingController.getInstance(getApplication()).notifyAccountCancel(this, accountWithNotification); } if (mAdapter.messages.isEmpty()) { From 2c5f640b9e3cf898a41c415aab5c9b8abd0a8997 Mon Sep 17 00:00:00 2001 From: cketti Date: Fri, 20 Jan 2012 23:15:11 +0100 Subject: [PATCH 10/18] Minor cleanup --- src/com/fsck/k9/activity/MessageCompose.java | 23 ++++++++------------ 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/src/com/fsck/k9/activity/MessageCompose.java b/src/com/fsck/k9/activity/MessageCompose.java index 2782e41d2..fc870d9ba 100644 --- a/src/com/fsck/k9/activity/MessageCompose.java +++ b/src/com/fsck/k9/activity/MessageCompose.java @@ -1525,15 +1525,12 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc private void saveIfNeeded() { if (!mDraftNeedsSaving || mPreventDraftSaving || mPgpData.hasEncryptionKeys() || - mEncryptCheckbox.isChecked()) { + mEncryptCheckbox.isChecked() || isDraftsFolderDisabled()) { return; } mDraftNeedsSaving = false; - - if (!draftsDisabled()) { - saveMessage(); - } + saveMessage(); } public void onEncryptionKeySelectionDone() { @@ -2012,8 +2009,8 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc super.onCreateOptionsMenu(menu); getMenuInflater().inflate(R.menu.message_compose_option, menu); - // Disable the 'Save' menu option if folder is set to NONE - if (draftsDisabled()) { + // Disable the 'Save' menu option if Drafts folder is set to -NONE- + if (isDraftsFolderDisabled()) { menu.findItem(R.id.save).setEnabled(false); } @@ -2042,18 +2039,16 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc public void onBackPressed() { if (mEncryptCheckbox.isChecked()) { showDialog(DIALOG_REFUSE_TO_SAVE_DRAFT_MARKED_ENCRYPTED); - } else if (!mDraftNeedsSaving || draftsDisabled()) { + } else if (!mDraftNeedsSaving || isDraftsFolderDisabled()) { Toast.makeText(MessageCompose.this, getString(R.string.message_discarded_toast), Toast.LENGTH_LONG).show(); super.onBackPressed(); - } else + } else { showDialog(DIALOG_SAVE_OR_DISCARD_DRAFT_MESSAGE); + } } - private boolean draftsDisabled() { - if (mAccount.getDraftsFolderName().equals(K9.FOLDER_NONE)) - return true; - else - return false; + private boolean isDraftsFolderDisabled() { + return mAccount.getDraftsFolderName().equals(K9.FOLDER_NONE); } @Override From a8f91b0f70e9ac9565695e9d6dcd929587ddffb4 Mon Sep 17 00:00:00 2001 From: cketti Date: Fri, 20 Jan 2012 23:32:12 +0100 Subject: [PATCH 11/18] Minor code cleanup --- src/com/fsck/k9/activity/MessageList.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/com/fsck/k9/activity/MessageList.java b/src/com/fsck/k9/activity/MessageList.java index 82b6785e6..8d60a6cc0 100644 --- a/src/com/fsck/k9/activity/MessageList.java +++ b/src/com/fsck/k9/activity/MessageList.java @@ -801,11 +801,9 @@ public class MessageList mController.addListener(mAdapter.mListener); - Account[] accountsWithNotification = null; - + Account[] accountsWithNotification; if (mAccount != null) { - accountsWithNotification = new Account[1]; - accountsWithNotification[0] = mAccount; + accountsWithNotification = new Account[] { mAccount }; } else { Preferences preferences = Preferences.getPreferences(this); accountsWithNotification = preferences.getAccounts(); From 0625e13380dad4214d03c90d5a06e405318f7379 Mon Sep 17 00:00:00 2001 From: cketti Date: Fri, 20 Jan 2012 23:32:55 +0100 Subject: [PATCH 12/18] Canceling notifications once should be enough --- src/com/fsck/k9/activity/MessageList.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/com/fsck/k9/activity/MessageList.java b/src/com/fsck/k9/activity/MessageList.java index 8d60a6cc0..1d2c8f59e 100644 --- a/src/com/fsck/k9/activity/MessageList.java +++ b/src/com/fsck/k9/activity/MessageList.java @@ -811,7 +811,6 @@ public class MessageList for (Account accountWithNotification : accountsWithNotification) { mController.notifyAccountCancel(this, accountWithNotification); - MessagingController.getInstance(getApplication()).notifyAccountCancel(this, accountWithNotification); } if (mAdapter.messages.isEmpty()) { From be2aac52a852dfc8a942d0e08895193ecf5273df Mon Sep 17 00:00:00 2001 From: cketti Date: Sat, 21 Jan 2012 03:10:40 +0100 Subject: [PATCH 13/18] Reload accounts after writing imported account settings to storage This makes sure that when the next account is imported it will see the account just imported. That's necessary e.g. when going though all accounts to find the next free account number, or when avoiding account name conflicts. --- .../fsck/k9/preferences/SettingsImporter.java | 36 +++++++++++-------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/src/com/fsck/k9/preferences/SettingsImporter.java b/src/com/fsck/k9/preferences/SettingsImporter.java index aa307ba66..a20059f47 100644 --- a/src/com/fsck/k9/preferences/SettingsImporter.java +++ b/src/com/fsck/k9/preferences/SettingsImporter.java @@ -215,7 +215,6 @@ public class SettingsImporter { if (accountUuids != null && accountUuids.size() > 0) { if (imported.accounts != null) { - List newUuids = new ArrayList(); for (String accountUuid : accountUuids) { if (imported.accounts.containsKey(accountUuid)) { ImportedAccount account = imported.accounts.get(accountUuid); @@ -225,16 +224,33 @@ public class SettingsImporter { AccountDescriptionPair importResult = importAccount(context, editor, imported.contentVersion, account, overwrite); - String newUuid = importResult.imported.uuid; - if (!importResult.overwritten) { - newUuids.add(newUuid); - } if (editor.commit()) { if (K9.DEBUG) { Log.v(K9.LOG_TAG, "Committed settings for account \"" + importResult.imported.name + "\" to the settings database."); } + + // Add UUID of the account we just imported to the list of + // account UUIDs + if (!importResult.overwritten) { + editor = storage.edit(); + + String newUuid = importResult.imported.uuid; + String oldAccountUuids = storage.getString("accountUuids", ""); + String newAccountUuids = (oldAccountUuids.length() > 0) ? + oldAccountUuids + "," + newUuid : newUuid; + + putString(editor, "accountUuids", newAccountUuids); + + if (!editor.commit()) { + throw new SettingsImportExportException("Failed to set account UUID list"); + } + } + + // Reload accounts + preferences.loadAccounts(); + importedAccounts.add(importResult); } else { if (K9.DEBUG) { @@ -263,16 +279,6 @@ public class SettingsImporter { SharedPreferences.Editor editor = storage.edit(); - if (newUuids.size() > 0) { - String oldAccountUuids = storage.getString("accountUuids", ""); - String appendUuids = Utility.combine(newUuids.toArray(new String[0]), ','); - String prefix = ""; - if (oldAccountUuids.length() > 0) { - prefix = oldAccountUuids + ","; - } - putString(editor, "accountUuids", prefix + appendUuids); - } - String defaultAccountUuid = storage.getString("defaultAccountUuid", null); if (defaultAccountUuid == null) { putString(editor, "defaultAccountUuid", accountUuids.get(0)); From 16003abcc1a0539345878abf0986f1b165367206 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Fri, 20 Jan 2012 23:42:30 -0500 Subject: [PATCH 14/18] Bumped manifest to 4.106 --- AndroidManifest.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 0aae9755b..00263f209 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1,8 +1,8 @@ Date: Sun, 22 Jan 2012 05:04:15 +0100 Subject: [PATCH 15/18] Modified LocalStore to use UPDATE when replacing existing messages This way we can later use the database ID to keep track of drafts. --- src/com/fsck/k9/mail/store/LocalStore.java | 39 +++++++++++++--------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/src/com/fsck/k9/mail/store/LocalStore.java b/src/com/fsck/k9/mail/store/LocalStore.java index fbcfafa21..21d2865fb 100644 --- a/src/com/fsck/k9/mail/store/LocalStore.java +++ b/src/com/fsck/k9/mail/store/LocalStore.java @@ -2019,9 +2019,9 @@ public class LocalStore extends Store implements Serializable { /** * The method differs slightly from the contract; If an incoming message already has a uid - * assigned and it matches the uid of an existing message then this message will replace the - * old message. It is implemented as a delete/insert. This functionality is used in saving - * of drafts and re-synchronization of updated server messages. + * assigned and it matches the uid of an existing message then this message will replace + * the old message. This functionality is used in saving of drafts and re-synchronization + * of updated server messages. * * NOTE that although this method is located in the LocalStore class, it is not guaranteed * that the messages supplied as parameters are actually {@link LocalMessage} instances (in @@ -2042,6 +2042,7 @@ public class LocalStore extends Store implements Serializable { throw new Error("LocalStore can only store Messages that extend MimeMessage"); } + long oldMessageId = -1; String uid = message.getUid(); if (uid == null || copy) { uid = K9.LOCAL_UID_PREFIX + UUID.randomUUID().toString(); @@ -2049,20 +2050,20 @@ public class LocalStore extends Store implements Serializable { message.setUid(uid); } } else { - Message oldMessage = getMessage(uid); - if (oldMessage != null && !oldMessage.isSet(Flag.SEEN)) { - setUnreadMessageCount(getUnreadMessageCount() - 1); + LocalMessage oldMessage = (LocalMessage) getMessage(uid); + + if (oldMessage != null) { + oldMessageId = oldMessage.getId(); + + if (!oldMessage.isSet(Flag.SEEN)) { + setUnreadMessageCount(getUnreadMessageCount() - 1); + } + if (oldMessage.isSet(Flag.FLAGGED)) { + setFlaggedMessageCount(getFlaggedMessageCount() - 1); + } } - if (oldMessage != null && oldMessage.isSet(Flag.FLAGGED)) { - setFlaggedMessageCount(getFlaggedMessageCount() - 1); - } - /* - * The message may already exist in this Folder, so delete it first. - */ + deleteAttachments(message.getUid()); - db.execSQL("DELETE FROM messages WHERE folder_id = ? AND uid = ?", - new Object[] - { mFolderId, message.getUid() }); } ArrayList viewables = new ArrayList(); @@ -2132,7 +2133,13 @@ public class LocalStore extends Store implements Serializable { cv.put("message_id", messageId); } long messageUid; - messageUid = db.insert("messages", "uid", cv); + + if (oldMessageId == -1) { + messageUid = db.insert("messages", "uid", cv); + } else { + db.update("messages", cv, "id = ?", new String[] { Long.toString(oldMessageId) }); + messageUid = oldMessageId; + } for (Part attachment : attachments) { saveAttachment(messageUid, attachment, copy); } From bddacf6b646606d817cd0b6a07e03f01f30270e4 Mon Sep 17 00:00:00 2001 From: cketti Date: Sun, 22 Jan 2012 05:14:58 +0100 Subject: [PATCH 16/18] Use database ID to keep track of the current draft By using the database ID we avoid having to deal with the problem of changing UIDs. First the message has a local UID, then, when the upload to the server is completed, it gets a remote UID. --- src/com/fsck/k9/activity/MessageCompose.java | 58 ++++++++----------- .../k9/controller/MessagingController.java | 24 +++++++- src/com/fsck/k9/mail/store/LocalStore.java | 33 +++++++++++ 3 files changed, 80 insertions(+), 35 deletions(-) diff --git a/src/com/fsck/k9/activity/MessageCompose.java b/src/com/fsck/k9/activity/MessageCompose.java index fc870d9ba..48173b0a7 100644 --- a/src/com/fsck/k9/activity/MessageCompose.java +++ b/src/com/fsck/k9/activity/MessageCompose.java @@ -84,6 +84,8 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc private static final int DIALOG_REFUSE_TO_SAVE_DRAFT_MARKED_ENCRYPTED = 2; private static final int DIALOG_CONTINUE_WITHOUT_PUBLIC_KEY = 3; + private static final long INVALID_DRAFT_ID = MessagingController.INVALID_MESSAGE_ID; + private static final String ACTION_COMPOSE = "com.fsck.k9.intent.action.COMPOSE"; private static final String ACTION_REPLY = "com.fsck.k9.intent.action.REPLY"; private static final String ACTION_REPLY_ALL = "com.fsck.k9.intent.action.REPLY_ALL"; @@ -104,8 +106,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc "com.fsck.k9.activity.MessageCompose.QuotedTextShown"; private static final String STATE_KEY_SOURCE_MESSAGE_PROCED = "com.fsck.k9.activity.MessageCompose.stateKeySourceMessageProced"; - private static final String STATE_KEY_DRAFT_UID = - "com.fsck.k9.activity.MessageCompose.draftUid"; + private static final String STATE_KEY_DRAFT_ID = "com.fsck.k9.activity.MessageCompose.draftId"; private static final String STATE_KEY_HTML_QUOTE = "com.fsck.k9.activity.MessageCompose.HTMLQuote"; private static final String STATE_IDENTITY_CHANGED = "com.fsck.k9.activity.MessageCompose.identityChanged"; @@ -228,10 +229,11 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc private boolean mIgnoreOnStop = false; /** - * The draft uid of this message. This is used when saving drafts so that the same draft is - * overwritten instead of being created anew. This property is null until the first save. + * The database ID of this message's draft. This is used when saving drafts so the message in + * the database is updated instead of being created anew. This property is INVALID_DRAFT_ID + * until the first save. */ - private String mDraftUid; + private long mDraftId = INVALID_DRAFT_ID; private Handler mHandler = new Handler() { @Override @@ -893,7 +895,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc outState.putBoolean(STATE_KEY_BCC_SHOWN, mBccWrapper.getVisibility() == View.VISIBLE); outState.putSerializable(STATE_KEY_QUOTED_TEXT_MODE, mQuotedTextMode); outState.putBoolean(STATE_KEY_SOURCE_MESSAGE_PROCED, mSourceMessageProcessed); - outState.putString(STATE_KEY_DRAFT_UID, mDraftUid); + outState.putLong(STATE_KEY_DRAFT_ID, mDraftId); outState.putSerializable(STATE_IDENTITY, mIdentity); outState.putBoolean(STATE_IDENTITY_CHANGED, mIdentityChanged); outState.putSerializable(STATE_PGP_DATA, mPgpData); @@ -930,7 +932,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc mQuotedHTML.loadDataWithBaseURL("http://", mQuotedHtmlContent.getQuotedContent(), "text/html", "utf-8", null); } } - mDraftUid = savedInstanceState.getString(STATE_KEY_DRAFT_UID); + mDraftId = savedInstanceState.getLong(STATE_KEY_DRAFT_ID); mIdentity = (Identity)savedInstanceState.getSerializable(STATE_IDENTITY); mIdentityChanged = savedInstanceState.getBoolean(STATE_IDENTITY_CHANGED); mPgpData = (PgpData) savedInstanceState.getSerializable(STATE_PGP_DATA); @@ -1609,9 +1611,9 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc } private void onDiscard() { - if (mDraftUid != null) { - MessagingController.getInstance(getApplication()).deleteDraft(mAccount, mDraftUid); - mDraftUid = null; + if (mDraftId != INVALID_DRAFT_ID) { + MessagingController.getInstance(getApplication()).deleteDraft(mAccount, mDraftId); + mDraftId = INVALID_DRAFT_ID; } mHandler.sendEmptyMessage(MSG_DISCARDED_DRAFT); mDraftNeedsSaving = false; @@ -1817,12 +1819,12 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc } // test whether there is something to save - if (mDraftNeedsSaving || (mDraftUid != null)) { - final String previousDraftUid = mDraftUid; + if (mDraftNeedsSaving || (mDraftId != INVALID_DRAFT_ID)) { + final long previousDraftId = mDraftId; final Account previousAccount = mAccount; // make current message appear as new - mDraftUid = null; + mDraftId = INVALID_DRAFT_ID; // actual account switch mAccount = account; @@ -1832,13 +1834,13 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc } saveMessage(); - if (previousDraftUid != null) { + if (previousDraftId != INVALID_DRAFT_ID) { if (K9.DEBUG) { Log.v(K9.LOG_TAG, "Account switch, deleting draft from previous account: " - + previousDraftUid); + + previousDraftId); } MessagingController.getInstance(getApplication()).deleteDraft(previousAccount, - previousDraftUid); + previousDraftId); } } else { mAccount = account; @@ -2264,7 +2266,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc } else if (ACTION_EDIT_DRAFT.equals(action)) { String showQuotedTextMode = "NONE"; - mDraftUid = message.getUid(); + mDraftId = MessagingController.getInstance(getApplication()).getId(message); mSubjectView.setText(message.getSubject()); addAddresses(mToView, message.getRecipients(RecipientType.TO)); if (message.getRecipients(RecipientType.CC).length > 0) { @@ -2854,14 +2856,6 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc @Override public void messageUidChanged(Account account, String folder, String oldUid, String newUid) { - //TODO: is this really necessary here? mDraftUid is update after the call to MessagingController.saveDraft() - // Track UID changes of the draft message - if (account.equals(mAccount) && - folder.equals(mAccount.getDraftsFolderName()) && - oldUid.equals(mDraftUid)) { - mDraftUid = newUid; - } - // Track UID changes of the source message if (mMessageReference != null) { final Account sourceAccount = Preferences.getPreferences(MessageCompose.this).getAccount(mMessageReference.accountUuid); @@ -2957,9 +2951,9 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc } MessagingController.getInstance(getApplication()).sendMessage(mAccount, message, null); - if (mDraftUid != null) { - MessagingController.getInstance(getApplication()).deleteDraft(mAccount, mDraftUid); - mDraftUid = null; + if (mDraftId != INVALID_DRAFT_ID) { + MessagingController.getInstance(getApplication()).deleteDraft(mAccount, mDraftId); + mDraftId = INVALID_DRAFT_ID; } return null; @@ -2983,9 +2977,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc /* * Save a draft */ - if (mDraftUid != null) { - message.setUid(mDraftUid); - } else if (ACTION_EDIT_DRAFT.equals(getIntent().getAction())) { + if (ACTION_EDIT_DRAFT.equals(getIntent().getAction())) { /* * We're saving a previously saved draft, so update the new message's uid * to the old message's uid. @@ -2996,8 +2988,8 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc } final MessagingController messagingController = MessagingController.getInstance(getApplication()); - Message draftMessage = messagingController.saveDraft(mAccount, message); - mDraftUid = draftMessage.getUid(); + Message draftMessage = messagingController.saveDraft(mAccount, message, mDraftId); + mDraftId = messagingController.getId(draftMessage); mHandler.sendEmptyMessage(MSG_SAVED_DRAFT); return null; diff --git a/src/com/fsck/k9/controller/MessagingController.java b/src/com/fsck/k9/controller/MessagingController.java index 2eedc119e..2aaa48ae1 100644 --- a/src/com/fsck/k9/controller/MessagingController.java +++ b/src/com/fsck/k9/controller/MessagingController.java @@ -79,6 +79,7 @@ import com.fsck.k9.mail.store.LocalStore.PendingCommand; * removed from the queue once the activity is no longer active. */ public class MessagingController implements Runnable { + public static final long INVALID_MESSAGE_ID = -1; /** * Immutable empty {@link String} array @@ -3303,12 +3304,13 @@ public class MessagingController implements Runnable { }); } - public void deleteDraft(final Account account, String uid) { + public void deleteDraft(final Account account, long id) { LocalFolder localFolder = null; try { LocalStore localStore = account.getLocalStore(); localFolder = localStore.getFolder(account.getDraftsFolderName()); localFolder.open(OpenMode.READ_WRITE); + String uid = localFolder.getMessageUidById(id); Message message = localFolder.getMessage(uid); if (message != null) { deleteMessages(new Message[] { message }, null); @@ -4059,12 +4061,18 @@ public class MessagingController implements Runnable { * @param message Message to save. * @return Message representing the entry in the local store. */ - public Message saveDraft(final Account account, final Message message) { + public Message saveDraft(final Account account, final Message message, long existingDraftId) { Message localMessage = null; try { LocalStore localStore = account.getLocalStore(); LocalFolder localFolder = localStore.getFolder(account.getDraftsFolderName()); localFolder.open(OpenMode.READ_WRITE); + + if (existingDraftId != INVALID_MESSAGE_ID) { + String uid = localFolder.getMessageUidById(existingDraftId); + message.setUid(uid); + } + // Save the message to the store. localFolder.appendMessages(new Message[] { message @@ -4089,6 +4097,18 @@ public class MessagingController implements Runnable { return localMessage; } + public long getId(Message message) { + long id; + if (message instanceof LocalMessage) { + id = ((LocalMessage) message).getId(); + } else { + Log.w(K9.LOG_TAG, "MessagingController.getId() called without a LocalMessage"); + id = INVALID_MESSAGE_ID; + } + + return id; + } + public boolean modeMismatch(Account.FolderMode aMode, Folder.FolderClass fMode) { if (aMode == Account.FolderMode.NONE || (aMode == Account.FolderMode.FIRST_CLASS && diff --git a/src/com/fsck/k9/mail/store/LocalStore.java b/src/com/fsck/k9/mail/store/LocalStore.java index 21d2865fb..abfa3ed1d 100644 --- a/src/com/fsck/k9/mail/store/LocalStore.java +++ b/src/com/fsck/k9/mail/store/LocalStore.java @@ -1798,6 +1798,39 @@ public class LocalStore extends Store implements Serializable { }); } + public String getMessageUidById(final long id) throws MessagingException { + try { + return database.execute(false, new DbCallback() { + @Override + public String doDbWork(final SQLiteDatabase db) throws WrappedException, UnavailableStorageException { + try { + open(OpenMode.READ_WRITE); + Cursor cursor = null; + + try { + cursor = db.rawQuery( + "SELECT uid FROM messages " + + "WHERE id = ? AND folder_id = ?", + new String[] { + Long.toString(id), Long.toString(mFolderId) + }); + if (!cursor.moveToNext()) { + return null; + } + return cursor.getString(0); + } finally { + Utility.closeQuietly(cursor); + } + } catch (MessagingException e) { + throw new WrappedException(e); + } + } + }); + } catch (WrappedException e) { + throw(MessagingException) e.getCause(); + } + } + @Override public Message getMessage(final String uid) throws MessagingException { try { From 45faad041e878ada27bea14d385cbe836014d6e8 Mon Sep 17 00:00:00 2001 From: cketti Date: Sun, 22 Jan 2012 05:32:52 +0100 Subject: [PATCH 17/18] Don't finish() MessageCompose in onPause() --- src/com/fsck/k9/activity/MessageCompose.java | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/com/fsck/k9/activity/MessageCompose.java b/src/com/fsck/k9/activity/MessageCompose.java index 48173b0a7..f0d2a68c2 100644 --- a/src/com/fsck/k9/activity/MessageCompose.java +++ b/src/com/fsck/k9/activity/MessageCompose.java @@ -864,12 +864,8 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc MessagingController.getInstance(getApplication()).removeListener(mListener); // Save email as draft when activity is changed (go to home screen, call received) or screen locked // don't do this if only changing orientations - if ((getChangingConfigurations() & ActivityInfo.CONFIG_ORIENTATION) == 0) { - // don't do this if selecting signature or if "Encrypt" is checked or if adding an attachment - if (!mPreventDraftSaving && !mEncryptCheckbox.isChecked() && !mIgnoreOnStop){ - saveIfNeeded(); - finish(); - } + if (!mIgnoreOnStop && (getChangingConfigurations() & ActivityInfo.CONFIG_ORIENTATION) == 0) { + saveIfNeeded(); } } From 4bbc5de1ba39007943361e7c4062ca1bb862ca22 Mon Sep 17 00:00:00 2001 From: cketti Date: Sun, 22 Jan 2012 06:25:06 +0100 Subject: [PATCH 18/18] Code cleanup / fixed lots of warnings --- src/com/fsck/k9/activity/MessageCompose.java | 173 ++++++++++++------- 1 file changed, 107 insertions(+), 66 deletions(-) diff --git a/src/com/fsck/k9/activity/MessageCompose.java b/src/com/fsck/k9/activity/MessageCompose.java index f0d2a68c2..6da95c263 100644 --- a/src/com/fsck/k9/activity/MessageCompose.java +++ b/src/com/fsck/k9/activity/MessageCompose.java @@ -140,7 +140,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc * Currently: * - "Aw:" (german: abbreviation for "Antwort") */ - private static final Pattern prefix = Pattern.compile("^AW[:\\s]\\s*", Pattern.CASE_INSENSITIVE); + private static final Pattern PREFIX = Pattern.compile("^AW[:\\s]\\s*", Pattern.CASE_INSENSITIVE); /** * The account used for message composition. @@ -226,7 +226,10 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc private boolean mDraftNeedsSaving = false; private boolean mPreventDraftSaving = false; - private boolean mIgnoreOnStop = false; + /** + * If this is {@code true} we don't save the message as a draft in {@link #onPause()}. + */ + private boolean mIgnoreOnPause = false; /** * The database ID of this message's draft. This is used when saving drafts so the message in @@ -295,11 +298,12 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc * @param account */ public static void actionCompose(Context context, Account account) { - if (account == null) { - account = Preferences.getPreferences(context).getDefaultAccount(); - } + String accountUuid = (account == null) ? + Preferences.getPreferences(context).getDefaultAccount().getUuid() : + account.getUuid(); + Intent i = new Intent(context, MessageCompose.class); - i.putExtra(EXTRA_ACCOUNT, account.getUuid()); + i.putExtra(EXTRA_ACCOUNT, accountUuid); i.setAction(ACTION_COMPOSE); context.startActivity(i); } @@ -443,26 +447,34 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc }); TextWatcher watcher = new TextWatcher() { - public void beforeTextChanged(CharSequence s, int start, - int before, int after) { } + @Override + public void beforeTextChanged(CharSequence s, int start, int before, int after) { + /* do nothing */ + } - public void onTextChanged(CharSequence s, int start, - int before, int count) { + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { mDraftNeedsSaving = true; } - public void afterTextChanged(android.text.Editable s) { } + @Override + public void afterTextChanged(android.text.Editable s) { /* do nothing */ } }; // For watching changes to the To:, Cc:, and Bcc: fields for auto-encryption on a matching // address. TextWatcher recipientWatcher = new TextWatcher() { - public void beforeTextChanged(CharSequence s, int start, int before, int after) { } + @Override + public void beforeTextChanged(CharSequence s, int start, int before, int after) { + /* do nothing */ + } + @Override public void onTextChanged(CharSequence s, int start, int before, int count) { mDraftNeedsSaving = true; } + @Override public void afterTextChanged(android.text.Editable s) { final CryptoProvider crypto = mAccount.getCryptoProvider(); if (mAutoEncrypt && crypto.isAvailable(getApplicationContext())) { @@ -479,16 +491,19 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc }; TextWatcher sigwatcher = new TextWatcher() { - public void beforeTextChanged(CharSequence s, int start, - int before, int after) { } + @Override + public void beforeTextChanged(CharSequence s, int start, int before, int after) { + /* do nothing */ + } - public void onTextChanged(CharSequence s, int start, - int before, int count) { + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { mDraftNeedsSaving = true; mSignatureChanged = true; } - public void afterTextChanged(android.text.Editable s) { } + @Override + public void afterTextChanged(android.text.Editable s) { /* do nothing */ } }; mToView.addTextChangedListener(recipientWatcher); @@ -854,7 +869,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc @Override public void onResume() { super.onResume(); - mIgnoreOnStop = false; + mIgnoreOnPause = false; MessagingController.getInstance(getApplication()).addListener(mListener); } @@ -864,7 +879,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc MessagingController.getInstance(getApplication()).removeListener(mListener); // Save email as draft when activity is changed (go to home screen, call received) or screen locked // don't do this if only changing orientations - if (!mIgnoreOnStop && (getChangingConfigurations() & ActivityInfo.CONFIG_ORIENTATION) == 0) { + if (!mIgnoreOnPause && (getChangingConfigurations() & ActivityInfo.CONFIG_ORIENTATION) == 0) { saveIfNeeded(); } } @@ -951,6 +966,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc } } + @Override public void onFocusChange(View view, boolean focused) { if (!focused) { updateTitle(); @@ -1318,9 +1334,13 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc } /** - * Get the list of IdentityFields that should be integer values. These values are sanity - * checked for integer-ness during decoding. - * @return + * Get the list of IdentityFields that should be integer values. + * + *

+ * These values are sanity checked for integer-ness during decoding. + *

+ * + * @return The list of integer {@link IdentityField}s. */ public static IdentityField[] getIntegerFields() { return new IdentityField[] { LENGTH, OFFSET, FOOTER_OFFSET, PLAIN_LENGTH, PLAIN_OFFSET }; @@ -1331,19 +1351,6 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc // use that to determine which version we're in. private static final String IDENTITY_VERSION_1 = "!"; - /** - * Build the identity header string. This string contains metadata about a draft message to be - * used upon loading a draft for composition. This should be generated at the time of saving a - * draft.
- *
- * This is a URL-encoded key/value pair string. The list of possible values are in {@link IdentityField}. - * @param body {@link TextBody} to analyze for body length and offset. - * @return Identity string. - */ - private String buildIdentityHeader(final TextBody body) { - return buildIdentityHeader(body, null); - } - /** * Build the identity header string. This string contains metadata about a draft message to be * used upon loading a draft for composition. This should be generated at the time of saving a @@ -1415,8 +1422,11 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc /** * Parse an identity string. Handles both legacy and new (!) style identities. + * * @param identityString - * @return + * The encoded identity string that was saved in a drafts header. + * + * @return A map containing the value for each {@link IdentityField} in the identity string. */ private Map parseIdentityHeader(final String identityString) { Map identity = new HashMap(); @@ -1487,7 +1497,8 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc } - private String appendSignature(String text) { + private String appendSignature(String originalText) { + String text = originalText; if (mIdentity.getSignatureUse()) { String signature = mSignatureView.getText().toString(); @@ -1660,6 +1671,9 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc /** * Kick off a picker for the specified MIME type and let Android take over. + * + * @param mime_type + * The MIME type we want our attachment to have. */ private void onAddAttachment2(final String mime_type) { if (mAccount.getCryptoProvider().isAvailable(this)) { @@ -1668,7 +1682,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc Intent i = new Intent(Intent.ACTION_GET_CONTENT); i.addCategory(Intent.CATEGORY_OPENABLE); i.setType(mime_type); - mIgnoreOnStop = true; + mIgnoreOnPause = true; startActivityForResult(Intent.createChooser(i, null), ACTIVITY_REQUEST_PICK_ATTACHMENT); } @@ -1704,11 +1718,12 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc name = uri.getLastPathSegment(); } - if ((contentType == null) || (contentType.indexOf('*') != -1)) { - contentType = contentResolver.getType(uri); + String usableContentType = contentType; + if ((usableContentType == null) || (usableContentType.indexOf('*') != -1)) { + usableContentType = contentResolver.getType(uri); } - if (contentType == null) { - contentType = MimeUtility.getMimeTypeByExtension(name); + if (usableContentType == null) { + usableContentType = MimeUtility.getMimeTypeByExtension(name); } if (size <= 0) { @@ -1727,7 +1742,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc Attachment attachment = new Attachment(); attachment.uri = uri; - attachment.contentType = contentType; + attachment.contentType = usableContentType; attachment.name = name; attachment.size = size; @@ -1791,7 +1806,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc } public void doLaunchContactPicker(int resultId) { - mIgnoreOnStop = true; + mIgnoreOnPause = true; startActivityForResult(mContacts.contactPickerIntent(), resultId); } @@ -1876,6 +1891,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc } } + @Override public void onClick(View view) { switch (view.getId()) { case R.id.attachment_delete: @@ -1986,7 +2002,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc private void onChooseIdentity() { // keep things simple: trigger account choice only if there are more // than 1 account - mIgnoreOnStop = true; + mIgnoreOnPause = true; if (Preferences.getPreferences(this).getAvailableAccounts().size() > 1) { final Intent intent = new Intent(this, ChooseAccount.class); intent.putExtra(ChooseAccount.EXTRA_ACCOUNT, mAccount.getUuid()); @@ -2057,12 +2073,14 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc .setTitle(R.string.save_or_discard_draft_message_dlg_title) .setMessage(R.string.save_or_discard_draft_message_instructions_fmt) .setPositiveButton(R.string.save_draft_action, new DialogInterface.OnClickListener() { + @Override public void onClick(DialogInterface dialog, int whichButton) { dismissDialog(DIALOG_SAVE_OR_DISCARD_DRAFT_MESSAGE); onSave(); } }) .setNegativeButton(R.string.discard_action, new DialogInterface.OnClickListener() { + @Override public void onClick(DialogInterface dialog, int whichButton) { dismissDialog(DIALOG_SAVE_OR_DISCARD_DRAFT_MESSAGE); onDiscard(); @@ -2074,6 +2092,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc .setTitle(R.string.refuse_to_save_draft_marked_encrypted_dlg_title) .setMessage(R.string.refuse_to_save_draft_marked_encrypted_instructions_fmt) .setNeutralButton(R.string.okay_action, new DialogInterface.OnClickListener() { + @Override public void onClick(DialogInterface dialog, int whichButton) { dismissDialog(DIALOG_REFUSE_TO_SAVE_DRAFT_MARKED_ENCRYPTED); } @@ -2084,6 +2103,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc .setTitle(R.string.continue_without_public_key_dlg_title) .setMessage(R.string.continue_without_public_key_instructions_fmt) .setPositiveButton(R.string.continue_action, new DialogInterface.OnClickListener() { + @Override public void onClick(DialogInterface dialog, int whichButton) { dismissDialog(DIALOG_CONTINUE_WITHOUT_PUBLIC_KEY); mContinueWithoutPublicKey = true; @@ -2091,6 +2111,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc } }) .setNegativeButton(R.string.back_action, new DialogInterface.OnClickListener() { + @Override public void onClick(DialogInterface dialog, int whichButton) { dismissDialog(DIALOG_CONTINUE_WITHOUT_PUBLIC_KEY); mContinueWithoutPublicKey = false; @@ -2102,7 +2123,18 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc } /** - * Returns true if all attachments were able to be attached, otherwise returns false. + * Add all attachments of an existing message as if they were added by hand. + * + * @param part + * The message part to check for being an attachment. This method will recurse if it's + * a multipart part. + * @param depth + * The recursion depth. Currently unused. + * + * @return {@code true} if all attachments were able to be attached, {@code false} otherwise. + * + * @throws MessagingException + * In case of an error */ private boolean loadAttachments(Part part, int depth) throws MessagingException { if (part.getBody() instanceof Multipart) { @@ -2114,24 +2146,25 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc } } return ret; - } else { - String contentType = MimeUtility.unfoldAndDecode(part.getContentType()); - String name = MimeUtility.getHeaderParameter(contentType, "name"); - if (name != null) { - Body body = part.getBody(); - if (body != null && body instanceof LocalAttachmentBody) { - final Uri uri = ((LocalAttachmentBody) body).getContentUri(); - mHandler.post(new Runnable() { - public void run() { - addAttachment(uri); - } - }); - } else { - return false; - } - } - return true; } + + String contentType = MimeUtility.unfoldAndDecode(part.getContentType()); + String name = MimeUtility.getHeaderParameter(contentType, "name"); + if (name != null) { + Body body = part.getBody(); + if (body != null && body instanceof LocalAttachmentBody) { + final Uri uri = ((LocalAttachmentBody) body).getContentUri(); + mHandler.post(new Runnable() { + @Override + public void run() { + addAttachment(uri); + } + }); + } else { + return false; + } + } + return true; } /** @@ -2144,7 +2177,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc try { if (ACTION_REPLY.equals(action) || ACTION_REPLY_ALL.equals(action)) { if (message.getSubject() != null) { - final String subject = prefix.matcher(message.getSubject()).replaceFirst(""); + final String subject = PREFIX.matcher(message.getSubject()).replaceFirst(""); if (!subject.toLowerCase(Locale.US).startsWith("re:")) { mSubjectView.setText("Re: " + subject); @@ -2505,9 +2538,13 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc /** * Build and populate the UI with the quoted message. + * + * @param showQuotedText + * {@code true} if the quoted text should be shown, {@code false} otherwise. + * * @throws MessagingException */ - private void populateUIWithQuotedMessage(boolean shown) throws MessagingException { + private void populateUIWithQuotedMessage(boolean showQuotedText) throws MessagingException { if (mMessageFormat == MessageFormat.AUTO) { mMessageFormat = MimeUtility.findFirstPartByMimeType(mSourceMessage, "text/html") == null ? MessageFormat.TEXT @@ -2612,7 +2649,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc mQuotedText.setText(quoteOriginalTextMessage(mSourceMessage, content, mQuoteStyle)); } - if (shown) { + if (showQuotedText) { showOrHideQuotedText(QuotedTextMode.SHOW); } else { showOrHideQuotedText(QuotedTextMode.HIDE); @@ -2820,6 +2857,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc mSourceMessage = message; runOnUiThread(new Runnable() { + @Override public void run() { // We check to see if we've previously processed the source message since this // could be called when switching from HTML to text replies. If that happens, we @@ -2873,6 +2911,9 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc /** * When we are launched with an intent that includes a mailto: URI, we can actually * gather quite a few of our message fields from it. + * + * @param mailtoUri + * The mailto: URI we use to initialize the message fields. */ private void initializeFromMailto(Uri mailtoUri) { String schemaSpecific = mailtoUri.getSchemeSpecificPart();