Skip to content

Commit cada961

Browse files
committed
New model manager implementation pt. 4
1 parent d8c2467 commit cada961

17 files changed

Lines changed: 941 additions & 104 deletions

app/src/main/java/nie/translator/rtranslator/Global.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ public enum RTranslatorMode {
7979
}
8080
private ArrayList<CustomLocale> languages = new ArrayList<>();
8181
private ArrayList<CustomLocale> translatorLanguages = new ArrayList<>();
82+
private ArrayList<Translator.MozillaLanguageInfo> mozillaLanguages = new ArrayList<>();
8283
private ArrayList<CustomLocale> ttsLanguages = new ArrayList<>();
8384
private CustomLocale language;
8485
private CustomLocale firstLanguage;
@@ -258,6 +259,16 @@ public ArrayList<CustomLocale> getTranslatorLanguages(final boolean recycleResul
258259
}
259260
}
260261

262+
public ArrayList<Translator.MozillaLanguageInfo> getMozillaLanguages(final boolean recycleResult) {
263+
if (recycleResult && !mozillaLanguages.isEmpty()) {
264+
return mozillaLanguages;
265+
} else {
266+
ArrayList<Translator.MozillaLanguageInfo> languages = Translator.getMozillaLanguagesInfo(this);
267+
mozillaLanguages = languages;
268+
return languages;
269+
}
270+
}
271+
261272
public void getTTSLanguages(final boolean recycleResult, final GetLocalesListListener responseListener){
262273
if(recycleResult && !ttsLanguages.isEmpty()){
263274
responseListener.onSuccess(ttsLanguages);

app/src/main/java/nie/translator/rtranslator/downloader2/DownloadInfo.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ public class DownloadInfo implements Parcelable {
99
protected final String name;
1010
protected final String url;
1111
protected final String destinationPath; //destination folder (should not include the file name)
12-
protected final long size; //size in kb (they are not exact, because this is used only for show the progress)
12+
protected final long size; //size in kb (they are not exact, because this is used only to show the progress)
1313
protected int downloadId = -1;
1414
protected final boolean shouldTestIntegrity;
1515
protected final boolean shouldUnzip;

app/src/main/java/nie/translator/rtranslator/downloader2/DownloadManager.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -160,11 +160,13 @@ private void startAndBindService(){
160160
}
161161

162162
private void stopAndUnbindService(){
163-
//we unbind from the service
164-
context.unbindService(this);
165-
// stop the service
166-
final Intent intent = new Intent(context, DownloaderService.class);
167-
context.stopService(intent);
163+
if (downloaderService != null) {
164+
//we unbind from the service
165+
context.unbindService(this);
166+
// stop the service
167+
final Intent intent = new Intent(context, DownloaderService.class);
168+
context.stopService(intent);
169+
}
168170
}
169171

170172
private boolean areDownloadsRunning(boolean includePaused){

app/src/main/java/nie/translator/rtranslator/settings/ModelManagerFragment.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import android.view.ViewGroup;
1010
import android.widget.Button;
1111
import android.widget.CompoundButton;
12+
import android.widget.ImageView;
1213
import android.widget.RadioGroup;
1314
import android.widget.TextView;
1415

@@ -56,6 +57,7 @@ public class ModelManagerFragment extends Fragment {
5657
private SwitchMaterial switchTranslationDict;
5758
private TextView textRamUsage;
5859
private TextView textRamUsage2;
60+
private ImageView arrowMozilla;
5961

6062

6163
@Override
@@ -82,6 +84,7 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat
8284
switchTranslationDict = view.findViewById(R.id.switchTranslationDict);
8385
textRamUsage = view.findViewById(R.id.textRamUsage);
8486
textRamUsage2 = view.findViewById(R.id.textRamUsage2);
87+
arrowMozilla = view.findViewById(R.id.arrowMozilla);
8588
}
8689

8790
@Override
@@ -157,6 +160,12 @@ public void onActivityCreated(@Nullable Bundle savedInstanceState) {
157160
updateTextRamUsage();
158161

159162
// initialize GUI listeners
163+
arrowMozilla.setOnClickListener(new View.OnClickListener() {
164+
@Override
165+
public void onClick(View v) {
166+
activity.startFragment(SettingsActivity.MOZILLA_MANAGER, null);
167+
}
168+
});
160169
radioGroup.setOnCheckedChangeListener((group, checkedId) -> {
161170
updateRamUsageTranslation();
162171
});
Lines changed: 304 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,304 @@
1+
/*
2+
* Copyright 2016 Luca Martino.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copyFile of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package nie.translator.rtranslator.settings;
18+
19+
import android.app.Application;
20+
import android.view.LayoutInflater;
21+
import android.view.ViewGroup;
22+
23+
import androidx.annotation.NonNull;
24+
import androidx.annotation.Nullable;
25+
import androidx.recyclerview.widget.RecyclerView;
26+
27+
import java.util.ArrayList;
28+
import java.util.Comparator;
29+
30+
import nie.translator.rtranslator.R;
31+
import nie.translator.rtranslator.downloader2.DownloadGroupInfo;
32+
import nie.translator.rtranslator.tools.SortedArrayList;
33+
import nie.translator.rtranslator.tools.gui.ResourceManagerView;
34+
35+
public class MozillaLanguagesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
36+
private enum ItemType {
37+
ITEM_MODEL,
38+
HEADER_INSTALLED,
39+
HEADER_AVAILABLE,
40+
}
41+
public enum ItemTypeExtended {
42+
ITEM_MODEL_INSTALLED,
43+
ITEM_MODEL_AVAILABLE,
44+
HEADER_INSTALLED,
45+
HEADER_AVAILABLE,
46+
}
47+
private final Comparator<ResourceManager> comparator = (o1, o2) -> o1.getTitle() != null && o2.getTitle() != null ? o1.getTitle().compareTo(o2.getTitle()) : 0;
48+
private final SortedArrayList<ResourceManager> modelsInstalled = new SortedArrayList<>(comparator);
49+
private final SortedArrayList<ResourceManager> modelsAvailable = new SortedArrayList<>(comparator);
50+
51+
52+
public MozillaLanguagesAdapter(ArrayList<ResourceManager> modelsInstalled, ArrayList<ResourceManager> modelsAvailable) {
53+
this.modelsInstalled.addAll(modelsInstalled);
54+
this.modelsAvailable.addAll(modelsAvailable);
55+
notifyItemRangeInserted(0, getItemCount()); // + eventual 2 headers
56+
}
57+
58+
@NonNull
59+
@Override
60+
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
61+
if(viewType == ItemType.ITEM_MODEL.ordinal()) {
62+
// Ensure layout parameters are set correctly
63+
ResourceManagerView view = new ResourceManagerView(parent.getContext());
64+
view.setLayoutParams(new ViewGroup.LayoutParams(
65+
ViewGroup.LayoutParams.MATCH_PARENT,
66+
ViewGroup.LayoutParams.WRAP_CONTENT
67+
));
68+
return new ModelHolder(view);
69+
} else if(viewType == ItemType.HEADER_INSTALLED.ordinal()) {
70+
return new HeaderInstalledHolder(LayoutInflater.from(parent.getContext()), parent);
71+
} else if(viewType == ItemType.HEADER_AVAILABLE.ordinal()) {
72+
return new HeaderAvailableHolder(LayoutInflater.from(parent.getContext()), parent);
73+
}
74+
return new ModelHolder(new ResourceManagerView(parent.getContext())); // to not return null
75+
}
76+
77+
@Override
78+
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
79+
ResourceManagerItem item = getItem(position);
80+
if(holder instanceof ModelHolder && item instanceof ResourceManager){
81+
ModelHolder modelHolder = (ModelHolder) holder;
82+
ResourceManager resourceManager = (ResourceManager) item;
83+
modelHolder.setResourceManager(resourceManager);
84+
resourceManager.setView((modelHolder.getView()));
85+
}
86+
}
87+
88+
@Nullable
89+
public ResourceManagerItem getItem(int position){
90+
ComposedIndex composedIndex = getComposedIndex(position);
91+
if(composedIndex != null) {
92+
if(composedIndex.itemType == ItemTypeExtended.HEADER_INSTALLED){
93+
return new ResourceManagerHeaderInstalled();
94+
}
95+
if(composedIndex.itemType == ItemTypeExtended.HEADER_AVAILABLE){
96+
return new ResourceManagerHeaderAvailable();
97+
}
98+
if(composedIndex.itemType == ItemTypeExtended.ITEM_MODEL_INSTALLED){
99+
return modelsInstalled.get(composedIndex.index);
100+
}
101+
if(composedIndex.itemType == ItemTypeExtended.ITEM_MODEL_AVAILABLE){
102+
return modelsAvailable.get(composedIndex.index);
103+
}
104+
}
105+
return null;
106+
}
107+
108+
public int getCompleteIndex(ItemTypeExtended itemType, int index){
109+
int base = 0;
110+
if(itemType == ItemTypeExtended.HEADER_INSTALLED){
111+
if(!modelsInstalled.isEmpty()){
112+
return 0;
113+
}else{
114+
return -1;
115+
}
116+
}
117+
if(itemType == ItemTypeExtended.ITEM_MODEL_INSTALLED){
118+
if(!modelsInstalled.isEmpty()){
119+
return index + 1;
120+
}else{
121+
return -1;
122+
}
123+
}
124+
base = !modelsInstalled.isEmpty() ? modelsInstalled.size() : 0;
125+
if(itemType == ItemTypeExtended.HEADER_AVAILABLE){
126+
if(!modelsAvailable.isEmpty()){
127+
return base;
128+
}
129+
}
130+
base += 1;
131+
if(itemType == ItemTypeExtended.ITEM_MODEL_AVAILABLE){
132+
if(!modelsAvailable.isEmpty()){
133+
return base + index;
134+
}else{
135+
return -1;
136+
}
137+
}
138+
return -1;
139+
}
140+
141+
public ComposedIndex getComposedIndex(int position){
142+
if(position >= 0 && position < getItemCount() && !(modelsInstalled.isEmpty() && modelsAvailable.isEmpty())) {
143+
if (position == 0) {
144+
if (!modelsInstalled.isEmpty()) {
145+
return new ComposedIndex(ItemTypeExtended.HEADER_INSTALLED, 0);
146+
} else {
147+
return new ComposedIndex(ItemTypeExtended.HEADER_AVAILABLE, 0);
148+
}
149+
}
150+
if (!modelsInstalled.isEmpty() && position < modelsInstalled.size() + 1) {
151+
return new ComposedIndex(ItemTypeExtended.ITEM_MODEL_INSTALLED, position-1);
152+
}
153+
if (!modelsInstalled.isEmpty() && position == modelsInstalled.size() + 1) {
154+
return new ComposedIndex(ItemTypeExtended.HEADER_AVAILABLE, 0);
155+
}
156+
int offset = !modelsInstalled.isEmpty() ? position - (modelsInstalled.size() + 1) : position - 1;
157+
if (offset < modelsAvailable.size()) {
158+
return new ComposedIndex(ItemTypeExtended.ITEM_MODEL_AVAILABLE, offset);
159+
}
160+
}
161+
return null;
162+
}
163+
164+
@Override
165+
public int getItemViewType(int position) {
166+
ResourceManagerItem item = getItem(position);
167+
if (item instanceof ResourceManagerHeaderInstalled) {
168+
return ItemType.HEADER_INSTALLED.ordinal();
169+
} else if (item instanceof ResourceManagerHeaderAvailable) {
170+
return ItemType.HEADER_AVAILABLE.ordinal();
171+
} else { //instanceof ResourceManager
172+
return ItemType.ITEM_MODEL.ordinal();
173+
}
174+
}
175+
176+
@Override
177+
public long getItemId(int position) {
178+
return position;
179+
}
180+
181+
@Override
182+
public int getItemCount() {
183+
return (!modelsInstalled.isEmpty() ? modelsInstalled.size() : 0) + (!modelsAvailable.isEmpty() ? modelsAvailable.size() : 0);
184+
}
185+
186+
public void setStatus(DownloadGroupInfo item, ResourceManagerView.State state, int progress) {
187+
setState(item, state, false);
188+
setProgress(item, progress);
189+
}
190+
191+
public void setState(DownloadGroupInfo item, ResourceManagerView.State state, boolean animate){
192+
int indexInstalled = modelsInstalled.indexOf(item);
193+
if(indexInstalled != -1){
194+
modelsInstalled.get(indexInstalled).setState(state, animate);
195+
if(state != ResourceManagerView.State.DOWNLOADED){
196+
// in this case we move the row from modelsInstalled to modelsAvailable
197+
ResourceManager resourceManager = modelsInstalled.remove(indexInstalled);
198+
int newIndex = modelsAvailable.addOrdered(resourceManager);
199+
notifyItemMoved(getCompleteIndex(ItemTypeExtended.ITEM_MODEL_INSTALLED, indexInstalled), getCompleteIndex(ItemTypeExtended.ITEM_MODEL_AVAILABLE, newIndex));
200+
}
201+
return;
202+
}
203+
int indexAvailable = modelsAvailable.indexOf(item);
204+
if(indexAvailable != -1){
205+
modelsAvailable.get(indexAvailable).setState(state, animate);
206+
if(state == ResourceManagerView.State.DOWNLOADED){
207+
// in this case we move the row from modelsAvailable to modelsInstalled
208+
ResourceManager resourceManager = modelsAvailable.remove(indexAvailable);
209+
int newIndex = modelsInstalled.addOrdered(resourceManager);
210+
notifyItemMoved(getCompleteIndex(ItemTypeExtended.ITEM_MODEL_AVAILABLE, indexAvailable), getCompleteIndex(ItemTypeExtended.ITEM_MODEL_INSTALLED, newIndex));
211+
}
212+
}
213+
}
214+
215+
public void setProgress(DownloadGroupInfo item, int progress){
216+
int indexInstalled = modelsInstalled.indexOf(item);
217+
if(indexInstalled != -1){
218+
modelsInstalled.get(indexInstalled).setProgress(progress);
219+
return;
220+
}
221+
int indexAvailable = modelsAvailable.indexOf(item);
222+
if(indexAvailable != -1){
223+
modelsAvailable.get(indexAvailable).setProgress(progress);
224+
}
225+
}
226+
227+
@Override
228+
public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) {
229+
super.onViewRecycled(holder);
230+
if(holder instanceof ModelHolder){
231+
ModelHolder modelHolder = (ModelHolder) holder;
232+
if(modelHolder.getResourceManager() != null) {
233+
modelHolder.getResourceManager().setView(null);
234+
modelHolder.setResourceManager(null);
235+
}
236+
}
237+
}
238+
239+
@Override
240+
public boolean onFailedToRecycleView(@NonNull RecyclerView.ViewHolder holder) {
241+
return super.onFailedToRecycleView(holder);
242+
}
243+
244+
/** The layout for each item in the RecycleView list*/
245+
private static class ModelHolder extends RecyclerView.ViewHolder {
246+
private final ResourceManagerView resourceManagerView;
247+
@Nullable
248+
private ResourceManager resourceManager;
249+
250+
ModelHolder(ResourceManagerView resourceManagerView) {
251+
super(resourceManagerView);
252+
this.resourceManagerView = resourceManagerView;
253+
}
254+
255+
public void setResourceManager(@Nullable ResourceManager resourceManager) {
256+
this.resourceManager = resourceManager;
257+
}
258+
259+
@Nullable
260+
public ResourceManager getResourceManager() {
261+
return resourceManager;
262+
}
263+
264+
public ResourceManagerView getView() {
265+
return resourceManagerView;
266+
}
267+
}
268+
269+
/** The layout for each item in the RecycleView list*/
270+
private static class HeaderInstalledHolder extends RecyclerView.ViewHolder {
271+
HeaderInstalledHolder(LayoutInflater inflater, ViewGroup parent) {
272+
super(inflater.inflate(R.layout.component_row_models_installed, parent, false));
273+
}
274+
}
275+
276+
/** The layout for each item in the RecycleView list*/
277+
private static class HeaderAvailableHolder extends RecyclerView.ViewHolder {
278+
HeaderAvailableHolder(LayoutInflater inflater, ViewGroup parent) {
279+
super(inflater.inflate(R.layout.component_row_models_available, parent, false));
280+
}
281+
}
282+
283+
public interface ResourceManagerItem {
284+
285+
}
286+
287+
public static class ResourceManagerHeaderInstalled implements ResourceManagerItem {
288+
289+
}
290+
291+
public static class ResourceManagerHeaderAvailable implements ResourceManagerItem {
292+
293+
}
294+
295+
public static class ComposedIndex {
296+
public ItemTypeExtended itemType;
297+
public int index;
298+
299+
public ComposedIndex(ItemTypeExtended itemType, int index) {
300+
this.itemType = itemType;
301+
this.index = index;
302+
}
303+
}
304+
}

0 commit comments

Comments
 (0)