[AND] Refactoring of DowloadUi
|
@ -190,7 +190,7 @@
|
|||
android:theme="@style/MWMMain.NoBar" >
|
||||
</activity>
|
||||
<activity
|
||||
android:name="com.mapswithme.maps.DownloadUI"
|
||||
android:name="com.mapswithme.country.DownloadUI"
|
||||
android:configChanges="orientation|screenLayout|screenSize"
|
||||
android:label="@string/download_maps"
|
||||
android:noHistory="true"
|
||||
|
|
BIN
android/res/drawable-hdpi/ic_about.png
Normal file
After Width: | Height: | Size: 683 B |
BIN
android/res/drawable-hdpi/ic_county_menu.png
Normal file
After Width: | Height: | Size: 268 B |
BIN
android/res/drawable-hdpi/ic_guide_mark.png
Normal file
After Width: | Height: | Size: 633 B |
BIN
android/res/drawable-hdpi/ic_settings.png
Normal file
After Width: | Height: | Size: 456 B |
BIN
android/res/drawable-mdpi/ic_about.png
Normal file
After Width: | Height: | Size: 465 B |
BIN
android/res/drawable-mdpi/ic_county_menu.png
Normal file
After Width: | Height: | Size: 190 B |
BIN
android/res/drawable-mdpi/ic_guide_mark.png
Normal file
After Width: | Height: | Size: 449 B |
BIN
android/res/drawable-mdpi/ic_settings.png
Normal file
After Width: | Height: | Size: 330 B |
BIN
android/res/drawable-xhdpi/ic_about.png
Normal file
After Width: | Height: | Size: 860 B |
BIN
android/res/drawable-xhdpi/ic_county_menu.png
Normal file
After Width: | Height: | Size: 250 B |
BIN
android/res/drawable-xhdpi/ic_guide_mark.png
Normal file
After Width: | Height: | Size: 772 B |
BIN
android/res/drawable-xhdpi/ic_settings.png
Normal file
After Width: | Height: | Size: 471 B |
BIN
android/res/drawable-xxhdpi/ic_about.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
android/res/drawable-xxhdpi/ic_county_menu.png
Normal file
After Width: | Height: | Size: 305 B |
BIN
android/res/drawable-xxhdpi/ic_guide_mark.png
Normal file
After Width: | Height: | Size: 1 KiB |
BIN
android/res/drawable-xxhdpi/ic_settings.png
Normal file
After Width: | Height: | Size: 671 B |
|
@ -1,70 +1,73 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="?android:attr/listPreferredItemHeight"
|
||||
android:paddingLeft="4dp"
|
||||
android:paddingRight="8dp" >
|
||||
android:paddingRight="4dp" >
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/flagOrGuide"
|
||||
android:layout_width="wrap_content"
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:padding="5dip"
|
||||
android:visibility="visible" >
|
||||
android:layout_gravity="center" >
|
||||
|
||||
<!-- Visible by defalut -->
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/country_flag"
|
||||
<FrameLayout
|
||||
android:id="@+id/flagContainer"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:scaleType="center"
|
||||
android:visibility="visible" />
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:padding="5dip"
|
||||
android:visibility="visible" >
|
||||
|
||||
<!-- Invisible by default -->
|
||||
<ImageView
|
||||
android:id="@+id/country_flag"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:scaleType="center"
|
||||
android:src="@drawable/jp" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/guide_available"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:scaleType="center"
|
||||
android:visibility="gone" />
|
||||
</FrameLayout>
|
||||
<!-- Invisible by default -->
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/show_country"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:padding="10dip"
|
||||
android:scaleType="center"
|
||||
android:src="@drawable/goto_map" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_toLeftOf="@+id/show_country"
|
||||
android:layout_toRightOf="@+id/flagOrGuide"
|
||||
android:orientation="vertical" >
|
||||
<ImageView
|
||||
android:id="@+id/guide_available"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|left"
|
||||
android:src="@drawable/ic_guide_mark" />
|
||||
</FrameLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_toLeftOf="@+id/country_menu"
|
||||
android:layout_toRightOf="@id/flagContainer"
|
||||
android:maxLines="2"
|
||||
android:text="Andora Andora Andora Andora"
|
||||
android:textAppearance="@style/Holo.TextAppearance.Large.Light" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/summary"
|
||||
<ImageView
|
||||
android:id="@+id/country_menu"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@style/Holo.TextAppearance.Small.Light" />
|
||||
</LinearLayout>
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:padding="10dip"
|
||||
android:scaleType="center"
|
||||
android:src="@drawable/ic_county_menu" />
|
||||
</RelativeLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
<ProgressBar
|
||||
android:id="@+id/download_progress"
|
||||
style="@style/Holo.ProgressBar.Horizontal.Light"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
android:layout_marginBottom="-2dp"
|
||||
android:max="100"
|
||||
android:padding="0" />
|
||||
|
||||
</FrameLayout>
|
|
@ -1,12 +1,15 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:id="@+id/menuitem_about_dialog"
|
||||
android:title="@string/about"
|
||||
android:icon="@drawable/ic_menu_about"
|
||||
android:showAsAction="ifRoom"/>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||
|
||||
<item android:id="@+id/menuitem_settings_activity"
|
||||
android:title="@string/settings"
|
||||
android:icon="@android:drawable/ic_menu_preferences"
|
||||
android:showAsAction="ifRoom"/>
|
||||
</menu>
|
||||
<item
|
||||
android:id="@+id/menuitem_about_dialog"
|
||||
android:icon="@drawable/ic_about"
|
||||
android:showAsAction="ifRoom"
|
||||
android:title="@string/about"/>
|
||||
<item
|
||||
android:id="@+id/menuitem_settings_activity"
|
||||
android:icon="@drawable/ic_settings"
|
||||
android:showAsAction="ifRoom"
|
||||
android:title="@string/settings"/>
|
||||
|
||||
</menu>
|
628
android/src/com/mapswithme/country/DownloadAdapter.java
Normal file
|
@ -0,0 +1,628 @@
|
|||
package com.mapswithme.country;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.res.Resources;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ListView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.mapswithme.maps.Framework;
|
||||
import com.mapswithme.maps.MWMApplication;
|
||||
import com.mapswithme.maps.MapStorage;
|
||||
import com.mapswithme.maps.MapStorage.Index;
|
||||
import com.mapswithme.maps.R;
|
||||
import com.mapswithme.maps.guides.GuideInfo;
|
||||
import com.mapswithme.util.UiUtils;
|
||||
import com.mapswithme.util.Utils;
|
||||
import com.mapswithme.util.statistics.Statistics;
|
||||
|
||||
/// ListView adapter
|
||||
class DownloadAdapter extends BaseAdapter
|
||||
{
|
||||
/// @name Different row types.
|
||||
//@{
|
||||
private static final int TYPE_GROUP = 0;
|
||||
private static final int TYPE_COUNTRY_GROUP = 1;
|
||||
private static final int TYPE_COUNTRY_IN_PROCESS = 2;
|
||||
private static final int TYPE_COUNTRY_READY = 3;
|
||||
private static final int TYPE_COUNTRY_NOT_DOWNLOADED = 4;
|
||||
private static final int TYPES_COUNT = 5;
|
||||
//@}
|
||||
|
||||
private final LayoutInflater mInflater;
|
||||
private final Activity mContext;
|
||||
|
||||
private int mSlotID = 0;
|
||||
final MapStorage mStorage;
|
||||
|
||||
private final String mPackageName;
|
||||
|
||||
private static class CountryItem
|
||||
{
|
||||
public final String mName;
|
||||
public final Index mCountryIdx;
|
||||
public final String mFlag;
|
||||
|
||||
/// @see constants in MapStorage
|
||||
public int mStatus;
|
||||
|
||||
public CountryItem(MapStorage storage, Index idx)
|
||||
{
|
||||
mCountryIdx = idx;
|
||||
mName = storage.countryName(idx);
|
||||
|
||||
final String flag = storage.countryFlag(idx);
|
||||
// The aapt can't process resources with name "do". Hack with renaming.
|
||||
mFlag = flag.equals("do") ? "do_hack" : flag;
|
||||
|
||||
updateStatus(storage, idx);
|
||||
}
|
||||
|
||||
public void updateStatus(MapStorage storage, Index idx)
|
||||
{
|
||||
if (idx.getCountry() == -1 || (idx.getRegion() == -1 && mFlag.length() == 0))
|
||||
mStatus = MapStorage.GROUP;
|
||||
else if (idx.getRegion() == -1 && storage.countriesCount(idx) > 0)
|
||||
mStatus = MapStorage.COUNTRY;
|
||||
else
|
||||
mStatus = storage.countryStatus(idx);
|
||||
}
|
||||
|
||||
public int getTextColor()
|
||||
{
|
||||
//TODO introduce resources
|
||||
switch (mStatus)
|
||||
{
|
||||
case MapStorage.ON_DISK: return 0xFF00A144;
|
||||
case MapStorage.ON_DISK_OUT_OF_DATE: return 0xFFFF69B4;
|
||||
case MapStorage.NOT_DOWNLOADED: return 0xFF000000;
|
||||
case MapStorage.DOWNLOAD_FAILED: return 0xFFFF0000;
|
||||
case MapStorage.DOWNLOADING: return 0xFF342BB6;
|
||||
case MapStorage.IN_QUEUE: return 0xFF5B94DE;
|
||||
default: return 0xFF000000;
|
||||
}
|
||||
}
|
||||
|
||||
/// Get item type for list view representation;
|
||||
public int getType()
|
||||
{
|
||||
switch (mStatus)
|
||||
{
|
||||
case MapStorage.GROUP: return TYPE_GROUP;
|
||||
case MapStorage.COUNTRY: return TYPE_COUNTRY_GROUP;
|
||||
case MapStorage.NOT_DOWNLOADED: return TYPE_COUNTRY_NOT_DOWNLOADED;
|
||||
|
||||
case MapStorage.ON_DISK:
|
||||
case MapStorage.ON_DISK_OUT_OF_DATE:
|
||||
return TYPE_COUNTRY_READY;
|
||||
|
||||
default : return TYPE_COUNTRY_IN_PROCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Index mIdx = new Index();
|
||||
private DownloadAdapter.CountryItem[] mItems = null;
|
||||
|
||||
private final String m_kb;
|
||||
private final String m_mb;
|
||||
|
||||
private final boolean mHasGoogleStore;
|
||||
|
||||
private final AlertDialog.Builder mAlert;
|
||||
private final DialogInterface.OnClickListener m_alertCancelHandler =
|
||||
new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dlg, int which)
|
||||
{
|
||||
dlg.dismiss();
|
||||
}
|
||||
};
|
||||
|
||||
public DownloadAdapter(Activity context)
|
||||
{
|
||||
final MWMApplication app = (MWMApplication) context.getApplication();
|
||||
mStorage = app.getMapStorage();
|
||||
mPackageName = app.getPackageName();
|
||||
|
||||
mContext = context;
|
||||
mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
|
||||
m_kb = context.getString(R.string.kb);
|
||||
m_mb = context.getString(R.string.mb);
|
||||
|
||||
mAlert = new AlertDialog.Builder(mContext);
|
||||
|
||||
mHasGoogleStore = Utils.hasAnyGoogleStoreInstalled();
|
||||
|
||||
fillList();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// Fill list for current m_group and m_country.
|
||||
private void fillList()
|
||||
{
|
||||
final int count = mStorage.countriesCount(mIdx);
|
||||
if (count > 0)
|
||||
{
|
||||
mItems = new DownloadAdapter.CountryItem[count];
|
||||
for (int i = 0; i < count; ++i)
|
||||
mItems[i] = new CountryItem(mStorage, mIdx.getChild(i));
|
||||
}
|
||||
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
/// Process list item click.
|
||||
public boolean onItemClick(int position)
|
||||
{
|
||||
if (mItems[position].mStatus < 0)
|
||||
{
|
||||
// expand next level
|
||||
mIdx = mIdx.getChild(position);
|
||||
|
||||
fillList();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
processCountry(position);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void showNotEnoughFreeSpaceDialog(String spaceNeeded, String countryName)
|
||||
{
|
||||
new AlertDialog.Builder(mContext)
|
||||
.setMessage(String.format(mContext.getString(R.string.free_space_for_country), spaceNeeded, countryName))
|
||||
.setNegativeButton(mContext.getString(R.string.close), m_alertCancelHandler)
|
||||
.create()
|
||||
.show();
|
||||
}
|
||||
|
||||
private boolean hasFreeSpace(long size)
|
||||
{
|
||||
final MWMApplication app = (MWMApplication) mContext.getApplication();
|
||||
return app.hasFreeSpace(size);
|
||||
}
|
||||
|
||||
private void processCountry(int position)
|
||||
{
|
||||
final Index idx = mIdx.getChild(position);
|
||||
final String name = mItems[position].mName;
|
||||
|
||||
// Get actual status here
|
||||
switch (mStorage.countryStatus(idx))
|
||||
{
|
||||
case MapStorage.ON_DISK:
|
||||
// Confirm deleting
|
||||
mAlert
|
||||
.setTitle(name)
|
||||
.setPositiveButton(R.string.delete, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dlg, int which)
|
||||
{
|
||||
mStorage.deleteCountry(idx);
|
||||
Statistics.INSTANCE.trackCountryDeleted(mContext);
|
||||
dlg.dismiss();
|
||||
}
|
||||
})
|
||||
.setNegativeButton(R.string.cancel, m_alertCancelHandler)
|
||||
.create()
|
||||
.show();
|
||||
break;
|
||||
|
||||
case MapStorage.ON_DISK_OUT_OF_DATE:
|
||||
final long remoteSize = mStorage.countryRemoteSizeInBytes(idx);
|
||||
|
||||
// Update or delete
|
||||
new AlertDialog.Builder(mContext)
|
||||
.setTitle(name)
|
||||
.setPositiveButton(mContext.getString(R.string.update_mb_or_kb, getSizeString(remoteSize)),
|
||||
new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dlg, int which)
|
||||
{
|
||||
if (!hasFreeSpace(remoteSize + MB))
|
||||
showNotEnoughFreeSpaceDialog(getSizeString(remoteSize), name);
|
||||
else
|
||||
{
|
||||
mStorage.downloadCountry(idx);
|
||||
Statistics.INSTANCE.trackCountryUpdate(mContext);
|
||||
}
|
||||
|
||||
dlg.dismiss();
|
||||
}
|
||||
})
|
||||
.setNeutralButton(R.string.delete, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dlg, int which)
|
||||
{
|
||||
mStorage.deleteCountry(idx);
|
||||
Statistics.INSTANCE.trackCountryDeleted(mContext);
|
||||
dlg.dismiss();
|
||||
}
|
||||
})
|
||||
.setNegativeButton(R.string.cancel, m_alertCancelHandler)
|
||||
.create()
|
||||
.show();
|
||||
break;
|
||||
|
||||
case MapStorage.NOT_DOWNLOADED:
|
||||
// Check for available free space
|
||||
final long size = mStorage.countryRemoteSizeInBytes(idx);
|
||||
if (!hasFreeSpace(size + MB))
|
||||
{
|
||||
showNotEnoughFreeSpaceDialog(getSizeString(size), name);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Confirm downloading
|
||||
mAlert
|
||||
.setTitle(name)
|
||||
.setPositiveButton(mContext.getString(R.string.download_mb_or_kb, getSizeString(size)),
|
||||
new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dlg, int which)
|
||||
{
|
||||
mStorage.downloadCountry(idx);
|
||||
Statistics.INSTANCE.trackCountryDownload(mContext);
|
||||
dlg.dismiss();
|
||||
}
|
||||
})
|
||||
.setNegativeButton(R.string.cancel, m_alertCancelHandler)
|
||||
.create()
|
||||
.show();
|
||||
}
|
||||
break;
|
||||
|
||||
case MapStorage.DOWNLOAD_FAILED:
|
||||
// Do not confirm downloading if status is failed, just start it
|
||||
mStorage.downloadCountry(idx);
|
||||
break;
|
||||
|
||||
case MapStorage.DOWNLOADING:
|
||||
// Confirm canceling
|
||||
mAlert
|
||||
.setTitle(name)
|
||||
.setPositiveButton(R.string.cancel_download, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dlg, int which)
|
||||
{
|
||||
mStorage.deleteCountry(idx);
|
||||
dlg.dismiss();
|
||||
}
|
||||
})
|
||||
.setNegativeButton(R.string.do_nothing, m_alertCancelHandler)
|
||||
.create()
|
||||
.show();
|
||||
break;
|
||||
|
||||
case MapStorage.IN_QUEUE:
|
||||
// Silently discard country from the queue
|
||||
mStorage.deleteCountry(idx);
|
||||
break;
|
||||
}
|
||||
|
||||
// Actual status will be updated in "updateStatus" callback.
|
||||
}
|
||||
|
||||
private void updateStatuses()
|
||||
{
|
||||
for (int i = 0; i < mItems.length; ++i)
|
||||
{
|
||||
final Index idx = mIdx.getChild(i);
|
||||
|
||||
assert(idx.isValid());
|
||||
if (idx.isValid())
|
||||
mItems[i].updateStatus(mStorage, idx);
|
||||
}
|
||||
}
|
||||
|
||||
/// @name Process routine from parent Activity.
|
||||
//@{
|
||||
/// @return true If "back" was processed.
|
||||
public boolean onBackPressed()
|
||||
{
|
||||
// we are on the root level already - return
|
||||
if (mIdx.isRoot())
|
||||
return false;
|
||||
|
||||
// go to the parent level
|
||||
mIdx = mIdx.getParent();
|
||||
|
||||
fillList();
|
||||
return true;
|
||||
}
|
||||
|
||||
public void onResume(MapStorage.Listener listener)
|
||||
{
|
||||
if (mSlotID == 0)
|
||||
mSlotID = mStorage.subscribe(listener);
|
||||
|
||||
// update actual statuses for items after resuming activity
|
||||
updateStatuses();
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void onPause()
|
||||
{
|
||||
if (mSlotID != 0)
|
||||
{
|
||||
mStorage.unsubscribe(mSlotID);
|
||||
mSlotID = 0;
|
||||
}
|
||||
}
|
||||
//@}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position)
|
||||
{
|
||||
return mItems[position].getType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getViewTypeCount()
|
||||
{
|
||||
return TYPES_COUNT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount()
|
||||
{
|
||||
return (mItems != null ? mItems.length : 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DownloadAdapter.CountryItem getItem(int position)
|
||||
{
|
||||
return mItems[position];
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position)
|
||||
{
|
||||
return position;
|
||||
}
|
||||
|
||||
private static class ViewHolder
|
||||
{
|
||||
public TextView mName = null;
|
||||
public ImageView mFlag = null;
|
||||
public ImageView mGuide = null;
|
||||
public ProgressBar mProgress = null;
|
||||
public View mCountryMenu = null;
|
||||
|
||||
void initFromView(View v)
|
||||
{
|
||||
mName = (TextView) v.findViewById(R.id.title);
|
||||
mFlag = (ImageView) v.findViewById(R.id.country_flag);
|
||||
mGuide = (ImageView) v.findViewById(R.id.guide_available);
|
||||
mCountryMenu = v.findViewById(R.id.country_menu);
|
||||
mProgress = (ProgressBar) v.findViewById(R.id.download_progress);
|
||||
}
|
||||
}
|
||||
|
||||
/// Process "Map" button click in list view.
|
||||
private class MapClickListener implements OnClickListener
|
||||
{
|
||||
private final int m_position;
|
||||
|
||||
public MapClickListener(int position) { m_position = position; }
|
||||
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
mStorage.showCountry(mIdx.getChild(m_position));
|
||||
|
||||
// close parent activity
|
||||
mContext.finish();
|
||||
}
|
||||
}
|
||||
|
||||
private String formatStringWithSize(int strID, int position)
|
||||
{
|
||||
return mContext.getString(strID, getSizeString(mStorage.countryLocalSizeInBytes(mIdx.getChild(position))));
|
||||
}
|
||||
|
||||
private String getSummary(int position)
|
||||
{
|
||||
int res = 0;
|
||||
|
||||
switch (mItems[position].mStatus)
|
||||
{
|
||||
case MapStorage.ON_DISK:
|
||||
return formatStringWithSize(R.string.downloaded_touch_to_delete, position);
|
||||
|
||||
case MapStorage.ON_DISK_OUT_OF_DATE:
|
||||
return formatStringWithSize(R.string.downloaded_touch_to_update, position);
|
||||
|
||||
case MapStorage.NOT_DOWNLOADED: res = R.string.touch_to_download; break;
|
||||
case MapStorage.DOWNLOAD_FAILED: res = R.string.download_has_failed; break;
|
||||
case MapStorage.DOWNLOADING: res = R.string.downloading; break;
|
||||
case MapStorage.IN_QUEUE: res = R.string.marked_for_downloading; break;
|
||||
default:
|
||||
return "An unknown error occured!";
|
||||
}
|
||||
|
||||
return mContext.getString(res);
|
||||
}
|
||||
|
||||
private void setFlag(int position, ImageView v)
|
||||
{
|
||||
final Resources res = mContext.getResources();
|
||||
|
||||
final String strID = mItems[position].mFlag;
|
||||
final int id = res.getIdentifier(strID, "drawable", mPackageName);
|
||||
if (id > 0)
|
||||
v.setImageDrawable(res.getDrawable(id));
|
||||
else
|
||||
Log.e(DownloadUI.TAG, "Failed to get resource id from: " + strID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent)
|
||||
{
|
||||
DownloadAdapter.ViewHolder holder = null;
|
||||
final int type = getItemViewType(position);
|
||||
|
||||
if (convertView == null)
|
||||
{
|
||||
holder = new ViewHolder();
|
||||
switch (type)
|
||||
{
|
||||
case TYPE_GROUP:
|
||||
convertView = mInflater.inflate(R.layout.download_item_group, null);
|
||||
holder.initFromView(convertView);
|
||||
break;
|
||||
|
||||
case TYPE_COUNTRY_GROUP:
|
||||
convertView = mInflater.inflate(R.layout.download_item_country_group, null);
|
||||
holder.initFromView(convertView);
|
||||
break;
|
||||
|
||||
case TYPE_COUNTRY_IN_PROCESS:
|
||||
case TYPE_COUNTRY_READY:
|
||||
case TYPE_COUNTRY_NOT_DOWNLOADED:
|
||||
convertView = mInflater.inflate(R.layout.download_item_country, null);
|
||||
holder.initFromView(convertView);
|
||||
break;
|
||||
}
|
||||
|
||||
convertView.setTag(holder);
|
||||
}
|
||||
else
|
||||
{
|
||||
holder = (DownloadAdapter.ViewHolder) convertView.getTag();
|
||||
}
|
||||
|
||||
// for everything that has flag: regions + countries
|
||||
if (type != TYPE_GROUP)
|
||||
{
|
||||
setFlag(position, holder.mFlag);
|
||||
|
||||
|
||||
// this part if only for downloadable items
|
||||
if (type != TYPE_COUNTRY_GROUP)
|
||||
{
|
||||
populateForGuide(position, holder);
|
||||
|
||||
if (type == TYPE_COUNTRY_IN_PROCESS)
|
||||
{
|
||||
holder.mProgress.setProgress(0);
|
||||
UiUtils.show(holder.mProgress);
|
||||
}
|
||||
else
|
||||
UiUtils.hide(holder.mProgress);
|
||||
}
|
||||
}
|
||||
setItemText(position, holder);
|
||||
|
||||
return convertView;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void setItemText(int position, DownloadAdapter.ViewHolder holder)
|
||||
{
|
||||
// set texts
|
||||
holder.mName.setText(mItems[position].mName);
|
||||
holder.mName.setTextColor(mItems[position].getTextColor());
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void populateForGuide(int position, DownloadAdapter.ViewHolder holder)
|
||||
{
|
||||
if (mHasGoogleStore)
|
||||
{
|
||||
final CountryItem item = getItem(position);
|
||||
final GuideInfo gi = Framework.getGuideInfoForIndex(item.mCountryIdx);
|
||||
if (gi != null)
|
||||
UiUtils.show(holder.mGuide);
|
||||
else
|
||||
UiUtils.hide(holder.mGuide);
|
||||
}
|
||||
}
|
||||
|
||||
/// Get list item position by index(g, c, r).
|
||||
/// @return -1 If no such item in display list.
|
||||
private int getItemPosition(Index idx)
|
||||
{
|
||||
if (mIdx.isChild(idx))
|
||||
{
|
||||
final int position = idx.getPosition();
|
||||
if (position >= 0 && position < mItems.length)
|
||||
return position;
|
||||
else
|
||||
Log.e(DownloadUI.TAG, "Incorrect item position for: " + idx.toString());
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// @return Current country status (@see MapStorage).
|
||||
public int onCountryStatusChanged(Index idx)
|
||||
{
|
||||
final int position = getItemPosition(idx);
|
||||
if (position != -1)
|
||||
{
|
||||
mItems[position].updateStatus(mStorage, idx);
|
||||
|
||||
// use this hard reset, because of caching different ViewHolders according to item's type
|
||||
notifyDataSetChanged();
|
||||
|
||||
return mItems[position].mStatus;
|
||||
}
|
||||
|
||||
return MapStorage.UNKNOWN;
|
||||
}
|
||||
|
||||
public void onCountryProgress(ListView list, Index idx, long current, long total)
|
||||
{
|
||||
final int position = getItemPosition(idx);
|
||||
if (position != -1)
|
||||
{
|
||||
assert(mItems[position].mStatus == 3);
|
||||
|
||||
// do update only one item's view; don't call notifyDataSetChanged
|
||||
final View v = list.getChildAt(position - list.getFirstVisiblePosition());
|
||||
if (v != null)
|
||||
{
|
||||
final DownloadAdapter.ViewHolder holder = (DownloadAdapter.ViewHolder) v.getTag();
|
||||
holder.mProgress.setProgress((int) (current*100/total));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String getSizeString(long size)
|
||||
{
|
||||
if (size > MB)
|
||||
{
|
||||
// do the correct rounding of MB
|
||||
return (size + 512 * 1024) / MB + " " + m_mb;
|
||||
}
|
||||
else
|
||||
{
|
||||
// get upper bound size for Kb
|
||||
return (size + 1023) / 1024 + " " + m_kb;
|
||||
}
|
||||
}
|
||||
private final static long MB = 1024 * 1024;
|
||||
}
|
156
android/src/com/mapswithme/country/DownloadUI.java
Normal file
|
@ -0,0 +1,156 @@
|
|||
package com.mapswithme.country;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.ListView;
|
||||
|
||||
import com.mapswithme.maps.ContextMenu;
|
||||
import com.mapswithme.maps.MWMActivity;
|
||||
import com.mapswithme.maps.MapStorage;
|
||||
import com.mapswithme.maps.MapStorage.Index;
|
||||
import com.mapswithme.maps.R;
|
||||
import com.mapswithme.maps.base.MapsWithMeBaseListActivity;
|
||||
import com.mapswithme.util.ConnectionState;
|
||||
|
||||
|
||||
public class DownloadUI extends MapsWithMeBaseListActivity implements MapStorage.Listener
|
||||
{
|
||||
static String TAG = "DownloadUI";
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setContentView(R.layout.downloader_list_view);
|
||||
|
||||
setListAdapter(new DownloadAdapter(this));
|
||||
}
|
||||
|
||||
private DownloadAdapter getDA()
|
||||
{
|
||||
return (DownloadAdapter) getListView().getAdapter();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
getDA().onResume(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause()
|
||||
{
|
||||
super.onPause();
|
||||
getDA().onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed()
|
||||
{
|
||||
if (getDA().onBackPressed())
|
||||
{
|
||||
// scroll list view to the top
|
||||
setSelection(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
super.onBackPressed();
|
||||
// Always show map as parent
|
||||
startActivity(new Intent(this, MWMActivity.class));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onListItemClick(ListView l, View v, int position, long id)
|
||||
{
|
||||
super.onListItemClick(l, v, position, id);
|
||||
|
||||
if (getDA().onItemClick(position))
|
||||
{
|
||||
// scroll list view to the top
|
||||
setSelection(0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCountryStatusChanged(final Index idx)
|
||||
{
|
||||
if (getDA().onCountryStatusChanged(idx) == MapStorage.DOWNLOAD_FAILED)
|
||||
{
|
||||
// Show wireless settings page if no connection found.
|
||||
if (ConnectionState.getState(this) == ConnectionState.NOT_CONNECTED)
|
||||
{
|
||||
final DownloadUI activity = this;
|
||||
final String country = getDA().mStorage.countryName(idx);
|
||||
|
||||
runOnUiThread(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
new AlertDialog.Builder(activity)
|
||||
.setCancelable(false)
|
||||
.setMessage(String.format(getString(R.string.download_country_failed), country))
|
||||
.setPositiveButton(getString(R.string.connection_settings), new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dlg, int which)
|
||||
{
|
||||
try
|
||||
{
|
||||
startActivity(new Intent(Settings.ACTION_WIRELESS_SETTINGS));
|
||||
}
|
||||
catch (final Exception ex)
|
||||
{
|
||||
Log.e(TAG, "Can't run activity:" + ex);
|
||||
}
|
||||
|
||||
dlg.dismiss();
|
||||
}
|
||||
})
|
||||
.setNegativeButton(getString(R.string.close), new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dlg, int which)
|
||||
{
|
||||
dlg.dismiss();
|
||||
}
|
||||
})
|
||||
.create()
|
||||
.show();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCountryProgress(Index idx, long current, long total)
|
||||
{
|
||||
getDA().onCountryProgress(getListView(), idx, current, total);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu)
|
||||
{
|
||||
return ContextMenu.onCreateOptionsMenu(this, menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item)
|
||||
{
|
||||
if (ContextMenu.onOptionsItemSelected(this, item))
|
||||
return true;
|
||||
else
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
|
@ -1,789 +0,0 @@
|
|||
package com.mapswithme.maps;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.mapswithme.maps.MapStorage.Index;
|
||||
import com.mapswithme.maps.base.MapsWithMeBaseListActivity;
|
||||
import com.mapswithme.maps.guides.GuideInfo;
|
||||
import com.mapswithme.maps.guides.GuidesUtils;
|
||||
import com.mapswithme.util.ConnectionState;
|
||||
import com.mapswithme.util.UiUtils;
|
||||
import com.mapswithme.util.Utils;
|
||||
import com.mapswithme.util.statistics.Statistics;
|
||||
|
||||
|
||||
public class DownloadUI extends MapsWithMeBaseListActivity implements MapStorage.Listener
|
||||
{
|
||||
private static String TAG = "DownloadUI";
|
||||
|
||||
/// ListView adapter
|
||||
private static class DownloadAdapter extends BaseAdapter
|
||||
{
|
||||
/// @name Different row types.
|
||||
//@{
|
||||
private static final int TYPE_GROUP = 0;
|
||||
private static final int TYPE_COUNTRY_GROUP = 1;
|
||||
private static final int TYPE_COUNTRY_IN_PROCESS = 2;
|
||||
private static final int TYPE_COUNTRY_READY = 3;
|
||||
private static final int TYPES_COUNT = 4;
|
||||
//@}
|
||||
|
||||
private final LayoutInflater m_inflater;
|
||||
private final Activity m_context;
|
||||
|
||||
private int m_slotID = 0;
|
||||
private final MapStorage m_storage;
|
||||
|
||||
private final String m_packageName;
|
||||
|
||||
private static class CountryItem
|
||||
{
|
||||
public final String m_name;
|
||||
public final Index mIdx;
|
||||
public String m_flag;
|
||||
|
||||
/// @see constants in MapStorage
|
||||
public int m_status;
|
||||
|
||||
public CountryItem(MapStorage storage, Index idx)
|
||||
{
|
||||
mIdx = idx;
|
||||
m_name = storage.countryName(idx);
|
||||
m_flag = storage.countryFlag(idx);
|
||||
|
||||
// The aapt can't process resources with name "do". Hack with renaming.
|
||||
if (m_flag.equals("do"))
|
||||
m_flag = "do_hack";
|
||||
|
||||
updateStatus(storage, idx);
|
||||
}
|
||||
|
||||
public void updateStatus(MapStorage storage, Index idx)
|
||||
{
|
||||
if (idx.mCountry == -1 || (idx.mRegion == -1 && m_flag.length() == 0))
|
||||
{
|
||||
// group and not a country
|
||||
m_status = MapStorage.GROUP;
|
||||
}
|
||||
else if (idx.mRegion == -1 && storage.countriesCount(idx) > 0)
|
||||
{
|
||||
// country with grouping
|
||||
m_status = MapStorage.COUNTRY;
|
||||
}
|
||||
else
|
||||
{
|
||||
// country or region without grouping
|
||||
m_status = storage.countryStatus(idx);
|
||||
}
|
||||
}
|
||||
|
||||
public int getTextColor()
|
||||
{
|
||||
//TODO introduce resources
|
||||
switch (m_status)
|
||||
{
|
||||
case MapStorage.ON_DISK: return 0xFF00A144;
|
||||
case MapStorage.ON_DISK_OUT_OF_DATE: return 0xFFFF69B4;
|
||||
case MapStorage.NOT_DOWNLOADED: return 0xFF000000;
|
||||
case MapStorage.DOWNLOAD_FAILED: return 0xFFFF0000;
|
||||
case MapStorage.DOWNLOADING: return 0xFF342BB6;
|
||||
case MapStorage.IN_QUEUE: return 0xFF5B94DE;
|
||||
default: return 0xFF000000;
|
||||
}
|
||||
}
|
||||
|
||||
/// Get item type for list view representation;
|
||||
public int getType()
|
||||
{
|
||||
switch (m_status)
|
||||
{
|
||||
case MapStorage.GROUP: return TYPE_GROUP;
|
||||
case MapStorage.COUNTRY: return TYPE_COUNTRY_GROUP;
|
||||
case MapStorage.ON_DISK:
|
||||
case MapStorage.ON_DISK_OUT_OF_DATE:
|
||||
return TYPE_COUNTRY_READY;
|
||||
default : return TYPE_COUNTRY_IN_PROCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Index m_idx = new Index();
|
||||
private CountryItem[] m_items = null;
|
||||
|
||||
private final String m_kb;
|
||||
private final String m_mb;
|
||||
|
||||
private final boolean mHasGoogleStore;
|
||||
|
||||
private final AlertDialog.Builder m_alert;
|
||||
private final DialogInterface.OnClickListener m_alertCancelHandler =
|
||||
new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dlg, int which)
|
||||
{
|
||||
dlg.dismiss();
|
||||
}
|
||||
};
|
||||
|
||||
public DownloadAdapter(Activity context)
|
||||
{
|
||||
final MWMApplication app = (MWMApplication) context.getApplication();
|
||||
m_storage = app.getMapStorage();
|
||||
m_packageName = app.getPackageName();
|
||||
|
||||
m_context = context;
|
||||
m_inflater = (LayoutInflater) m_context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
|
||||
m_kb = context.getString(R.string.kb);
|
||||
m_mb = context.getString(R.string.mb);
|
||||
|
||||
m_alert = new AlertDialog.Builder(m_context);
|
||||
|
||||
mHasGoogleStore = Utils.hasAnyGoogleStoreInstalled();
|
||||
|
||||
fillList();
|
||||
}
|
||||
|
||||
private final long MB = 1024 * 1024;
|
||||
|
||||
private String getSizeString(long size)
|
||||
{
|
||||
if (size > MB)
|
||||
{
|
||||
// do the correct rounding of MB
|
||||
return (size + 512 * 1024) / MB + " " + m_mb;
|
||||
}
|
||||
else
|
||||
{
|
||||
// get upper bound size for Kb
|
||||
return (size + 1023) / 1024 + " " + m_kb;
|
||||
}
|
||||
}
|
||||
|
||||
/// Fill list for current m_group and m_country.
|
||||
private void fillList()
|
||||
{
|
||||
final int count = m_storage.countriesCount(m_idx);
|
||||
if (count > 0)
|
||||
{
|
||||
m_items = new CountryItem[count];
|
||||
for (int i = 0; i < count; ++i)
|
||||
m_items[i] = new CountryItem(m_storage, m_idx.getChild(i));
|
||||
}
|
||||
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
/// Process list item click.
|
||||
public boolean onItemClick(int position)
|
||||
{
|
||||
if (m_items[position].m_status < 0)
|
||||
{
|
||||
// expand next level
|
||||
m_idx = m_idx.getChild(position);
|
||||
|
||||
fillList();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
processCountry(position);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void showNotEnoughFreeSpaceDialog(String spaceNeeded, String countryName)
|
||||
{
|
||||
new AlertDialog.Builder(m_context)
|
||||
.setMessage(String.format(m_context.getString(R.string.free_space_for_country), spaceNeeded, countryName))
|
||||
.setNegativeButton(m_context.getString(R.string.close), m_alertCancelHandler)
|
||||
.create()
|
||||
.show();
|
||||
}
|
||||
|
||||
private boolean hasFreeSpace(long size)
|
||||
{
|
||||
final MWMApplication app = (MWMApplication) m_context.getApplication();
|
||||
return app.hasFreeSpace(size);
|
||||
}
|
||||
|
||||
private void processCountry(int position)
|
||||
{
|
||||
final Index idx = m_idx.getChild(position);
|
||||
|
||||
final String name = m_items[position].m_name;
|
||||
|
||||
// Get actual status here
|
||||
switch (m_storage.countryStatus(idx))
|
||||
{
|
||||
case MapStorage.ON_DISK:
|
||||
// Confirm deleting
|
||||
m_alert
|
||||
.setTitle(name)
|
||||
.setPositiveButton(R.string.delete, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dlg, int which)
|
||||
{
|
||||
m_storage.deleteCountry(idx);
|
||||
Statistics.INSTANCE.trackCountryDeleted(m_context);
|
||||
dlg.dismiss();
|
||||
}
|
||||
})
|
||||
.setNegativeButton(R.string.cancel, m_alertCancelHandler)
|
||||
.create()
|
||||
.show();
|
||||
break;
|
||||
|
||||
case MapStorage.ON_DISK_OUT_OF_DATE:
|
||||
final long remoteSize = m_storage.countryRemoteSizeInBytes(idx);
|
||||
|
||||
// Update or delete
|
||||
new AlertDialog.Builder(m_context)
|
||||
.setTitle(name)
|
||||
.setPositiveButton(m_context.getString(R.string.update_mb_or_kb, getSizeString(remoteSize)),
|
||||
new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dlg, int which)
|
||||
{
|
||||
if (!hasFreeSpace(remoteSize + MB))
|
||||
showNotEnoughFreeSpaceDialog(getSizeString(remoteSize), name);
|
||||
else
|
||||
{
|
||||
m_storage.downloadCountry(idx);
|
||||
Statistics.INSTANCE.trackCountryUpdate(m_context);
|
||||
}
|
||||
|
||||
dlg.dismiss();
|
||||
}
|
||||
})
|
||||
.setNeutralButton(R.string.delete, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dlg, int which)
|
||||
{
|
||||
m_storage.deleteCountry(idx);
|
||||
Statistics.INSTANCE.trackCountryDeleted(m_context);
|
||||
dlg.dismiss();
|
||||
}
|
||||
})
|
||||
.setNegativeButton(R.string.cancel, m_alertCancelHandler)
|
||||
.create()
|
||||
.show();
|
||||
break;
|
||||
|
||||
case MapStorage.NOT_DOWNLOADED:
|
||||
// Check for available free space
|
||||
final long size = m_storage.countryRemoteSizeInBytes(idx);
|
||||
if (!hasFreeSpace(size + MB))
|
||||
{
|
||||
showNotEnoughFreeSpaceDialog(getSizeString(size), name);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Confirm downloading
|
||||
m_alert
|
||||
.setTitle(name)
|
||||
.setPositiveButton(m_context.getString(R.string.download_mb_or_kb, getSizeString(size)),
|
||||
new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dlg, int which)
|
||||
{
|
||||
m_storage.downloadCountry(idx);
|
||||
Statistics.INSTANCE.trackCountryDownload(m_context);
|
||||
dlg.dismiss();
|
||||
}
|
||||
})
|
||||
.setNegativeButton(R.string.cancel, m_alertCancelHandler)
|
||||
.create()
|
||||
.show();
|
||||
}
|
||||
break;
|
||||
|
||||
case MapStorage.DOWNLOAD_FAILED:
|
||||
// Do not confirm downloading if status is failed, just start it
|
||||
m_storage.downloadCountry(idx);
|
||||
break;
|
||||
|
||||
case MapStorage.DOWNLOADING:
|
||||
// Confirm canceling
|
||||
m_alert
|
||||
.setTitle(name)
|
||||
.setPositiveButton(R.string.cancel_download, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dlg, int which)
|
||||
{
|
||||
m_storage.deleteCountry(idx);
|
||||
dlg.dismiss();
|
||||
}
|
||||
})
|
||||
.setNegativeButton(R.string.do_nothing, m_alertCancelHandler)
|
||||
.create()
|
||||
.show();
|
||||
break;
|
||||
|
||||
case MapStorage.IN_QUEUE:
|
||||
// Silently discard country from the queue
|
||||
m_storage.deleteCountry(idx);
|
||||
break;
|
||||
}
|
||||
|
||||
// Actual status will be updated in "updateStatus" callback.
|
||||
}
|
||||
|
||||
private void updateStatuses()
|
||||
{
|
||||
for (int i = 0; i < m_items.length; ++i)
|
||||
{
|
||||
final Index idx = m_idx.getChild(i);
|
||||
|
||||
assert(idx.isValid());
|
||||
if (idx.isValid())
|
||||
m_items[i].updateStatus(m_storage, idx);
|
||||
}
|
||||
}
|
||||
|
||||
/// @name Process routine from parent Activity.
|
||||
//@{
|
||||
/// @return true If "back" was processed.
|
||||
public boolean onBackPressed()
|
||||
{
|
||||
// we are on the root level already - return
|
||||
if (m_idx.isRoot())
|
||||
return false;
|
||||
|
||||
// go to the parent level
|
||||
m_idx = m_idx.getParent();
|
||||
|
||||
fillList();
|
||||
return true;
|
||||
}
|
||||
|
||||
public void onResume(MapStorage.Listener listener)
|
||||
{
|
||||
if (m_slotID == 0)
|
||||
m_slotID = m_storage.subscribe(listener);
|
||||
|
||||
// update actual statuses for items after resuming activity
|
||||
updateStatuses();
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void onPause()
|
||||
{
|
||||
if (m_slotID != 0)
|
||||
{
|
||||
m_storage.unsubscribe(m_slotID);
|
||||
m_slotID = 0;
|
||||
}
|
||||
}
|
||||
//@}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position)
|
||||
{
|
||||
return m_items[position].getType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getViewTypeCount()
|
||||
{
|
||||
return TYPES_COUNT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount()
|
||||
{
|
||||
return (m_items != null ? m_items.length : 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CountryItem getItem(int position)
|
||||
{
|
||||
return m_items[position];
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position)
|
||||
{
|
||||
return position;
|
||||
}
|
||||
|
||||
private static class ViewHolder
|
||||
{
|
||||
public TextView mName = null;
|
||||
public TextView mSummary = null;
|
||||
public ImageView mFlag = null;
|
||||
public ImageView mMap = null;
|
||||
public ImageView mGuide = null;
|
||||
|
||||
void initFromView(View v)
|
||||
{
|
||||
mName = (TextView) v.findViewById(R.id.title);
|
||||
mSummary = (TextView) v.findViewById(R.id.summary);
|
||||
mFlag = (ImageView) v.findViewById(R.id.country_flag);
|
||||
mMap = (ImageView) v.findViewById(R.id.show_country);
|
||||
mGuide = (ImageView) v.findViewById(R.id.guide_available);
|
||||
}
|
||||
}
|
||||
|
||||
/// Process "Map" button click in list view.
|
||||
private class MapClickListener implements OnClickListener
|
||||
{
|
||||
private final int m_position;
|
||||
|
||||
public MapClickListener(int position) { m_position = position; }
|
||||
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
m_storage.showCountry(m_idx.getChild(m_position));
|
||||
|
||||
// close parent activity
|
||||
m_context.finish();
|
||||
}
|
||||
}
|
||||
|
||||
private String formatStringWithSize(int strID, int position)
|
||||
{
|
||||
return m_context.getString(strID, getSizeString(m_storage.countryLocalSizeInBytes(m_idx.getChild(position))));
|
||||
}
|
||||
|
||||
private String getSummary(int position)
|
||||
{
|
||||
int res = 0;
|
||||
|
||||
switch (m_items[position].m_status)
|
||||
{
|
||||
case MapStorage.ON_DISK:
|
||||
return formatStringWithSize(R.string.downloaded_touch_to_delete, position);
|
||||
|
||||
case MapStorage.ON_DISK_OUT_OF_DATE:
|
||||
return formatStringWithSize(R.string.downloaded_touch_to_update, position);
|
||||
|
||||
case MapStorage.NOT_DOWNLOADED: res = R.string.touch_to_download; break;
|
||||
case MapStorage.DOWNLOAD_FAILED: res = R.string.download_has_failed; break;
|
||||
case MapStorage.DOWNLOADING: res = R.string.downloading; break;
|
||||
case MapStorage.IN_QUEUE: res = R.string.marked_for_downloading; break;
|
||||
default:
|
||||
return "An unknown error occured!";
|
||||
}
|
||||
|
||||
return m_context.getString(res);
|
||||
}
|
||||
|
||||
private void setFlag(int position, ImageView v)
|
||||
{
|
||||
final Resources res = m_context.getResources();
|
||||
|
||||
final String strID = m_items[position].m_flag;
|
||||
final int id = res.getIdentifier(strID, "drawable", m_packageName);
|
||||
if (id > 0)
|
||||
v.setImageDrawable(res.getDrawable(id));
|
||||
else
|
||||
Log.e(TAG, "Failed to get resource id from: " + strID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent)
|
||||
{
|
||||
ViewHolder holder = null;
|
||||
|
||||
if (convertView == null)
|
||||
{
|
||||
holder = new ViewHolder();
|
||||
switch (getItemViewType(position))
|
||||
{
|
||||
case TYPE_GROUP:
|
||||
convertView = m_inflater.inflate(R.layout.download_item_group, null);
|
||||
holder.initFromView(convertView);
|
||||
break;
|
||||
|
||||
case TYPE_COUNTRY_GROUP:
|
||||
convertView = m_inflater.inflate(R.layout.download_item_country_group, null);
|
||||
holder.initFromView(convertView);
|
||||
break;
|
||||
|
||||
case TYPE_COUNTRY_IN_PROCESS:
|
||||
convertView = m_inflater.inflate(R.layout.download_item_country, null);
|
||||
holder.initFromView(convertView);
|
||||
holder.mMap.setVisibility(Button.INVISIBLE);
|
||||
break;
|
||||
|
||||
case TYPE_COUNTRY_READY:
|
||||
convertView = m_inflater.inflate(R.layout.download_item_country, null);
|
||||
holder.initFromView(convertView);
|
||||
break;
|
||||
}
|
||||
|
||||
convertView.setTag(holder);
|
||||
}
|
||||
else
|
||||
{
|
||||
holder = (ViewHolder) convertView.getTag();
|
||||
}
|
||||
|
||||
// set texts
|
||||
holder.mName.setText(m_items[position].m_name);
|
||||
holder.mName.setTextColor(m_items[position].getTextColor());
|
||||
if (holder.mSummary != null)
|
||||
holder.mSummary.setText(getSummary(position));
|
||||
|
||||
// attach to "Map" button if needed
|
||||
if (holder.mMap != null && holder.mMap.getVisibility() == Button.VISIBLE)
|
||||
holder.mMap.setOnClickListener(new MapClickListener(position));
|
||||
|
||||
// flag or guide
|
||||
if (holder.mFlag != null)
|
||||
{
|
||||
if (holder.mGuide != null)
|
||||
UiUtils.hide(holder.mGuide);
|
||||
UiUtils.show(holder.mFlag);
|
||||
setFlag(position, holder.mFlag);
|
||||
}
|
||||
|
||||
if (mHasGoogleStore)
|
||||
{
|
||||
final CountryItem item = getItem(position);
|
||||
if (item.getType() == TYPE_COUNTRY_IN_PROCESS || item.getType() == TYPE_COUNTRY_READY)
|
||||
{
|
||||
final GuideInfo gi = Framework.getGuideInfoForIndex(item.mIdx);
|
||||
if (gi != null)
|
||||
{
|
||||
UiUtils.hide(holder.mFlag);
|
||||
UiUtils.show(holder.mGuide);
|
||||
holder.mGuide.setImageResource(R.drawable.ic_guide);
|
||||
holder.mGuide.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
final String packName = gi.mAppId;
|
||||
if (GuidesUtils.isGuideInstalled(packName, m_context))
|
||||
{
|
||||
final Intent i = m_context.getPackageManager().getLaunchIntentForPackage(packName);
|
||||
m_context.startActivity(i);
|
||||
}
|
||||
else
|
||||
m_context.startActivity(GuidesUtils.getGoogleStoreIntentForPackage(gi.mAppId));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return convertView;
|
||||
}
|
||||
|
||||
/// Get list item position by index(g, c, r).
|
||||
/// @return -1 If no such item in display list.
|
||||
private int getItemPosition(Index idx)
|
||||
{
|
||||
if (m_idx.isChild(idx))
|
||||
{
|
||||
final int position = idx.getPosition();
|
||||
if (position >= 0 && position < m_items.length)
|
||||
return position;
|
||||
else
|
||||
Log.e(TAG, "Incorrect item position for: " + idx.toString());
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// @return Current country status (@see MapStorage).
|
||||
public int onCountryStatusChanged(Index idx)
|
||||
{
|
||||
final int position = getItemPosition(idx);
|
||||
if (position != -1)
|
||||
{
|
||||
m_items[position].updateStatus(m_storage, idx);
|
||||
|
||||
// use this hard reset, because of caching different ViewHolders according to item's type
|
||||
notifyDataSetChanged();
|
||||
|
||||
return m_items[position].m_status;
|
||||
}
|
||||
|
||||
return MapStorage.UNKNOWN;
|
||||
}
|
||||
|
||||
public void onCountryProgress(ListView list, Index idx, long current, long total)
|
||||
{
|
||||
final int position = getItemPosition(idx);
|
||||
if (position != -1)
|
||||
{
|
||||
assert(m_items[position].m_status == 3);
|
||||
|
||||
// do update only one item's view; don't call notifyDataSetChanged
|
||||
final View v = list.getChildAt(position - list.getFirstVisiblePosition());
|
||||
if (v != null)
|
||||
{
|
||||
final ViewHolder holder = (ViewHolder) v.getTag();
|
||||
|
||||
// This function actually is a callback from downloading engine and
|
||||
// when using cached views and holders, summary may be null
|
||||
// because of different ListView context.
|
||||
if (holder != null && holder.mSummary != null)
|
||||
{
|
||||
holder.mSummary.setText(String.format(m_context.getString(R.string.downloading_touch_to_cancel),
|
||||
current * 100 / total));
|
||||
v.invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setContentView(R.layout.downloader_list_view);
|
||||
|
||||
setListAdapter(new DownloadAdapter(this));
|
||||
}
|
||||
|
||||
private DownloadAdapter getDA()
|
||||
{
|
||||
return (DownloadAdapter) getListView().getAdapter();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
getDA().onResume(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause()
|
||||
{
|
||||
super.onPause();
|
||||
getDA().onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed()
|
||||
{
|
||||
if (getDA().onBackPressed())
|
||||
{
|
||||
// scroll list view to the top
|
||||
setSelection(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
super.onBackPressed();
|
||||
// Always show map as parent
|
||||
startActivity(new Intent(this, MWMActivity.class));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onListItemClick(ListView l, View v, int position, long id)
|
||||
{
|
||||
super.onListItemClick(l, v, position, id);
|
||||
|
||||
if (getDA().onItemClick(position))
|
||||
{
|
||||
// scroll list view to the top
|
||||
setSelection(0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCountryStatusChanged(final Index idx)
|
||||
{
|
||||
if (getDA().onCountryStatusChanged(idx) == MapStorage.DOWNLOAD_FAILED)
|
||||
{
|
||||
// Show wireless settings page if no connection found.
|
||||
if (ConnectionState.getState(this) == ConnectionState.NOT_CONNECTED)
|
||||
{
|
||||
final DownloadUI activity = this;
|
||||
final String country = getDA().m_storage.countryName(idx);
|
||||
|
||||
runOnUiThread(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
new AlertDialog.Builder(activity)
|
||||
.setCancelable(false)
|
||||
.setMessage(String.format(getString(R.string.download_country_failed), country))
|
||||
.setPositiveButton(getString(R.string.connection_settings), new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dlg, int which)
|
||||
{
|
||||
try
|
||||
{
|
||||
startActivity(new Intent(Settings.ACTION_WIRELESS_SETTINGS));
|
||||
}
|
||||
catch (final Exception ex)
|
||||
{
|
||||
Log.e(TAG, "Can't run activity:" + ex);
|
||||
}
|
||||
|
||||
dlg.dismiss();
|
||||
}
|
||||
})
|
||||
.setNegativeButton(getString(R.string.close), new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dlg, int which)
|
||||
{
|
||||
dlg.dismiss();
|
||||
}
|
||||
})
|
||||
.create()
|
||||
.show();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCountryProgress(Index idx, long current, long total)
|
||||
{
|
||||
getDA().onCountryProgress(getListView(), idx, current, total);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu)
|
||||
{
|
||||
return ContextMenu.onCreateOptionsMenu(this, menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item)
|
||||
{
|
||||
if (ContextMenu.onOptionsItemSelected(this, item))
|
||||
return true;
|
||||
else
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
|
@ -34,6 +34,7 @@ import android.widget.RelativeLayout;
|
|||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.mapswithme.country.DownloadUI;
|
||||
import com.mapswithme.maps.Framework.OnBalloonListener;
|
||||
import com.mapswithme.maps.MapStorage.Index;
|
||||
import com.mapswithme.maps.api.ParsedMmwRequest;
|
||||
|
|
|
@ -31,26 +31,26 @@ public class MapStorage
|
|||
private static final long serialVersionUID = 1L;
|
||||
|
||||
int mGroup;
|
||||
int mCountry;
|
||||
int mRegion;
|
||||
private int mCountry;
|
||||
private int mRegion;
|
||||
|
||||
public Index()
|
||||
{
|
||||
mGroup = -1;
|
||||
mCountry = -1;
|
||||
mRegion = -1;
|
||||
setCountry(-1);
|
||||
setRegion(-1);
|
||||
}
|
||||
|
||||
public Index(int group, int country, int region)
|
||||
{
|
||||
mGroup = group;
|
||||
mCountry = country;
|
||||
mRegion = region;
|
||||
setCountry(country);
|
||||
setRegion(region);
|
||||
}
|
||||
|
||||
public boolean isRoot()
|
||||
{
|
||||
return (mGroup == -1 && mCountry == -1 && mRegion == -1);
|
||||
return (mGroup == -1 && getCountry() == -1 && getRegion() == -1);
|
||||
}
|
||||
|
||||
public boolean isValid()
|
||||
|
@ -60,14 +60,14 @@ public class MapStorage
|
|||
|
||||
public Index getChild(int position)
|
||||
{
|
||||
final Index ret = new Index(mGroup, mCountry, mRegion);
|
||||
final Index ret = new Index(mGroup, getCountry(), getRegion());
|
||||
|
||||
if (ret.mGroup == -1) ret.mGroup = position;
|
||||
else if (ret.mCountry == -1) ret.mCountry = position;
|
||||
else if (ret.getCountry() == -1) ret.setCountry(position);
|
||||
else
|
||||
{
|
||||
assert(ret.mRegion == -1);
|
||||
ret.mRegion = position;
|
||||
assert(ret.getRegion() == -1);
|
||||
ret.setRegion(position);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -75,10 +75,10 @@ public class MapStorage
|
|||
|
||||
public Index getParent()
|
||||
{
|
||||
final Index ret = new Index(mGroup, mCountry, mRegion);
|
||||
final Index ret = new Index(mGroup, getCountry(), getRegion());
|
||||
|
||||
if (ret.mRegion != -1) ret.mRegion = -1;
|
||||
else if (ret.mCountry != -1) ret.mCountry = -1;
|
||||
if (ret.getRegion() != -1) ret.setRegion(-1);
|
||||
else if (ret.getCountry() != -1) ret.setCountry(-1);
|
||||
else
|
||||
{
|
||||
assert(ret.mGroup != -1);
|
||||
|
@ -90,7 +90,7 @@ public class MapStorage
|
|||
|
||||
public boolean isEqual(Index idx)
|
||||
{
|
||||
return (mGroup == idx.mGroup && mCountry == idx.mCountry && mRegion == idx.mRegion);
|
||||
return (mGroup == idx.mGroup && getCountry() == idx.getCountry() && getRegion() == idx.getRegion());
|
||||
}
|
||||
|
||||
public boolean isChild(Index idx)
|
||||
|
@ -100,15 +100,35 @@ public class MapStorage
|
|||
|
||||
public int getPosition()
|
||||
{
|
||||
if (mRegion != -1) return mRegion;
|
||||
else if (mCountry != -1) return mCountry;
|
||||
if (getRegion() != -1) return getRegion();
|
||||
else if (getCountry() != -1) return getCountry();
|
||||
else return mGroup;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return ("Index(" + mGroup + ", " + mCountry + ", " + mRegion + ")");
|
||||
return ("Index(" + mGroup + ", " + getCountry() + ", " + getRegion() + ")");
|
||||
}
|
||||
|
||||
public int getCountry()
|
||||
{
|
||||
return mCountry;
|
||||
}
|
||||
|
||||
public void setCountry(int mCountry)
|
||||
{
|
||||
this.mCountry = mCountry;
|
||||
}
|
||||
|
||||
public int getRegion()
|
||||
{
|
||||
return mRegion;
|
||||
}
|
||||
|
||||
public void setRegion(int mRegion)
|
||||
{
|
||||
this.mRegion = mRegion;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import android.content.Context;
|
|||
import android.content.Intent;
|
||||
import android.support.v4.app.NotificationCompat;
|
||||
|
||||
import com.mapswithme.maps.DownloadUI;
|
||||
import com.mapswithme.country.DownloadUI;
|
||||
import com.mapswithme.maps.MWMActivity;
|
||||
import com.mapswithme.maps.MapStorage.Index;
|
||||
import com.mapswithme.maps.R;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.mapswithme.maps.guides;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
|
@ -30,4 +31,16 @@ public class GuidesUtils
|
|||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET | Intent.FLAG_ACTIVITY_NO_HISTORY);
|
||||
return intent;
|
||||
}
|
||||
|
||||
public static void openOrDownloadGuide(GuideInfo info, Activity activity)
|
||||
{
|
||||
final String packName = info.mAppId;
|
||||
if (GuidesUtils.isGuideInstalled(packName, activity))
|
||||
{
|
||||
final Intent i = activity.getPackageManager().getLaunchIntentForPackage(packName);
|
||||
activity.startActivity(i);
|
||||
}
|
||||
else
|
||||
activity.startActivity(GuidesUtils.getGoogleStoreIntentForPackage(info.mAppId));
|
||||
}
|
||||
}
|
||||
|
|