@Override
  protected Dialog onCreateDialog(int id) {
    StyledDialog dialog = null;
    Resources res = getResources();
    StyledDialog.Builder builder = new StyledDialog.Builder(this);

    switch (id) {
      case DIALOG_ORDER:
        builder.setTitle(res.getString(R.string.card_browser_change_display_order_title));
        builder.setIcon(android.R.drawable.ic_menu_sort_by_size);
        builder.setSingleChoiceItems(
            getResources().getStringArray(R.array.card_browser_order_labels),
            mSelectedOrder,
            new DialogInterface.OnClickListener() {
              @Override
              public void onClick(DialogInterface arg0, int which) {
                if (which != mSelectedOrder) {
                  mSelectedOrder = which;
                  getCards();
                }
              }
            });
        dialog = builder.create();
    }
    return dialog;
  }
        @Override
        public void onClick(DialogInterface dialog, int which) {
          switch (which) {
            case CONTEXT_MENU_MARK:
              DeckTask.launchDeckTask(
                  DeckTask.TASK_TYPE_MARK_CARD,
                  mUpdateCardHandler,
                  new DeckTask.TaskData(
                      mCol.getSched(),
                      mCol.getCard(Long.parseLong(mCards.get(mPositionInCardsList).get("id"))),
                      0));
              return;

            case CONTEXT_MENU_SUSPEND:
              DeckTask.launchDeckTask(
                  DeckTask.TASK_TYPE_DISMISS_NOTE,
                  mSuspendCardHandler,
                  new DeckTask.TaskData(
                      mCol.getSched(),
                      mCol.getCard(Long.parseLong(mCards.get(mPositionInCardsList).get("id"))),
                      1));
              return;

            case CONTEXT_MENU_DELETE:
              Resources res = getResources();
              StyledDialog.Builder builder = new StyledDialog.Builder(CardBrowser.this);
              builder.setTitle(res.getString(R.string.delete_card_title));
              builder.setIcon(android.R.drawable.ic_dialog_alert);
              builder.setMessage(
                  res.getString(
                      R.string.delete_card_message, mCards.get(mPositionInCardsList).get("sfld")));
              builder.setPositiveButton(
                  res.getString(R.string.yes),
                  new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                      Card card =
                          mCol.getCard(Long.parseLong(mCards.get(mPositionInCardsList).get("id")));
                      deleteNote(card);
                      DeckTask.launchDeckTask(
                          DeckTask.TASK_TYPE_DISMISS_NOTE,
                          mDeleteNoteHandler,
                          new DeckTask.TaskData(mCol.getSched(), card, 3));
                    }
                  });
              builder.setNegativeButton(res.getString(R.string.no), null);
              builder.create().show();
              return;

            case CONTEXT_MENU_DETAILS:
              Card tempCard =
                  mCol.getCard(Long.parseLong(mCards.get(mPositionInCardsList).get("id")));
              Themes.htmlOkDialog(
                      CardBrowser.this,
                      getResources().getString(R.string.card_browser_card_details),
                      tempCard.getCardDetails(CardBrowser.this))
                  .show();
              return;
          }
        }
  @Override
  public boolean onContextItemSelected(MenuItem item) {
    AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();

    switch (item.getItemId()) {
      case CONTEXT_MENU_MARK:
        mPositionInCardsList = info.position;
        DeckTask.launchDeckTask(
            DeckTask.TASK_TYPE_MARK_CARD,
            mMarkCardHandler,
            new DeckTask.TaskData(0, mDeck, mSelectedCard));
        return true;
      case CONTEXT_MENU_SUSPEND:
        mPositionInCardsList = info.position;
        DeckTask.launchDeckTask(
            DeckTask.TASK_TYPE_SUSPEND_CARD,
            mSuspendCardHandler,
            new DeckTask.TaskData(0, mDeck, mSelectedCard));
        return true;
      case CONTEXT_MENU_DELETE:
        mPositionInCardsList = info.position;

        Dialog dialog;
        Resources res = getResources();
        StyledDialog.Builder builder = new StyledDialog.Builder(this);
        builder.setTitle(res.getString(R.string.delete_card_title));
        builder.setIcon(android.R.drawable.ic_dialog_alert);
        builder.setMessage(
            String.format(
                res.getString(R.string.delete_card_message),
                mCards.get(mPositionInCardsList).get("question"),
                mCards.get(mPositionInCardsList).get("answer")));
        builder.setPositiveButton(
            res.getString(R.string.yes),
            new DialogInterface.OnClickListener() {
              @Override
              public void onClick(DialogInterface dialog, int which) {
                DeckTask.launchDeckTask(
                    DeckTask.TASK_TYPE_DELETE_CARD,
                    mDeleteCardHandler,
                    new DeckTask.TaskData(0, mDeck, mSelectedCard));
              }
            });
        builder.setNegativeButton(res.getString(R.string.no), null);
        dialog = builder.create();
        dialog.show();
        return true;
      case CONTEXT_MENU_DETAILS:
        Themes.htmlOkDialog(
                this,
                getResources().getString(R.string.card_browser_card_details),
                mSelectedCard.getCardDetails(this, true))
            .show();
        return true;
      default:
        return super.onContextItemSelected(item);
    }
  }
        @Override
        public void onProgressUpdate(DeckTask.TaskData... values) {
          mAllCards.clear();
          ArrayList<String[]> allCards = values[0].getAllCards();
          if (allCards == null) {
            Resources res = getResources();
            StyledDialog.Builder builder = new StyledDialog.Builder(CardBrowser.this);
            builder.setTitle(res.getString(R.string.error));
            builder.setIcon(android.R.drawable.ic_dialog_alert);
            builder.setMessage(res.getString(R.string.card_browser_cardloading_error));
            builder.setPositiveButton(
                res.getString(R.string.ok),
                new DialogInterface.OnClickListener() {
                  @Override
                  public void onClick(DialogInterface dialog, int which) {
                    CardBrowser.this.finish();
                  }
                });
            builder.setOnCancelListener(
                new OnCancelListener() {
                  @Override
                  public void onCancel(DialogInterface dialog) {
                    CardBrowser.this.finish();
                  }
                });
            builder.create().show();
          } else {
            for (String[] item : allCards) {
              // reshape Arabic words
              if (mPrefFixArabic) {
                item[1] = ArabicUtilities.reshapeSentence(item[1]);
                item[2] = ArabicUtilities.reshapeSentence(item[2]);
              }

              HashMap<String, String> data = new HashMap<String, String>();
              data.put("id", item[0]);
              data.put("question", item[1]);
              data.put("answer", item[2]);
              data.put("marSus", item[3]);
              data.put("tags", item[4]);
              mAllCards.add(data);
            }
            updateCardsList();
          }

          // This verification would not be necessary if
          // onConfigurationChanged it's executed correctly (which seems
          // that emulator does not do)
          if (mProgressDialog.isShowing()) {
            try {
              mProgressDialog.dismiss();
            } catch (Exception e) {
              Log.e(
                  AnkiDroidApp.TAG, "onPostExecute - Dialog dismiss Exception = " + e.getMessage());
            }
          }
        }
  private void recreateTagsDialog() {
    Resources res = getResources();
    if (allTags == null) {
      String[] oldTags = AnkiDroidApp.deck().allTags_();
      Log.i(AnkiDroidApp.TAG, "all tags: " + Arrays.toString(oldTags));
      allTags = new String[oldTags.length];
      for (int i = 0; i < oldTags.length; i++) {
        allTags[i] = oldTags[i];
      }
    }
    mSelectedTags.clear();

    StyledDialog.Builder builder = new StyledDialog.Builder(this);
    builder.setTitle(R.string.studyoptions_limit_select_tags);
    builder.setMultiChoiceItems(
        allTags,
        new boolean[0],
        new DialogInterface.OnClickListener() {
          @Override
          public void onClick(DialogInterface dialog, int which) {
            String tag = allTags[which];
            if (mSelectedTags.contains(tag)) {
              Log.i(AnkiDroidApp.TAG, "unchecked tag: " + tag);
              mSelectedTags.remove(tag);
            } else {
              Log.i(AnkiDroidApp.TAG, "checked tag: " + tag);
              mSelectedTags.add(tag);
            }
          }
        });
    builder.setPositiveButton(
        res.getString(R.string.select),
        new OnClickListener() {
          @Override
          public void onClick(DialogInterface dialog, int which) {
            updateCardsList();
          }
        });
    builder.setNegativeButton(
        res.getString(R.string.cancel),
        new OnClickListener() {
          @Override
          public void onClick(DialogInterface dialog, int which) {
            mSelectedTags.clear();
          }
        });
    builder.setOnCancelListener(
        new OnCancelListener() {

          @Override
          public void onCancel(DialogInterface dialog) {
            mSelectedTags.clear();
          }
        });
    mTagsDialog = builder.create();
  }
  /** Create AlertDialogs used on all the activity */
  private void initAllAlertDialogs() {
    Resources res = getResources();

    StyledDialog.Builder builder = new StyledDialog.Builder(this);

    builder.setTitle(res.getString(R.string.connection_error_title));
    builder.setIcon(R.drawable.ic_dialog_alert);
    builder.setMessage(res.getString(R.string.connection_needed));
    builder.setPositiveButton(
        res.getString(R.string.ok),
        new DialogInterface.OnClickListener() {
          @Override
          public void onClick(DialogInterface dialog, int which) {
            mPostingFeedback = false;
            refreshInterface();
          }
        });
    mNoConnectionAlert = builder.create();
  }
        @Override
        public void onProgressUpdate(DeckTask.TaskData... values) {
          if (canceled) {
            return;
          }
          ArrayList<HashMap<String, String>> cards = values[0].getCards();
          if (cards == null) {
            Resources res = getResources();
            StyledDialog.Builder builder = new StyledDialog.Builder(CardBrowser.this);
            builder.setTitle(res.getString(R.string.error));
            builder.setIcon(android.R.drawable.ic_dialog_alert);
            builder.setMessage(res.getString(R.string.card_browser_cardloading_error));
            builder.setPositiveButton(
                res.getString(R.string.ok),
                new DialogInterface.OnClickListener() {
                  @Override
                  public void onClick(DialogInterface dialog, int which) {
                    closeCardBrowser();
                  }
                });
            builder.setOnCancelListener(
                new OnCancelListener() {
                  @Override
                  public void onCancel(DialogInterface dialog) {
                    closeCardBrowser();
                  }
                });
            builder.create().show();
          } else {
            if (mPrefFixArabic) {
              for (HashMap<String, String> entry : cards) {
                entry.put("sfld", ArabicUtilities.reshapeSentence(entry.get("sfld")));
              }
            }
            try {

              int field =
                  AnkiDroidApp.getSharedPrefs(getBaseContext()).getInt("cardBrowserField", 0);

              Card tempCard =
                  mCol.getCard(
                      Long.parseLong(
                          cards.get(0).get("id"))); // Long.parseLong(mCards.get(0).get("id"))

              ArrayList<String> uniqueFields = new ArrayList<String>();

              if (field > 0 && (mFields != null)) {
                for (HashMap<String, String> entry : cards) {
                  tempCard = mCol.getCard(Long.parseLong(entry.get("id")));
                  String item = tempCard.note().getitem(mFields[field]);
                  entry.put("sfld", item);

                  if (!uniqueFields.contains(item)) {
                    uniqueFields.add(item);
                    mAllCards.add(entry);
                    mCards.add(entry);
                  }
                }
              } else {
                mAllCards.addAll(cards);
                mCards.addAll(cards);
              }

              if (mOrder == CARD_ORDER_NONE) {
                updateCardsList();
                mProgressDialog.dismiss();
              } else {
                DeckTask.launchDeckTask(
                    DeckTask.TASK_TYPE_UPDATE_CARD_BROWSER_LIST,
                    mSortCardsHandler,
                    new DeckTask.TaskData(mAllCards, new HashMapCompare()));
              }
            } catch (OutOfMemoryError e) {
              Log.e(AnkiDroidApp.TAG, "CardBrowser: mLoadCardsHandler: OutOfMemoryError: " + e);
              Themes.showThemedToast(
                  CardBrowser.this,
                  getResources().getString(R.string.error_insufficient_memory),
                  false);
              closeCardBrowser();
            }
          }
        }
  @Override
  protected Dialog onCreateDialog(int id) {
    StyledDialog dialog = null;
    Resources res = getResources();
    StyledDialog.Builder builder = new StyledDialog.Builder(this);

    switch (id) {
      case DIALOG_ORDER:
        builder.setTitle(res.getString(R.string.card_browser_change_display_order_title));
        builder.setIcon(android.R.drawable.ic_menu_sort_by_size);
        builder.setSingleChoiceItems(
            getResources().getStringArray(R.array.card_browser_order_labels),
            mOrder,
            new DialogInterface.OnClickListener() {
              @Override
              public void onClick(DialogInterface arg0, int which) {
                if (which != mOrder) {
                  mOrder = which;
                  AnkiDroidApp.getSharedPrefs(AnkiDroidApp.getInstance().getBaseContext())
                      .edit()
                      .putInt("cardBrowserOrder", mOrder)
                      .commit();
                  if (mOrder != CARD_ORDER_NONE) {
                    DeckTask.launchDeckTask(
                        DeckTask.TASK_TYPE_UPDATE_CARD_BROWSER_LIST,
                        mSortCardsHandler,
                        new DeckTask.TaskData(mAllCards, new HashMapCompare()));
                  }
                }
              }
            });
        dialog = builder.create();
        break;

      case DIALOG_CONTEXT_MENU:
        String[] entries = new String[4];
        @SuppressWarnings("unused")
        MenuItem item;
        entries[CONTEXT_MENU_MARK] = res.getString(R.string.card_browser_mark_card);
        entries[CONTEXT_MENU_SUSPEND] = res.getString(R.string.card_browser_suspend_card);
        entries[CONTEXT_MENU_DELETE] = res.getString(R.string.card_browser_delete_card);
        entries[CONTEXT_MENU_DETAILS] = res.getString(R.string.card_browser_card_details);
        builder.setTitle("contextmenu");
        builder.setIcon(R.drawable.ic_menu_manage);
        builder.setItems(entries, mContextMenuListener);
        dialog = builder.create();
        break;

      case DIALOG_TAGS:
        allTags = mCol.getTags().all();
        builder.setTitle(R.string.studyoptions_limit_select_tags);
        builder.setMultiChoiceItems(
            allTags,
            new boolean[allTags.length],
            new DialogInterface.OnClickListener() {
              @Override
              public void onClick(DialogInterface dialog, int which) {
                String tag = allTags[which];
                if (mSelectedTags.contains(tag)) {
                  Log.i(AnkiDroidApp.TAG, "unchecked tag: " + tag);
                  mSelectedTags.remove(tag);
                } else {
                  Log.i(AnkiDroidApp.TAG, "checked tag: " + tag);
                  mSelectedTags.add(tag);
                }
              }
            });
        builder.setPositiveButton(
            res.getString(R.string.select),
            new OnClickListener() {
              @Override
              public void onClick(DialogInterface dialog, int which) {
                mSearchEditText.setText("");
                mTimerHandler.removeCallbacks(updateList);
                String tags = mSelectedTags.toString();
                mSearchEditText.setHint(
                    getResources()
                        .getString(
                            R.string.card_browser_tags_shown,
                            tags.substring(1, tags.length() - 1)));
                DeckTask.launchDeckTask(
                    DeckTask.TASK_TYPE_UPDATE_CARD_BROWSER_LIST,
                    new DeckTask.TaskListener() {
                      @Override
                      public void onPreExecute() {
                        mProgressDialog =
                            StyledProgressDialog.show(
                                CardBrowser.this,
                                "",
                                getResources().getString(R.string.card_browser_filtering_cards),
                                true);
                      }

                      @Override
                      public void onProgressUpdate(DeckTask.TaskData... values) {}

                      @Override
                      public void onPostExecute(DeckTask.TaskData result) {
                        updateList();
                        if (mProgressDialog != null && mProgressDialog.isShowing()) {
                          mProgressDialog.dismiss();
                        }
                      }
                    },
                    new DeckTask.TaskData(mAllCards),
                    new DeckTask.TaskData(mCards),
                    new DeckTask.TaskData(new Object[] {mSelectedTags}));
              }
            });
        builder.setNegativeButton(
            res.getString(R.string.cancel),
            new OnClickListener() {
              @Override
              public void onClick(DialogInterface dialog, int which) {
                mSelectedTags.clear();
              }
            });
        builder.setOnCancelListener(
            new OnCancelListener() {

              @Override
              public void onCancel(DialogInterface dialog) {
                mSelectedTags.clear();
              }
            });
        dialog = builder.create();
        break;
        //		case DIALOG_RELOAD_CARDS:
        //			builder.setTitle(res.getString(R.string.pref_cache_cardbrowser));
        //			builder.setMessage(res.getString(R.string.pref_cache_cardbrowser_reload));
        //			builder.setPositiveButton(res.getString(R.string.yes), new OnClickListener() {
        //
        //				@Override
        //				public void onClick(DialogInterface arg0, int arg1) {
        //					DeckTask.launchDeckTask(DeckTask.TASK_TYPE_LOAD_CARDS,
        //							mLoadCardsHandler,
        //							new DeckTask.TaskData(mDeck, LOAD_CHUNK));
        //					}
        //
        //			});
        //			builder.setNegativeButton(res.getString(R.string.no), new OnClickListener() {
        //
        //				@Override
        //				public void onClick(DialogInterface arg0, int arg1) {
        //					mAllCards.addAll(sAllCardsCache);
        //					mCards.addAll(mAllCards);
        //					updateList();
        //				}
        //
        //			});
        //			builder.setCancelable(true);
        //			builder.setOnCancelListener(new OnCancelListener() {
        //
        //				@Override
        //				public void onCancel(DialogInterface arg0) {
        //					mAllCards.addAll(sAllCardsCache);
        //					mCards.addAll(mAllCards);
        //					updateList();
        //				}
        //
        //			});
        //			dialog = builder.create();
        //			break;
      case DIALOG_FIELD:
        builder.setTitle(res.getString(R.string.card_browser_field_title));
        builder.setIcon(android.R.drawable.ic_menu_sort_by_size);

        HashMap<String, String> card = mAllCards.get(0);

        String[][] items = mCol.getCard(Long.parseLong(card.get("id"))).note().items();

        mFields = new String[items.length + 1];
        mFields[0] = "SFLD";

        for (int i = 0; i < items.length; i++) {
          mFields[i + 1] = items[i][0];
        }

        builder.setSingleChoiceItems(
            mFields,
            0,
            new DialogInterface.OnClickListener() {
              @Override
              public void onClick(DialogInterface arg0, int which) {
                if (which != mField) {
                  mField = which;
                  AnkiDroidApp.getSharedPrefs(AnkiDroidApp.getInstance().getBaseContext())
                      .edit()
                      .putInt("cardBrowserField", mField)
                      .commit();
                  getCards();
                }
              }
            });
        dialog = builder.create();
        break;
    }
    return dialog;
  }
  @Override
  protected Dialog onCreateDialog(int id) {
    Resources res = getResources();
    StyledDialog.Builder builder = new StyledDialog.Builder(this);
    switch (id) {
      case DIALOG_BACKUP:
        builder.setTitle(res.getString(R.string.backup_manager_title));
        builder.setCancelable(false);
        builder.setMessage(res.getString(R.string.pref_backup_warning));
        builder.setPositiveButton(
            res.getString(R.string.yes),
            new OnClickListener() {

              @Override
              public void onClick(DialogInterface arg0, int arg1) {
                lockCheckAction = true;
                useBackupPreference.setChecked(false);
                dialogMessage = getResources().getString(R.string.backup_delete);
                DeckTask.launchDeckTask(
                    DeckTask.TASK_TYPE_DELETE_BACKUPS,
                    mDeckOperationHandler,
                    (DeckTask.TaskData[]) null);
              }
            });
        builder.setNegativeButton(res.getString(R.string.no), null);
        break;
      case DIALOG_ASYNC:
        builder.setTitle(res.getString(R.string.async_mode));
        builder.setCancelable(false);
        builder.setMessage(res.getString(R.string.async_mode_message));
        builder.setPositiveButton(
            res.getString(R.string.yes),
            new OnClickListener() {

              @Override
              public void onClick(DialogInterface arg0, int arg1) {
                lockCheckAction = true;
                asyncModePreference.setChecked(true);
              }
            });
        builder.setNegativeButton(res.getString(R.string.no), null);
        break;
      case DIALOG_WRITE_ANSWERS:
        builder.setTitle(res.getString(R.string.write_answers));
        builder.setCancelable(false);
        builder.setMessage(res.getString(R.string.write_answers_message));
        builder.setNegativeButton(res.getString(R.string.ok), null);
        break;
      case DIALOG_HEBREW_FONT:
        builder.setTitle(res.getString(R.string.fix_hebrew_text));
        builder.setCancelable(false);
        builder.setMessage(
            res.getString(
                R.string.fix_hebrew_instructions, AnkiDroidApp.getCurrentAnkiDroidDirectory()));
        builder.setNegativeButton(R.string.cancel, null);
        builder.setPositiveButton(
            res.getString(R.string.fix_hebrew_download_font),
            new OnClickListener() {
              @Override
              public void onClick(DialogInterface dialog, int which) {
                Intent intent =
                    new Intent(
                        "android.intent.action.VIEW",
                        Uri.parse(getResources().getString(R.string.link_hebrew_font)));
                startActivity(intent);
              }
            });
        break;
    }
    return builder.create();
  }
