Merge remote-tracking branch 'origin/master'

This commit is contained in:
Weblate 2017-02-18 19:39:39 +01:00
commit b174f3a3e4
6 changed files with 460 additions and 168 deletions

View file

@ -225,6 +225,13 @@ public class Algorithms {
} }
} }
public static String capitalizeFirstLetter(String s) {
if (s != null && s.length() > 0) {
return Character.toUpperCase(s.charAt(0)) + (s.length() > 1 ? s.substring(1) : "");
} else {
return s;
}
}
public static boolean objectEquals(Object a, Object b) { public static boolean objectEquals(Object a, Object b) {
if (a == null) { if (a == null) {

View file

@ -7,31 +7,11 @@
android:minHeight="@dimen/list_item_height" android:minHeight="@dimen/list_item_height"
android:orientation="vertical"> android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/bg_color">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:src="@drawable/bg_shadow_list_bottom"/>
<View
android:layout_width="match_parent"
android:layout_height="16dp"/>
</FrameLayout>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"> android:orientation="vertical"
android:background="?attr/bg_color">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@ -42,7 +22,7 @@
android:id="@+id/check_local_index" android:id="@+id/check_local_index"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/local_index_check_right_margin" android:layout_marginLeft="@dimen/list_content_padding"
android:layout_marginTop="12dp" android:layout_marginTop="12dp"
android:focusable="false" android:focusable="false"
android:visibility="gone"/> android:visibility="gone"/>
@ -200,8 +180,6 @@
</LinearLayout> </LinearLayout>
</FrameLayout>
<include layout="@layout/list_item_divider"/> <include layout="@layout/list_item_divider"/>
</LinearLayout> </LinearLayout>

View file

@ -9,6 +9,9 @@
3. All your modified/created strings are in the top of the file (to make easier find what\'s translated). 3. All your modified/created strings are in the top of the file (to make easier find what\'s translated).
PLEASE: Have a look at http://code.google.com/p/osmand/wiki/UIConsistency, it may really improve your and our work :-) Thx - Hardy PLEASE: Have a look at http://code.google.com/p/osmand/wiki/UIConsistency, it may really improve your and our work :-) Thx - Hardy
--> -->
<string name="select_gpx_folder">Select GPX folder</string>
<string name="file_can_not_be_moved">File can not be moved.</string>
<string name="shared_string_move">Move</string>
<string name="shared_string_tracks">Tracks</string> <string name="shared_string_tracks">Tracks</string>
<string name="routing_attr_driving_style_name">Driving style</string> <string name="routing_attr_driving_style_name">Driving style</string>
<string name="routing_attr_driving_style_description">Safe, fast or balanced driving</string> <string name="routing_attr_driving_style_description">Safe, fast or balanced driving</string>

View file

@ -34,6 +34,7 @@ public class ContextMenuItem {
private final ContextMenuAdapter.OnIntegerValueChangedListener integerListener; private final ContextMenuAdapter.OnIntegerValueChangedListener integerListener;
private final boolean hideDivider; private final boolean hideDivider;
private final int minHeight; private final int minHeight;
private final int tag;
private ContextMenuItem(@StringRes int titleId, private ContextMenuItem(@StringRes int titleId,
String title, String title,
@ -50,7 +51,8 @@ public class ContextMenuItem {
ContextMenuAdapter.ItemClickListener itemClickListener, ContextMenuAdapter.ItemClickListener itemClickListener,
ContextMenuAdapter.OnIntegerValueChangedListener integerListener, ContextMenuAdapter.OnIntegerValueChangedListener integerListener,
boolean hideDivider, boolean hideDivider,
int minHeight) { int minHeight,
int tag) {
this.titleId = titleId; this.titleId = titleId;
this.title = title; this.title = title;
this.mIcon = icon; this.mIcon = icon;
@ -68,6 +70,7 @@ public class ContextMenuItem {
this.integerListener = integerListener; this.integerListener = integerListener;
this.hideDivider = hideDivider; this.hideDivider = hideDivider;
this.minHeight = minHeight; this.minHeight = minHeight;
this.tag = tag;
} }
@StringRes @StringRes
@ -185,6 +188,10 @@ public class ContextMenuItem {
return minHeight; return minHeight;
} }
public int getTag() {
return tag;
}
public static ItemBuilder createBuilder(String title) { public static ItemBuilder createBuilder(String title) {
return new ItemBuilder().setTitle(title); return new ItemBuilder().setTitle(title);
} }
@ -212,6 +219,7 @@ public class ContextMenuItem {
private boolean mSkipPaintingWithoutColor; private boolean mSkipPaintingWithoutColor;
private boolean mHideDivider; private boolean mHideDivider;
private int mMinHeight; private int mMinHeight;
private int mTag;
public ItemBuilder setTitleId(@StringRes int titleId, @Nullable Context context) { public ItemBuilder setTitleId(@StringRes int titleId, @Nullable Context context) {
this.mTitleId = titleId; this.mTitleId = titleId;
@ -302,10 +310,20 @@ public class ContextMenuItem {
return this; return this;
} }
public int getTag() {
return mTag;
}
public ItemBuilder setTag(int tag) {
this.mTag = tag;
return this;
}
public ContextMenuItem createItem() { public ContextMenuItem createItem() {
return new ContextMenuItem(mTitleId, mTitle, mIcon, mColorRes, mSecondaryIcon, return new ContextMenuItem(mTitleId, mTitle, mIcon, mColorRes, mSecondaryIcon,
mSelected, mProgress, mLayout, mLoading, mIsCategory, mSkipPaintingWithoutColor, mSelected, mProgress, mLayout, mLoading, mIsCategory, mSkipPaintingWithoutColor,
mPosition, mDescription, mItemClickListener, mIntegerListener, mHideDivider, mMinHeight); mPosition, mDescription, mItemClickListener, mIntegerListener, mHideDivider,
mMinHeight, mTag);
} }
} }
} }

View file

@ -0,0 +1,226 @@
package net.osmand.plus;
import net.osmand.IndexConstants;
import net.osmand.plus.GPXUtilities.GPXTrackAnalysis;
import net.osmand.plus.api.SQLiteAPI;
import net.osmand.util.Algorithms;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class GPXDatabase {
private static final String DB_NAME = "gpx_database";
private static final int DB_VERSION = 1;
private static final String GPX_TABLE_NAME = "gpxTable";
private static final String GPX_COL_NAME = "fileName";
private static final String GPX_COL_DIR = "fileDir";
private static final String GPX_COL_TOTAL_DISTANCE = "totalDistance";
private static final String GPX_COL_TOTAL_TRACKS = "totalTracks";
private static final String GPX_COL_START_TIME = "startTime";
private static final String GPX_COL_END_TIME = "endTime";
private static final String GPX_COL_TIME_SPAN = "timeSpan";
private static final String GPX_COL_TIME_MOVING = "timeMoving";
private static final String GPX_COL_TOTAL_DISTANCE_MOVING = "totalDistanceMoving";
private static final String GPX_COL_DIFF_ELEVATION_UP = "diffElevationUp";
private static final String GPX_COL_DIFF_ELEVATION_DOWN = "diffElevationDown";
private static final String GPX_COL_AVG_ELEVATION = "avgElevation";
private static final String GPX_COL_MIN_ELEVATION = "minElevation";
private static final String GPX_COL_MAX_ELEVATION = "maxElevation";
private static final String GPX_COL_MAX_SPEED = "maxSpeed";
private static final String GPX_COL_AVG_SPEED = "avgSpeed";
private static final String GPX_COL_POINTS = "points";
private static final String GPX_COL_WPT_POINTS = "wptPoints";
private static final String GPX_TABLE_CREATE = "CREATE TABLE IF NOT EXISTS " + GPX_TABLE_NAME + " (" +
GPX_COL_NAME + " TEXT, " +
GPX_COL_DIR + " TEXT, " +
GPX_COL_TOTAL_DISTANCE + " double, " +
GPX_COL_TOTAL_TRACKS + " int, " +
GPX_COL_START_TIME + " long, " +
GPX_COL_END_TIME + " long, " +
GPX_COL_TIME_SPAN + " long, " +
GPX_COL_TIME_MOVING + " long, " +
GPX_COL_TOTAL_DISTANCE_MOVING + " double, " +
GPX_COL_DIFF_ELEVATION_UP + " double, " +
GPX_COL_DIFF_ELEVATION_DOWN + " double, " +
GPX_COL_AVG_ELEVATION + " double, " +
GPX_COL_MIN_ELEVATION + " double, " +
GPX_COL_MAX_ELEVATION + " double, " +
GPX_COL_MAX_SPEED + " double, " +
GPX_COL_AVG_SPEED + " double, " +
GPX_COL_POINTS + " int, " +
GPX_COL_WPT_POINTS + " int);";
private OsmandApplication context;
public static class GpxDataItem {
private File file;
private GPXTrackAnalysis analysis;
public GpxDataItem(File file, GPXTrackAnalysis analysis) {
this.file = file;
this.analysis = analysis;
}
public File getFile() {
return file;
}
public GPXTrackAnalysis getAnalysis() {
return analysis;
}
}
public GPXDatabase(OsmandApplication app) {
context = app;
}
private SQLiteAPI.SQLiteConnection openConnection(boolean readonly) {
SQLiteAPI.SQLiteConnection conn = context.getSQLiteAPI().getOrCreateDatabase(DB_NAME, readonly);
if (conn.getVersion() == 0 || DB_VERSION != conn.getVersion()) {
if (readonly) {
conn.close();
conn = context.getSQLiteAPI().getOrCreateDatabase(DB_NAME, readonly);
}
if (conn.getVersion() == 0) {
onCreate(conn);
} else {
onUpgrade(conn, conn.getVersion(), DB_VERSION);
}
conn.setVersion(DB_VERSION);
}
return conn;
}
public void onCreate(SQLiteAPI.SQLiteConnection db) {
db.execSQL(GPX_TABLE_CREATE);
}
public void onUpgrade(SQLiteAPI.SQLiteConnection db, int oldVersion, int newVersion) {
/*
if (newVersion == 2) {
db.execSQL(GPX_TABLE_CREATE);
//...
}
*/
}
public boolean remove(GpxDataItem item) {
SQLiteAPI.SQLiteConnection db = openConnection(false);
if(db != null){
try {
db.execSQL("DELETE FROM " + GPX_TABLE_NAME + " WHERE " + GPX_COL_NAME + " = ?, " + GPX_COL_DIR + " = ?",
new Object[] { item.file.getName(), item.file.getParentFile().getName() });
} finally {
db.close();
}
return true;
}
return false;
}
public boolean add(GpxDataItem item) {
SQLiteAPI.SQLiteConnection db = openConnection(false);
if(db != null){
try {
insert(item, db);
} finally {
db.close();
}
return true;
}
return false;
}
private void insert(GpxDataItem item, SQLiteAPI.SQLiteConnection db) {
String fileName = item.file.getName();
String fileDir = item.file.getParentFile().getName();
GPXTrackAnalysis a = item.getAnalysis();
db.execSQL(
"INSERT INTO " + GPX_TABLE_NAME + " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
new Object[] { fileName, fileDir, a.totalDistance, a.totalTracks, a.startTime, a.endTime,
a.timeSpan, a.timeMoving, a.totalDistanceMoving, a.diffElevationUp, a.diffElevationDown,
a.avgElevation, a.minElevation, a.maxElevation, a.maxSpeed, a.avgSpeed, a.points, a.wptPoints });
}
public List<GpxDataItem> getItems() {
List<GpxDataItem> items = new ArrayList<>();
SQLiteAPI.SQLiteConnection db = openConnection(true);
if(db != null){
try {
SQLiteAPI.SQLiteCursor query = db.rawQuery(
"SELECT " + GPX_COL_NAME + ", " + GPX_COL_DIR + "," + GPX_COL_TOTAL_DISTANCE + ", " +
GPX_COL_TOTAL_TRACKS + ", " + GPX_COL_START_TIME + ", " + GPX_COL_END_TIME + ", " +
GPX_COL_TIME_SPAN + ", " + GPX_COL_TIME_MOVING + ", " + GPX_COL_TOTAL_DISTANCE_MOVING + ", " +
GPX_COL_DIFF_ELEVATION_UP + ", " + GPX_COL_DIFF_ELEVATION_DOWN + ", " + GPX_COL_AVG_ELEVATION + ", " +
GPX_COL_MIN_ELEVATION + ", " + GPX_COL_MAX_ELEVATION + ", " + GPX_COL_MAX_SPEED + ", " +
GPX_COL_AVG_SPEED + ", " + GPX_COL_POINTS + ", " + GPX_COL_WPT_POINTS +
" FROM " + GPX_TABLE_NAME , null);
if (query.moveToFirst()) {
do {
String fileName = query.getString(0);
String fileDir = query.getString(1);
float totalDistance = (float)query.getDouble(2);
int totalTracks = (int)query.getInt(3);
long startTime = query.getLong(4);
long endTime = query.getLong(5);
long timeSpan = query.getLong(6);
long timeMoving = query.getLong(7);
float totalDistanceMoving = (float)query.getDouble(8);
double diffElevationUp = query.getDouble(9);
double diffElevationDown = query.getDouble(10);
double avgElevation = query.getDouble(11);
double minElevation = query.getDouble(12);
double maxElevation = query.getDouble(13);
float maxSpeed = (float)query.getDouble(14);
float avgSpeed = (float)query.getDouble(15);
int points = (int)query.getInt(16);
int wptPoints = (int)query.getInt(17);
GPXTrackAnalysis a = new GPXTrackAnalysis();
a.totalDistance = totalDistance;
a.totalTracks = totalTracks;
a.startTime = startTime;
a.endTime = endTime;
a.timeSpan = timeSpan;
a.timeMoving = timeMoving;
a.totalDistanceMoving = totalDistanceMoving;
a.diffElevationUp = diffElevationUp;
a.diffElevationDown = diffElevationDown;
a.avgElevation = avgElevation;
a.minElevation = minElevation;
a.maxElevation = maxElevation;
a.maxSpeed = maxSpeed;
a.avgSpeed = avgSpeed;
a.points = points;
a.wptPoints = wptPoints;
File dir;
if (!Algorithms.isEmpty(fileDir)) {
dir = new File(context.getAppPath(IndexConstants.GPX_INDEX_DIR), fileDir);
} else {
dir = context.getAppPath(IndexConstants.GPX_INDEX_DIR);
}
GpxDataItem item = new GpxDataItem(new File(dir, fileName), a);
items.add(item);
} while (query.moveToNext());
}
query.close();
} finally {
db.close();
}
}
return items;
}
}

View file

@ -166,6 +166,7 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment {
ImageView icon = (ImageView) currentGpxView.findViewById(R.id.icon); ImageView icon = (ImageView) currentGpxView.findViewById(R.id.icon);
icon.setImageDrawable(app.getIconsCache().getIcon(R.drawable.monitoring_rec_big)); icon.setImageDrawable(app.getIconsCache().getIcon(R.drawable.monitoring_rec_big));
icon.setVisibility(selectionMode && showOnMapMode ? View.GONE : View.VISIBLE);
final boolean light = app.getSettings().isLightContent(); final boolean light = app.getSettings().isLightContent();
SavingTrackHelper sth = app.getSavingTrackHelper(); SavingTrackHelper sth = app.getSavingTrackHelper();
@ -583,6 +584,59 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment {
} }
} }
private void moveGpx(final GpxInfo info) {
final ContextMenuAdapter menuAdapter = new ContextMenuAdapter();
ContextMenuItem.ItemBuilder itemBuilder = new ContextMenuItem.ItemBuilder();
File[] listFiles = app.getAppPath(IndexConstants.GPX_INDEX_DIR).listFiles();
final List<File> dirs = new ArrayList<>();
if (listFiles != null) {
Arrays.sort(listFiles);
for (File f : listFiles) {
if (f.isDirectory() && !info.file.getParentFile().equals(f)) {
dirs.add(f);
}
}
if (!info.file.getParentFile().equals(app.getAppPath(IndexConstants.GPX_INDEX_DIR))) {
dirs.add(0, app.getAppPath(IndexConstants.GPX_INDEX_DIR));
}
int i = 0;
for (File dir: dirs) {
menuAdapter.addItem(itemBuilder.setTitle(Algorithms.capitalizeFirstLetter(dir.getName()))
.setIcon(R.drawable.ic_action_folder_stroke).setTag(i).createItem());
i++;
}
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
final ArrayAdapter<ContextMenuItem> listAdapter =
menuAdapter.createListAdapter(getActivity(), app.getSettings().isLightContent());
builder.setTitle(R.string.select_gpx_folder);
builder.setAdapter(listAdapter, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
ContextMenuItem item = menuAdapter.getItem(which);
int index = item.getTag();
File dir = dirs.get(index);
File dest = new File(dir, info.file.getName());
if (dest.exists()) {
Toast.makeText(app, R.string.file_with_name_already_exists, Toast.LENGTH_LONG).show();
} else {
if (info.file.renameTo(dest)) {
asyncLoader = new LoadGpxTask();
asyncLoader.execute(getActivity());
} else {
Toast.makeText(app, R.string.file_can_not_be_moved, Toast.LENGTH_LONG).show();
}
}
}
});
builder.setNegativeButton(R.string.shared_string_cancel, null);
builder.create().show();
}
}
public class LoadGpxTask extends AsyncTask<Activity, GpxInfo, List<GpxInfo>> { public class LoadGpxTask extends AsyncTask<Activity, GpxInfo, List<GpxInfo>> {
private List<GpxInfo> result; private List<GpxInfo> result;
@ -872,10 +926,7 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment {
if (groupName.length() == 0) { if (groupName.length() == 0) {
groupName = getString(R.string.shared_string_tracks); groupName = getString(R.string.shared_string_tracks);
} }
t.append(Character.toUpperCase(groupName.charAt(0))); t.append(Algorithms.capitalizeFirstLetter(groupName));
if (groupName.length() > 1) {
t.append(groupName.substring(1));
}
boolean light = app.getSettings().isLightContent(); boolean light = app.getSettings().isLightContent();
if (selectionMode) { if (selectionMode) {
@ -1021,6 +1072,15 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment {
} }
}); });
item = optionsMenu.getMenu().add(R.string.shared_string_move).setIcon(iconsCache.getThemedIcon(R.drawable.ic_action_folder_stroke));
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
moveGpx(gpxInfo);
return true;
}
});
item = optionsMenu.getMenu().add(R.string.shared_string_rename) item = optionsMenu.getMenu().add(R.string.shared_string_rename)
.setIcon(iconsCache.getThemedIcon(R.drawable.ic_action_edit_dark)); .setIcon(iconsCache.getThemedIcon(R.drawable.ic_action_edit_dark));
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {