Search in sources :

Example 1 with LocalSearch

use of com.fsck.k9.search.LocalSearch in project k-9 by k9mail.

the class MessagingController method searchLocalMessagesSynchronous.

@VisibleForTesting
void searchLocalMessagesSynchronous(final LocalSearch search, final MessagingListener listener) {
    final AccountStats stats = new AccountStats();
    final Set<String> uuidSet = new HashSet<>(Arrays.asList(search.getAccountUuids()));
    List<Account> accounts = Preferences.getPreferences(context).getAccounts();
    boolean allAccounts = uuidSet.contains(SearchSpecification.ALL_ACCOUNTS);
    // for every account we want to search do the query in the localstore
    for (final Account account : accounts) {
        if (!allAccounts && !uuidSet.contains(account.getUuid())) {
            continue;
        }
        // Collecting statistics of the search result
        MessageRetrievalListener<LocalMessage> retrievalListener = new MessageRetrievalListener<LocalMessage>() {

            @Override
            public void messageStarted(String message, int number, int ofTotal) {
            }

            @Override
            public void messagesFinished(int number) {
            }

            @Override
            public void messageFinished(LocalMessage message, int number, int ofTotal) {
                if (!isMessageSuppressed(message)) {
                    List<LocalMessage> messages = new ArrayList<>();
                    messages.add(message);
                    stats.unreadMessageCount += (!message.isSet(Flag.SEEN)) ? 1 : 0;
                    stats.flaggedMessageCount += (message.isSet(Flag.FLAGGED)) ? 1 : 0;
                    if (listener != null) {
                        listener.listLocalMessagesAddMessages(account, null, messages);
                    }
                }
            }
        };
        // build and do the query in the localstore
        try {
            LocalStore localStore = account.getLocalStore();
            localStore.searchForMessages(retrievalListener, search);
        } catch (Exception e) {
            addErrorMessage(account, null, e);
        }
    }
    // publish the total search statistics
    if (listener != null) {
        listener.searchStats(stats);
    }
}
Also used : SearchAccount(com.fsck.k9.search.SearchAccount) Account(com.fsck.k9.Account) LocalMessage(com.fsck.k9.mailstore.LocalMessage) ArrayList(java.util.ArrayList) LocalStore(com.fsck.k9.mailstore.LocalStore) CertificateValidationException(com.fsck.k9.mail.CertificateValidationException) UnavailableStorageException(com.fsck.k9.mailstore.UnavailableStorageException) IOException(java.io.IOException) MessagingException(com.fsck.k9.mail.MessagingException) AuthenticationFailedException(com.fsck.k9.mail.AuthenticationFailedException) MessageRetrievalListener(com.fsck.k9.mail.MessageRetrievalListener) AccountStats(com.fsck.k9.AccountStats) HashSet(java.util.HashSet) VisibleForTesting(android.support.annotation.VisibleForTesting)

Example 2 with LocalSearch

use of com.fsck.k9.search.LocalSearch in project k-9 by k9mail.

the class UnreadWidgetProvider method updateWidget.

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 {
        BaseAccount account = null;
        AccountStats stats = null;
        SearchAccount searchAccount = null;
        if (SearchAccount.UNIFIED_INBOX.equals(accountUuid)) {
            searchAccount = SearchAccount.createUnifiedInboxAccount(context);
        } else if (SearchAccount.ALL_MESSAGES.equals(accountUuid)) {
            searchAccount = SearchAccount.createAllMessagesAccount(context);
        }
        if (searchAccount != null) {
            account = searchAccount;
            MessagingController controller = MessagingController.getInstance(context);
            stats = controller.getSearchAccountStatsSynchronous(searchAccount, null);
            clickIntent = MessageList.intentDisplaySearch(context, searchAccount.getRelatedSearch(), false, true, true);
        } else {
            Account realAccount = Preferences.getPreferences(context).getAccount(accountUuid);
            if (realAccount != null) {
                account = realAccount;
                stats = realAccount.getStats(context);
                if (K9.FOLDER_NONE.equals(realAccount.getAutoExpandFolderName())) {
                    clickIntent = FolderList.actionHandleAccountIntent(context, realAccount, false);
                } else {
                    LocalSearch search = new LocalSearch(realAccount.getAutoExpandFolderName());
                    search.addAllowedFolder(realAccount.getAutoExpandFolderName());
                    search.addAccountUuid(account.getUuid());
                    clickIntent = MessageList.intentDisplaySearch(context, search, false, true, true);
                }
                clickIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
            }
        }
        if (account != null) {
            accountName = account.getDescription();
        }
        if (stats != null) {
            unreadCount = stats.unreadMessageCount;
        }
    } catch (Exception e) {
        Timber.e(e, "Error getting widget configuration");
    }
    if (unreadCount <= 0) {
        // Hide TextView for unread count if there are no unread messages.
        remoteViews.setViewVisibility(R.id.unread_count, View.GONE);
    } else {
        remoteViews.setViewVisibility(R.id.unread_count, View.VISIBLE);
        String displayCount = (unreadCount <= MAX_COUNT) ? String.valueOf(unreadCount) : String.valueOf(MAX_COUNT) + "+";
        remoteViews.setTextViewText(R.id.unread_count, displayCount);
    }
    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);
}
Also used : SearchAccount(com.fsck.k9.search.SearchAccount) Account(com.fsck.k9.Account) BaseAccount(com.fsck.k9.BaseAccount) UnreadWidgetConfiguration(com.fsck.k9.activity.UnreadWidgetConfiguration) MessagingController(com.fsck.k9.controller.MessagingController) Intent(android.content.Intent) PendingIntent(android.app.PendingIntent) SearchAccount(com.fsck.k9.search.SearchAccount) RemoteViews(android.widget.RemoteViews) LocalSearch(com.fsck.k9.search.LocalSearch) BaseAccount(com.fsck.k9.BaseAccount) PendingIntent(android.app.PendingIntent) AccountStats(com.fsck.k9.AccountStats)

Example 3 with LocalSearch

use of com.fsck.k9.search.LocalSearch in project k-9 by k9mail.

the class SqlQueryBuilder method buildWhereClauseInternal.

private static void buildWhereClauseInternal(Account account, ConditionsTreeNode node, StringBuilder query, List<String> selectionArgs) {
    if (node == null) {
        query.append("1");
        return;
    }
    if (node.mLeft == null && node.mRight == null) {
        SearchCondition condition = node.mCondition;
        switch(condition.field) {
            case FOLDER:
                {
                    String folderName = condition.value;
                    long folderId = getFolderId(account, folderName);
                    if (condition.attribute == Attribute.EQUALS) {
                        query.append("folder_id = ?");
                    } else {
                        query.append("folder_id != ?");
                    }
                    selectionArgs.add(Long.toString(folderId));
                    break;
                }
            case SEARCHABLE:
                {
                    switch(account.getSearchableFolders()) {
                        case ALL:
                            {
                                // Create temporary LocalSearch object so we can use...
                                LocalSearch tempSearch = new LocalSearch();
                                // ...the helper methods in Account to create the necessary conditions
                                // to exclude "unwanted" folders.
                                account.excludeUnwantedFolders(tempSearch);
                                buildWhereClauseInternal(account, tempSearch.getConditions(), query, selectionArgs);
                                break;
                            }
                        case DISPLAYABLE:
                            {
                                // Create temporary LocalSearch object so we can use...
                                LocalSearch tempSearch = new LocalSearch();
                                // ...the helper methods in Account to create the necessary conditions
                                // to limit the selection to displayable, non-special folders.
                                account.excludeSpecialFolders(tempSearch);
                                account.limitToDisplayableFolders(tempSearch);
                                buildWhereClauseInternal(account, tempSearch.getConditions(), query, selectionArgs);
                                break;
                            }
                        case NONE:
                            {
                                // Dummy condition, never select
                                query.append("0");
                                break;
                            }
                    }
                    break;
                }
            case MESSAGE_CONTENTS:
                {
                    String fulltextQueryString = condition.value;
                    if (condition.attribute != Attribute.CONTAINS) {
                        Timber.e("message contents can only be matched!");
                    }
                    query.append("(EXISTS (SELECT docid FROM messages_fulltext WHERE docid = id AND fulltext MATCH ?))");
                    selectionArgs.add(fulltextQueryString);
                    break;
                }
            default:
                {
                    appendCondition(condition, query, selectionArgs);
                }
        }
    } else {
        query.append("(");
        buildWhereClauseInternal(account, node.mLeft, query, selectionArgs);
        query.append(") ");
        query.append(node.mValue.name());
        query.append(" (");
        buildWhereClauseInternal(account, node.mRight, query, selectionArgs);
        query.append(")");
    }
}
Also used : SearchCondition(com.fsck.k9.search.SearchSpecification.SearchCondition)

Example 4 with LocalSearch

use of com.fsck.k9.search.LocalSearch in project k-9 by k9mail.

the class MessageList method decodeExtras.

private boolean decodeExtras(Intent intent) {
    String action = intent.getAction();
    if (Intent.ACTION_VIEW.equals(action) && intent.getData() != null) {
        Uri uri = intent.getData();
        List<String> segmentList = uri.getPathSegments();
        String accountId = segmentList.get(0);
        Collection<Account> accounts = Preferences.getPreferences(this).getAvailableAccounts();
        for (Account account : accounts) {
            if (String.valueOf(account.getAccountNumber()).equals(accountId)) {
                String folderName = segmentList.get(1);
                String messageUid = segmentList.get(2);
                mMessageReference = new MessageReference(account.getUuid(), folderName, messageUid, null);
                break;
            }
        }
    } else if (ACTION_SHORTCUT.equals(action)) {
        // Handle shortcut intents
        String specialFolder = intent.getStringExtra(EXTRA_SPECIAL_FOLDER);
        if (SearchAccount.UNIFIED_INBOX.equals(specialFolder)) {
            mSearch = SearchAccount.createUnifiedInboxAccount(this).getRelatedSearch();
        } else if (SearchAccount.ALL_MESSAGES.equals(specialFolder)) {
            mSearch = SearchAccount.createAllMessagesAccount(this).getRelatedSearch();
        }
    } else if (intent.getStringExtra(SearchManager.QUERY) != null) {
        // check if this intent comes from the system search ( remote )
        if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
            //Query was received from Search Dialog
            String query = intent.getStringExtra(SearchManager.QUERY).trim();
            mSearch = new LocalSearch(getString(R.string.search_results));
            mSearch.setManualSearch(true);
            mNoThreading = true;
            mSearch.or(new SearchCondition(SearchField.SENDER, Attribute.CONTAINS, query));
            mSearch.or(new SearchCondition(SearchField.SUBJECT, Attribute.CONTAINS, query));
            mSearch.or(new SearchCondition(SearchField.MESSAGE_CONTENTS, Attribute.CONTAINS, query));
            Bundle appData = intent.getBundleExtra(SearchManager.APP_DATA);
            if (appData != null) {
                mSearch.addAccountUuid(appData.getString(EXTRA_SEARCH_ACCOUNT));
                // searches started from a folder list activity will provide an account, but no folder
                if (appData.getString(EXTRA_SEARCH_FOLDER) != null) {
                    mSearch.addAllowedFolder(appData.getString(EXTRA_SEARCH_FOLDER));
                }
            } else {
                mSearch.addAccountUuid(LocalSearch.ALL_ACCOUNTS);
            }
        }
    } else if (intent.hasExtra(EXTRA_SEARCH_OLD)) {
        mSearch = intent.getParcelableExtra(EXTRA_SEARCH_OLD);
        mNoThreading = intent.getBooleanExtra(EXTRA_NO_THREADING, false);
    } else {
        // regular LocalSearch object was passed
        mSearch = intent.hasExtra(EXTRA_SEARCH) ? ParcelableUtil.unmarshall(intent.getByteArrayExtra(EXTRA_SEARCH), LocalSearch.CREATOR) : null;
        mNoThreading = intent.getBooleanExtra(EXTRA_NO_THREADING, false);
    }
    if (mMessageReference == null) {
        String messageReferenceString = intent.getStringExtra(EXTRA_MESSAGE_REFERENCE);
        mMessageReference = MessageReference.parse(messageReferenceString);
    }
    if (mMessageReference != null) {
        mSearch = new LocalSearch();
        mSearch.addAccountUuid(mMessageReference.getAccountUuid());
        mSearch.addAllowedFolder(mMessageReference.getFolderName());
    }
    if (mSearch == null) {
        // We've most likely been started by an old unread widget
        String accountUuid = intent.getStringExtra("account");
        String folderName = intent.getStringExtra("folder");
        mSearch = new LocalSearch(folderName);
        mSearch.addAccountUuid((accountUuid == null) ? "invalid" : accountUuid);
        if (folderName != null) {
            mSearch.addAllowedFolder(folderName);
        }
    }
    Preferences prefs = Preferences.getPreferences(getApplicationContext());
    String[] accountUuids = mSearch.getAccountUuids();
    if (mSearch.searchAllAccounts()) {
        List<Account> accounts = prefs.getAccounts();
        mSingleAccountMode = (accounts.size() == 1);
        if (mSingleAccountMode) {
            mAccount = accounts.get(0);
        }
    } else {
        mSingleAccountMode = (accountUuids.length == 1);
        if (mSingleAccountMode) {
            mAccount = prefs.getAccount(accountUuids[0]);
        }
    }
    mSingleFolderMode = mSingleAccountMode && (mSearch.getFolderNames().size() == 1);
    if (mSingleAccountMode && (mAccount == null || !mAccount.isAvailable(this))) {
        Timber.i("not opening MessageList of unavailable account");
        onAccountUnavailable();
        return false;
    }
    if (mSingleFolderMode) {
        mFolderName = mSearch.getFolderNames().get(0);
    }
    // now we know if we are in single account mode and need a subtitle
    mActionBarSubTitle.setVisibility((!mSingleFolderMode) ? View.GONE : View.VISIBLE);
    return true;
}
Also used : SearchAccount(com.fsck.k9.search.SearchAccount) Account(com.fsck.k9.Account) SearchCondition(com.fsck.k9.search.SearchSpecification.SearchCondition) LocalSearch(com.fsck.k9.search.LocalSearch) Bundle(android.os.Bundle) Preferences(com.fsck.k9.Preferences) Uri(android.net.Uri)

Example 5 with LocalSearch

use of com.fsck.k9.search.LocalSearch in project k-9 by k9mail.

the class MessageList method showThread.

@Override
public void showThread(Account account, String folderName, long threadRootId) {
    showMessageViewPlaceHolder();
    LocalSearch tmpSearch = new LocalSearch();
    tmpSearch.addAccountUuid(account.getUuid());
    tmpSearch.and(SearchField.THREAD_ID, String.valueOf(threadRootId), Attribute.EQUALS);
    MessageListFragment fragment = MessageListFragment.newInstance(tmpSearch, true, false);
    addMessageListFragment(fragment, true);
}
Also used : LocalSearch(com.fsck.k9.search.LocalSearch) MessageListFragment(com.fsck.k9.fragment.MessageListFragment)

Aggregations

LocalSearch (com.fsck.k9.search.LocalSearch)13 Account (com.fsck.k9.Account)6 SearchAccount (com.fsck.k9.search.SearchAccount)6 SearchCondition (com.fsck.k9.search.SearchSpecification.SearchCondition)4 PendingIntent (android.app.PendingIntent)3 Intent (android.content.Intent)3 Uri (android.net.Uri)3 AccountStats (com.fsck.k9.AccountStats)3 BaseAccount (com.fsck.k9.BaseAccount)3 ArrayList (java.util.ArrayList)3 ContentResolver (android.content.ContentResolver)2 Cursor (android.database.Cursor)2 TaskStackBuilder (android.support.v4.app.TaskStackBuilder)2 Preferences (com.fsck.k9.Preferences)2 MessageListFragment (com.fsck.k9.fragment.MessageListFragment)2 LocalStore (com.fsck.k9.mailstore.LocalStore)2 ConditionsTreeNode (com.fsck.k9.search.ConditionsTreeNode)2 SuppressLint (android.annotation.SuppressLint)1 Bundle (android.os.Bundle)1 VisibleForTesting (android.support.annotation.VisibleForTesting)1