Exemple #10
0
 public static boolean lookUp(String text) {
   if (!mIsDictionaryAvailable) {
     return false;
   }
   // clear text from leading and closing dots, commas, brackets etc.
   text =
       text.trim()
           .replaceAll("[,;:\\s\\(\\[\\)\\]\\.]*$", "")
           .replaceAll("^[,;:\\s\\(\\[\\)\\]\\.]*", "");
   switch (mDictionary) {
     case DICTIONARY_NONE:
       return false;
     case DICTIONARY_AEDICT:
       Intent aedictSearchIntent = new Intent(mDictionaryAction);
       aedictSearchIntent.putExtra("kanjis", text);
       mContext.startActivity(aedictSearchIntent);
       return true;
     case DICTIONARY_LEO_WEB:
     case DICTIONARY_LEO_APP:
       mLookupText = text;
       // localisation is needless here since leo.org translates only into or out of German
       final CharSequence[] itemValues = {"en", "fr", "es", "it", "ch", "ru"};
       String language = getLanguage(MetaDB.LANGUAGES_QA_UNDEFINED);
       if (language.length() > 0) {
         for (int i = 0; i < itemValues.length; i++) {
           if (language.equals(itemValues[i])) {
             lookupLeo(language, mLookupText);
             mLookupText = "";
             return true;
           }
         }
       }
       final String[] items = {
         "Englisch", "Französisch", "Spanisch", "Italienisch", "Chinesisch", "Russisch"
       };
       StyledDialog.Builder builder = new StyledDialog.Builder(mContext);
       builder.setTitle("\"" + mLookupText + "\" nachschlagen");
       builder.setItems(
           items,
           new DialogInterface.OnClickListener() {
             public void onClick(DialogInterface dialog, int item) {
               String language = itemValues[item].toString();
               storeLanguage(language, MetaDB.LANGUAGES_QA_UNDEFINED);
               lookupLeo(language, mLookupText);
               mLookupText = "";
             }
           });
       StyledDialog alert = builder.create();
       alert.show();
       return true;
     case DICTIONARY_COLORDICT:
       Intent colordictSearchIntent = new Intent(mDictionaryAction);
       colordictSearchIntent.putExtra("EXTRA_QUERY", text);
       mContext.startActivity(colordictSearchIntent);
       return true;
     case DICTIONARY_FORA:
       Intent foraSearchIntent = new Intent(mDictionaryAction);
       foraSearchIntent.putExtra("HEADWORD", text.trim());
       mContext.startActivity(foraSearchIntent);
       return true;
     case DICTIONARY_NCIKU_WEB:
       Intent ncikuWebIntent =
           new Intent(mDictionaryAction, Uri.parse("http://m.nciku.com/en/entry/?query=" + text));
       mContext.startActivity(ncikuWebIntent);
       return true;
     case DICTIONARY_EIJIRO_WEB:
       Intent eijiroWebIntent =
           new Intent(mDictionaryAction, Uri.parse("http://eow.alc.co.jp/" + text));
       mContext.startActivity(eijiroWebIntent);
       return true;
   }
   return false;
 }
