1// Copyright 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5package org.chromium.chrome.browser.infobar; 6 7import java.util.Arrays; 8import java.util.Collections; 9import java.util.List; 10 11 12/** 13 * A class that keeps the state of the different translation options and 14 * languages. 15 */ 16public class TranslateOptions { 17 18 // This would be an enum but they are not good for mobile. 19 // The checkBoundaries method below needs to be updated if new options are added. 20 private static final int NEVER_LANGUAGE = 0; 21 private static final int NEVER_DOMAIN = 1; 22 private static final int ALWAYS_LANGUAGE = 2; 23 24 private final String[] mAllLanguages; 25 26 // Will reflect the state before the object was ever modified 27 private final boolean[] mOriginalOptions; 28 private final int mOriginalSourceLanguageIndex; 29 private final int mOriginalTargetLanguageIndex; 30 31 private final boolean[] mOptions; 32 private int mSourceLanguageIndex; 33 private int mTargetLanguageIndex; 34 private final boolean mTriggeredFromMenu; 35 36 private TranslateOptions(int sourceLanguageCode, int targetLanguageCode, String[] allLanguages, 37 boolean neverLanguage, boolean neverDomain, boolean alwaysLanguage, 38 boolean triggeredFromMenu, boolean[] originalOptions) { 39 mAllLanguages = allLanguages; 40 mSourceLanguageIndex = sourceLanguageCode; 41 mTargetLanguageIndex = targetLanguageCode; 42 mTriggeredFromMenu = triggeredFromMenu; 43 44 mOptions = new boolean[3]; 45 mOptions[NEVER_LANGUAGE] = neverLanguage; 46 mOptions[NEVER_DOMAIN] = neverDomain; 47 mOptions[ALWAYS_LANGUAGE] = alwaysLanguage; 48 49 50 if (originalOptions == null) { 51 mOriginalOptions = mOptions.clone(); 52 } else { 53 mOriginalOptions = originalOptions.clone(); 54 } 55 56 mOriginalSourceLanguageIndex = mSourceLanguageIndex; 57 mOriginalTargetLanguageIndex = mTargetLanguageIndex; 58 } 59 60 public TranslateOptions(int sourceLanguageCode, int targetLanguageCode, String[] allLanguages, 61 boolean alwaysTranslate, boolean triggeredFromMenu) { 62 this(sourceLanguageCode, targetLanguageCode, allLanguages, false, false, alwaysTranslate, 63 triggeredFromMenu, null); 64 } 65 66 /** 67 * Copy constructor 68 */ 69 public TranslateOptions(TranslateOptions other) { 70 this(other.mSourceLanguageIndex, other.mTargetLanguageIndex, other.mAllLanguages, 71 other.mOptions[NEVER_LANGUAGE], other.mOptions[NEVER_DOMAIN], 72 other.mOptions[ALWAYS_LANGUAGE], other.mTriggeredFromMenu, 73 other.mOriginalOptions); 74 } 75 76 public String sourceLanguage() { 77 if (checkLanguageBoundaries(mSourceLanguageIndex)) 78 return mAllLanguages[mSourceLanguageIndex]; 79 return ""; 80 } 81 82 public String targetLanguage() { 83 if (checkLanguageBoundaries(mTargetLanguageIndex)) 84 return mAllLanguages[mTargetLanguageIndex]; 85 return ""; 86 } 87 88 public int sourceLanguageIndex() { 89 return checkLanguageBoundaries(mSourceLanguageIndex) ? mSourceLanguageIndex : 0; 90 } 91 92 public int targetLanguageIndex() { 93 return checkLanguageBoundaries(mTargetLanguageIndex) ? mTargetLanguageIndex : 0; 94 } 95 96 public boolean triggeredFromMenu() { 97 return mTriggeredFromMenu; 98 } 99 100 public boolean optionsChanged() { 101 return (mSourceLanguageIndex != mOriginalSourceLanguageIndex) || 102 (mTargetLanguageIndex != mOriginalTargetLanguageIndex) || 103 (mOptions[NEVER_LANGUAGE] != mOriginalOptions[NEVER_LANGUAGE]) || 104 (mOptions[NEVER_DOMAIN] != mOriginalOptions[NEVER_DOMAIN]) || 105 (mOptions[ALWAYS_LANGUAGE] != mOriginalOptions[ALWAYS_LANGUAGE]); 106 } 107 108 109 public List<String> allLanguages() { 110 return Collections.unmodifiableList(Arrays.asList(mAllLanguages)); 111 } 112 113 public boolean neverTranslateLanguageState() { 114 return mOptions[NEVER_LANGUAGE]; 115 } 116 117 public boolean alwaysTranslateLanguageState() { 118 return mOptions[ALWAYS_LANGUAGE]; 119 } 120 121 public boolean neverTranslateDomainState() { 122 return mOptions[NEVER_DOMAIN]; 123 } 124 125 public boolean setSourceLanguage(int languageIndex) { 126 boolean canSet = canSetLanguage(languageIndex, mTargetLanguageIndex); 127 if (canSet) { 128 mSourceLanguageIndex = languageIndex; 129 } 130 return canSet; 131 } 132 133 public boolean setTargetLanguage(int languageIndex) { 134 boolean canSet = canSetLanguage(mSourceLanguageIndex, languageIndex); 135 if (canSet) { 136 mTargetLanguageIndex = languageIndex; 137 } 138 return canSet; 139 } 140 141 /** 142 * Sets the new state of never translate domain. 143 * 144 * @return true if the toggling was possible 145 */ 146 public boolean toggleNeverTranslateDomainState(boolean value) { 147 return toggleState(NEVER_DOMAIN, value); 148 } 149 150 /** 151 * Sets the new state of never translate language. 152 * 153 * @return true if the toggling was possible 154 */ 155 public boolean toggleNeverTranslateLanguageState(boolean value) { 156 // Do not toggle if we are activating NeverLanguge but AlwaysTranslate 157 // for a language pair with the same source language is already active. 158 if (mOptions[ALWAYS_LANGUAGE] && value) { 159 return false; 160 } 161 return toggleState(NEVER_LANGUAGE, value); 162 } 163 164 /** 165 * Sets the new state of never translate a language pair. 166 * 167 * @return true if the toggling was possible 168 */ 169 public boolean toggleAlwaysTranslateLanguageState(boolean value) { 170 // Do not toggle if we are activating AlwaysLanguge but NeverLanguage is active already. 171 if (mOptions[NEVER_LANGUAGE] && value) { 172 return false; 173 } 174 return toggleState(ALWAYS_LANGUAGE, value); 175 } 176 177 private boolean toggleState(int element, boolean newValue) { 178 if (!checkElementBoundaries(element)) 179 return false; 180 181 mOptions[element] = newValue; 182 return true; 183 } 184 185 186 private boolean checkLanguageBoundaries(int index) { 187 return index >= 0 && index < mAllLanguages.length; 188 } 189 190 private boolean canSetLanguage(int sourceIndex, int targetIndex) { 191 if (sourceIndex == targetIndex) 192 return false; 193 return checkLanguageBoundaries(sourceIndex) && checkLanguageBoundaries(targetIndex); 194 } 195 196 197 private static boolean checkElementBoundaries(int element) { 198 return element >= NEVER_LANGUAGE && element <= ALWAYS_LANGUAGE; 199 } 200 201 @Override 202 public String toString() { 203 return new StringBuilder() 204 .append(sourceLanguage()) 205 .append(" -> ") 206 .append(targetLanguage()) 207 .append(" - ") 208 .append("Never Language:") 209 .append(mOptions[NEVER_LANGUAGE]) 210 .append(" Always Language:") 211 .append(mOptions[ALWAYS_LANGUAGE]) 212 .append(" Never Domain:") 213 .append(mOptions[NEVER_DOMAIN]) 214 .toString(); 215 } 216} 217