diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index d0f09e32e..f530b902f 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -391,5 +391,25 @@ otherwise it would make K-9 start at the wrong time
android:readPermission="com.fsck.k9.permission.READ_MESSAGES"
android:writePermission="com.fsck.k9.permission.DELETE_MESSAGES"
/>
+
+
+ * Classes extending this abstract class have to provide an {@link #onAccountSelected(Account)} + * method to perform an action when an account is selected. + *
+ */ +public abstract class AccountList extends K9ListActivity implements OnItemClickListener { + private FontSizes mFontSizes = K9.getFontSizes(); + + @Override + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + + setResult(RESULT_CANCELED); + + setContentView(R.layout.account_list); + + ListView listView = getListView(); + listView.setOnItemClickListener(this); + listView.setItemsCanFocus(false); + } + + /** + * Reload list of accounts when this activity is resumed. + */ + @Override + public void onResume() { + super.onResume(); + new LoadAccounts().execute(); + } + + public void onItemClick(AdapterView> parent, View view, int position, long id) { + Account account = (Account) parent.getItemAtPosition(position); + onAccountSelected(account); + } + + /** + * Create a new {@link AccountsAdapter} instance and assign it to the {@link ListView}. + * + * @param accounts + * An array of accounts to display. + */ + public void populateListView(Account[] accounts) { + AccountsAdapter adapter = new AccountsAdapter(accounts); + ListView listView = getListView(); + listView.setAdapter(adapter); + listView.invalidate(); + } + + /** + * This method will be called when an account was selected. + * + * @param account + * The account the user selected. + */ + protected abstract void onAccountSelected(Account account); + + class AccountsAdapter extends ArrayAdapter@@ -499,6 +500,9 @@ public class LocalStore extends Store implements Serializable { public Void doDbWork(final SQLiteDatabase db) { db.execSQL("DELETE FROM messages WHERE deleted = 0 and uid not like 'Local%'"); db.execSQL("update folders set flagged_count = 0, unread_count = 0"); + + // FIXME: hack to update unread count widget + UnreadWidgetProvider.updateUnreadCount(K9.app); return null; } }); @@ -1311,6 +1315,9 @@ public class LocalStore extends Store implements Serializable { public void setUnreadMessageCount(final int unreadMessageCount) throws MessagingException { mUnreadMessageCount = Math.max(0, unreadMessageCount); updateFolderColumn("unread_count", mUnreadMessageCount); + + // FIXME: hack to update unread count widget + UnreadWidgetProvider.updateUnreadCount(K9.app); } public void setFlaggedMessageCount(final int flaggedMessageCount) throws MessagingException { diff --git a/src/com/fsck/k9/provider/UnreadWidgetProvider.java b/src/com/fsck/k9/provider/UnreadWidgetProvider.java new file mode 100644 index 000000000..8913fb4e7 --- /dev/null +++ b/src/com/fsck/k9/provider/UnreadWidgetProvider.java @@ -0,0 +1,123 @@ +package com.fsck.k9.provider; + +import com.fsck.k9.Account; +import com.fsck.k9.AccountStats; +import com.fsck.k9.K9; +import com.fsck.k9.Preferences; +import com.fsck.k9.R; +import com.fsck.k9.activity.UnreadWidgetConfiguration; +import com.fsck.k9.activity.FolderList; +import com.fsck.k9.activity.MessageList; + +import android.app.PendingIntent; +import android.appwidget.AppWidgetManager; +import android.appwidget.AppWidgetProvider; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.util.Log; +import android.view.View; +import android.widget.RemoteViews; + +public class UnreadWidgetProvider extends AppWidgetProvider { + + /** + * Trigger update for all of our unread widgets. + * + * @param context + * The {@code Context} object to use for the broadcast intent. + */ + public static void updateUnreadCount(Context context) { + Context appContext = context.getApplicationContext(); + AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(appContext); + + ComponentName thisWidget = new ComponentName(appContext, UnreadWidgetProvider.class); + int[] widgetIds = appWidgetManager.getAppWidgetIds(thisWidget); + + Intent intent = new Intent(context, UnreadWidgetProvider.class); + intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE); + intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, widgetIds); + + context.sendBroadcast(intent); + } + + public static void updateWidget(Context context, AppWidgetManager appWidgetManager, + int appWidgetId, String accountUuid) { + + RemoteViews remoteViews = new RemoteViews(context.getPackageName(), + R.layout.unread_widget_layout); + + int unreadCount = 0; + String accountName = context.getString(R.string.app_name); + Intent clickIntent = null; + try { + Account account = Preferences.getPreferences(context).getAccount(accountUuid); + if (account != null) { + AccountStats stats = new AccountStats(); + account.getLocalStore().getMessageCounts(stats); + unreadCount = stats.unreadMessageCount; + accountName = account.getDescription(); + if (K9.FOLDER_NONE.equals(account.getAutoExpandFolderName())) { + clickIntent = FolderList.actionHandleAccountIntent(context, account, null); + } else { + clickIntent = MessageList.actionHandleFolderIntent(context, account, + account.getAutoExpandFolderName()); + } + clickIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); + } + } catch (Exception e) { + if (K9.DEBUG) { + Log.e(K9.LOG_TAG, "Error getting widget configuration", e); + } + } + + if (unreadCount == 0) { + // Hide TextView for unread count if there are no unread messages. + remoteViews.setViewVisibility(R.id.unread_count, View.GONE); + } else { + remoteViews.setTextViewText(R.id.unread_count, String.valueOf(unreadCount)); + } + + remoteViews.setTextViewText(R.id.account_name, accountName); + + if (clickIntent == null) { + // If the widget configuration couldn't be loaded we open the configuration + // activity when the user clicks the widget. + clickIntent = new Intent(context, UnreadWidgetConfiguration.class); + clickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); + } + clickIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + + + PendingIntent pendingIntent = PendingIntent.getActivity(context, appWidgetId, + clickIntent, 0); + + remoteViews.setOnClickPendingIntent(R.id.unread_widget_layout, pendingIntent); + + appWidgetManager.updateAppWidget(appWidgetId, remoteViews); + + } + + + /** + * Called when one or more widgets need to be updated. + */ + @Override + public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { + for (int widgetId : appWidgetIds) { + String accountUuid = UnreadWidgetConfiguration.getAccountUuid(context, widgetId); + + updateWidget(context, appWidgetManager, widgetId, accountUuid); + } + } + + /** + * Called when a widget instance is deleted. + */ + @Override + public void onDeleted(Context context, int[] appWidgetIds) { + for (int appWidgetId : appWidgetIds) { + UnreadWidgetConfiguration.deleteWidgetConfiguration(context, appWidgetId); + } + } +}