Exemple #11
0
  public static void textToSpeech(String text, long did, int ord, int qa) {
    mTextToSpeak = text;
    mQuestionAnswer = qa;
    mDid = did;
    mOrd = ord;
    Timber.d("ReadText.textToSpeech() method started for string '%s'", text);
    // get the user's existing language preference
    String language = getLanguage(mDid, mOrd, mQuestionAnswer);
    Timber.d("ReadText.textToSpeech() method found language choice '%s'", language);
    // rebuild the language list if it's empty
    if (availableTtsLocales.isEmpty()) {
      buildAvailableLanguages();
    }
    // Check, if stored language is available
    for (int i = 0; i < availableTtsLocales.size(); i++) {
      if (language.equals(NO_TTS)) {
        // user has chosen not to read the text
        return;
      } else if (language.equals(availableTtsLocales.get(i).getISO3Language())) {
        speak(mTextToSpeak, language);
        return;
      }
    }

    // Otherwise ask the user what language they want to use
    Resources res = mReviewer.get().getResources();
    final StyledDialog.Builder builder = new StyledDialog.Builder(mReviewer.get());
    if (availableTtsLocales.size() == 0) {
      // builder.setTitle(res.getString(R.string.no_tts_available_title));
      Timber.w("ReadText.textToSpeech() no TTS languages available");
      builder.setMessage(res.getString(R.string.no_tts_available_message));
      builder.setIcon(R.drawable.ic_dialog_alert);
      builder.setPositiveButton(res.getString(R.string.dialog_ok), null);
    } else {
      ArrayList<CharSequence> dialogItems = new ArrayList<CharSequence>();
      final ArrayList<String> dialogIds = new ArrayList<String>();
      builder.setTitle(R.string.select_locale_title);
      // Add option: "no tts"
      dialogItems.add(res.getString(R.string.tts_no_tts));
      dialogIds.add(NO_TTS);
      for (int i = 0; i < availableTtsLocales.size(); i++) {
        dialogItems.add(availableTtsLocales.get(i).getDisplayName());
        dialogIds.add(availableTtsLocales.get(i).getISO3Language());
      }
      String[] items = new String[dialogItems.size()];
      dialogItems.toArray(items);

      builder.setItems(
          items,
          new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
              String locale = dialogIds.get(which);
              Timber.d("ReadText.textToSpeech() user chose locale '%s'", locale);
              if (!locale.equals(NO_TTS)) {
                speak(mTextToSpeak, locale);
              }
              MetaDB.storeLanguage(mReviewer.get(), mDid, mOrd, mQuestionAnswer, locale);
            }
          });
    }
    // Show the dialog after short delay so that user gets a chance to preview the card
    final Handler handler = new Handler();
    final int delay = 500;
    handler.postDelayed(
        new Runnable() {
          @Override
          public void run() {
            builder.create().show();
          }
        },
        delay);
  }