diff --git a/OsmAnd-java/src/net/osmand/IndexConstants.java b/OsmAnd-java/src/net/osmand/IndexConstants.java
index 5d41d0a9c7..508f98d4b3 100644
--- a/OsmAnd-java/src/net/osmand/IndexConstants.java
+++ b/OsmAnd-java/src/net/osmand/IndexConstants.java
@@ -54,12 +54,13 @@ public class IndexConstants {
public static final String SRTM_INDEX_DIR = "srtm/"; //$NON-NLS-1$
public static final String ROADS_INDEX_DIR = "roads/"; //$NON-NLS-1$
public static final String WIKI_INDEX_DIR = "wiki/"; //$NON-NLS-1$
+ public static final String WIKIVOYAGE_INDEX_DIR = "wikivoyage/";
public static final String AV_INDEX_DIR = "avnotes/"; //$NON-NLS-1$
public static final String FONT_INDEX_DIR = "fonts/"; //$NON-NLS-1$
public static final String VOICE_INDEX_DIR = "voice/"; //$NON-NLS-1$
public static final String RENDERERS_DIR = "rendering/"; //$NON-NLS-1$
public static final String ROUTING_XML_FILE= "routing.xml";
-
+
public static final String SQLITE_EXT = ".sqlitedb"; //$NON-NLS-1$
public static final String TEMP_SOURCE_TO_LOAD = "temp";
diff --git a/OsmAnd-java/src/net/osmand/util/Algorithms.java b/OsmAnd-java/src/net/osmand/util/Algorithms.java
index 8f1bae7cbf..2f556113be 100644
--- a/OsmAnd-java/src/net/osmand/util/Algorithms.java
+++ b/OsmAnd-java/src/net/osmand/util/Algorithms.java
@@ -6,6 +6,7 @@ import net.osmand.PlatformUtil;
import org.apache.commons.logging.Log;
import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
import java.io.Closeable;
import java.io.EOFException;
import java.io.File;
@@ -26,6 +27,7 @@ import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
+import java.util.zip.GZIPInputStream;
/**
@@ -452,6 +454,18 @@ public class Algorithms {
return responseBody;
}
+ public static String gzipToString(byte[] gzip) throws IOException {
+ GZIPInputStream gzipIs = new GZIPInputStream(new ByteArrayInputStream(gzip));
+ BufferedReader br = new BufferedReader(new InputStreamReader(gzipIs, "UTF-8"));
+ StringBuilder sb = new StringBuilder();
+ String s;
+ while ((s = br.readLine()) != null) {
+ sb.append(s);
+ }
+ br.close();
+ return sb.toString();
+ }
+
public static boolean removeAllFiles(File f) {
if (f == null) {
return false;
diff --git a/OsmAnd/res/layout/fragment_wikivoyage_article_dialog.xml b/OsmAnd/res/layout/fragment_wikivoyage_article_dialog.xml
new file mode 100644
index 0000000000..49836f372f
--- /dev/null
+++ b/OsmAnd/res/layout/fragment_wikivoyage_article_dialog.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/OsmAnd/res/layout/fragment_wikivoyage_explore_dialog.xml b/OsmAnd/res/layout/fragment_wikivoyage_explore_dialog.xml
new file mode 100644
index 0000000000..57dd12bc97
--- /dev/null
+++ b/OsmAnd/res/layout/fragment_wikivoyage_explore_dialog.xml
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/OsmAnd/res/layout/fragment_wikivoyage_search_dialog.xml b/OsmAnd/res/layout/fragment_wikivoyage_search_dialog.xml
new file mode 100644
index 0000000000..5dc1c6fbe0
--- /dev/null
+++ b/OsmAnd/res/layout/fragment_wikivoyage_search_dialog.xml
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/OsmAnd/res/layout/wikivoyage_search_list_item.xml b/OsmAnd/res/layout/wikivoyage_search_list_item.xml
new file mode 100644
index 0000000000..09d3095579
--- /dev/null
+++ b/OsmAnd/res/layout/wikivoyage_search_list_item.xml
@@ -0,0 +1,70 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml
index d623adbf92..89d5e4859e 100644
--- a/OsmAnd/res/values/strings.xml
+++ b/OsmAnd/res/values/strings.xml
@@ -9,6 +9,7 @@
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
-->
+ Travel
Waypoints removed from map markers
Nothing found within the radius:
You can add all of the track\'s waypoints, or select separate categories.
diff --git a/OsmAnd/src/net/osmand/plus/AppInitializer.java b/OsmAnd/src/net/osmand/plus/AppInitializer.java
index 738ab9c61e..56f92ede64 100644
--- a/OsmAnd/src/net/osmand/plus/AppInitializer.java
+++ b/OsmAnd/src/net/osmand/plus/AppInitializer.java
@@ -47,6 +47,7 @@ import net.osmand.plus.voice.CommandPlayer;
import net.osmand.plus.voice.CommandPlayerException;
import net.osmand.plus.voice.MediaCommandPlayerImpl;
import net.osmand.plus.voice.TTSCommandPlayerImpl;
+import net.osmand.plus.wikivoyage.data.WikivoyageDbHelper;
import net.osmand.render.RenderingRulesStorage;
import net.osmand.router.RoutingConfiguration;
import net.osmand.util.Algorithms;
@@ -445,6 +446,7 @@ public class AppInitializer implements IProgress {
app.mapMarkersDbHelper = startupInit(new MapMarkersDbHelper(app), MapMarkersDbHelper.class);
app.mapMarkersHelper = startupInit(new MapMarkersHelper(app), MapMarkersHelper.class);
app.searchUICore = startupInit(new QuickSearchHelper(app), QuickSearchHelper.class);
+ app.wikivoyageDbHelper = startupInit(new WikivoyageDbHelper(app), WikivoyageDbHelper.class);
initOpeningHoursParser();
}
diff --git a/OsmAnd/src/net/osmand/plus/OsmandApplication.java b/OsmAnd/src/net/osmand/plus/OsmandApplication.java
index cdd793c103..dd284ecb20 100644
--- a/OsmAnd/src/net/osmand/plus/OsmandApplication.java
+++ b/OsmAnd/src/net/osmand/plus/OsmandApplication.java
@@ -55,6 +55,7 @@ import net.osmand.plus.resources.ResourceManager;
import net.osmand.plus.routing.RoutingHelper;
import net.osmand.plus.search.QuickSearchHelper;
import net.osmand.plus.voice.CommandPlayer;
+import net.osmand.plus.wikivoyage.data.WikivoyageDbHelper;
import net.osmand.router.RoutingConfiguration;
import net.osmand.search.SearchUICore;
import net.osmand.util.Algorithms;
@@ -117,6 +118,7 @@ public class OsmandApplication extends MultiDexApplication {
OsmandRegions regions;
GeocodingLookupService geocodingLookupService;
QuickSearchHelper searchUICore;
+ WikivoyageDbHelper wikivoyageDbHelper;
RoutingConfiguration.Builder defaultRoutingConfig;
private Locale preferredLocale = null;
@@ -390,6 +392,10 @@ public class OsmandApplication extends MultiDexApplication {
return searchUICore;
}
+ public WikivoyageDbHelper getWikivoyageDbHelper() {
+ return wikivoyageDbHelper;
+ }
+
public CommandPlayer getPlayer() {
return player;
}
diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java
index 958ee82ecd..a61007900f 100644
--- a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java
+++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java
@@ -62,6 +62,8 @@ import net.osmand.plus.views.BaseMapLayer;
import net.osmand.plus.views.MapControlsLayer;
import net.osmand.plus.views.MapTileLayer;
import net.osmand.plus.views.OsmandMapTileView;
+import net.osmand.plus.wikivoyage.WikivoyageExploreDialogFragment;
+import net.osmand.plus.wikivoyage.data.WikivoyageDbHelper;
import net.osmand.router.GeneralRouter;
import org.apache.commons.logging.Log;
@@ -764,6 +766,19 @@ public class MapActivityActions implements DialogProvider {
}).createItem());
}
+ if (WikivoyageDbHelper.isDbFileExists(app)) {
+ optionsMenuHelper.addItem(new ItemBuilder().setTitleId(R.string.shared_string_travel, mapActivity)
+ .setIcon(R.drawable.ic_action_travel)
+ .setListener(new ItemClickListener() {
+ @Override
+ public boolean onContextMenuClick(ArrayAdapter adapter, int itemId, int pos, boolean isChecked, int[] viewCoordinates) {
+ MapActivity.clearPrevActivityIntent();
+ WikivoyageExploreDialogFragment.showInstance(mapActivity.getSupportFragmentManager());
+ return true;
+ }
+ }).createItem());
+ }
+
optionsMenuHelper.addItem(new ContextMenuItem.ItemBuilder().setTitleId(R.string.measurement_tool, mapActivity)
.setIcon(R.drawable.ic_action_ruler)
.setListener(new ContextMenuAdapter.ItemClickListener() {
diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/WikivoyageArticleDialogFragment.java b/OsmAnd/src/net/osmand/plus/wikivoyage/WikivoyageArticleDialogFragment.java
new file mode 100644
index 0000000000..22bdf3850b
--- /dev/null
+++ b/OsmAnd/src/net/osmand/plus/wikivoyage/WikivoyageArticleDialogFragment.java
@@ -0,0 +1,61 @@
+package net.osmand.plus.wikivoyage;
+
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v4.app.FragmentManager;
+import android.support.v7.widget.Toolbar;
+import android.text.Html;
+import android.text.SpannableString;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import net.osmand.plus.R;
+import net.osmand.plus.base.BaseOsmAndDialogFragment;
+import net.osmand.plus.wikivoyage.data.SearchResult;
+import net.osmand.plus.wikivoyage.data.WikivoyageArticle;
+
+public class WikivoyageArticleDialogFragment extends BaseOsmAndDialogFragment {
+
+ public static final String TAG = "WikivoyageArticleDialogFragment";
+
+ private SearchResult searchResult;
+
+ public void setSearchResult(SearchResult searchResult) {
+ this.searchResult = searchResult;
+ }
+
+ @Nullable
+ @Override
+ public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+ final View mainView = inflater.inflate(R.layout.fragment_wikivoyage_article_dialog, container);
+
+ Toolbar toolbar = (Toolbar) mainView.findViewById(R.id.toolbar);
+ toolbar.setNavigationIcon(getContentIcon(R.drawable.ic_arrow_back));
+ toolbar.setNavigationContentDescription(R.string.access_shared_string_navigate_up);
+ toolbar.setNavigationOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ dismiss();
+ }
+ });
+
+ TextView contentTv = (TextView) mainView.findViewById(R.id.content_text_view);
+ WikivoyageArticle article = getMyApplication().getWikivoyageDbHelper().getArticle(searchResult);
+ contentTv.setText(new SpannableString(Html.fromHtml(article.getContent())));
+
+ return mainView;
+ }
+
+ public static boolean showInstance(FragmentManager fm, SearchResult searchResult) {
+ try {
+ WikivoyageArticleDialogFragment fragment = new WikivoyageArticleDialogFragment();
+ fragment.setSearchResult(searchResult);
+ fragment.show(fm, TAG);
+ return true;
+ } catch (RuntimeException e) {
+ return false;
+ }
+ }
+}
diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/WikivoyageExploreDialogFragment.java b/OsmAnd/src/net/osmand/plus/wikivoyage/WikivoyageExploreDialogFragment.java
new file mode 100644
index 0000000000..6d61239c5d
--- /dev/null
+++ b/OsmAnd/src/net/osmand/plus/wikivoyage/WikivoyageExploreDialogFragment.java
@@ -0,0 +1,57 @@
+package net.osmand.plus.wikivoyage;
+
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v4.app.FragmentManager;
+import android.support.v7.widget.Toolbar;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+
+import net.osmand.plus.R;
+import net.osmand.plus.base.BaseOsmAndDialogFragment;
+import net.osmand.plus.wikivoyage.search.WikivoyageSearchDialogFragment;
+
+public class WikivoyageExploreDialogFragment extends BaseOsmAndDialogFragment {
+
+ public static final String TAG = "WikivoyageExploreDialogFragment";
+
+ @Nullable
+ @Override
+ public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+ final View mainView = inflater.inflate(R.layout.fragment_wikivoyage_explore_dialog, container);
+
+ Toolbar toolbar = (Toolbar) mainView.findViewById(R.id.toolbar);
+ toolbar.setNavigationIcon(getContentIcon(R.drawable.ic_arrow_back));
+ toolbar.setNavigationContentDescription(R.string.access_shared_string_navigate_up);
+ toolbar.setNavigationOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ dismiss();
+ }
+ });
+
+ ((ImageView) mainView.findViewById(R.id.search_icon))
+ .setImageDrawable(getContentIcon(R.drawable.ic_action_search_dark));
+
+ mainView.findViewById(R.id.search_button).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ WikivoyageSearchDialogFragment.showInstance(getFragmentManager());
+ }
+ });
+
+ return mainView;
+ }
+
+ public static boolean showInstance(FragmentManager fm) {
+ try {
+ WikivoyageExploreDialogFragment fragment = new WikivoyageExploreDialogFragment();
+ fragment.show(fm, TAG);
+ return true;
+ } catch (RuntimeException e) {
+ return false;
+ }
+ }
+}
diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/data/SearchResult.java b/OsmAnd/src/net/osmand/plus/wikivoyage/data/SearchResult.java
new file mode 100644
index 0000000000..9755fc972d
--- /dev/null
+++ b/OsmAnd/src/net/osmand/plus/wikivoyage/data/SearchResult.java
@@ -0,0 +1,25 @@
+package net.osmand.plus.wikivoyage.data;
+
+public class SearchResult {
+
+ String searchTerm;
+ long cityId;
+ String articleTitle;
+ String lang;
+
+ public String getSearchTerm() {
+ return searchTerm;
+ }
+
+ public long getCityId() {
+ return cityId;
+ }
+
+ public String getArticleTitle() {
+ return articleTitle;
+ }
+
+ public String getLang() {
+ return lang;
+ }
+}
diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/data/WikivoyageArticle.java b/OsmAnd/src/net/osmand/plus/wikivoyage/data/WikivoyageArticle.java
new file mode 100644
index 0000000000..bd2528a08e
--- /dev/null
+++ b/OsmAnd/src/net/osmand/plus/wikivoyage/data/WikivoyageArticle.java
@@ -0,0 +1,62 @@
+package net.osmand.plus.wikivoyage.data;
+
+import net.osmand.plus.GPXUtilities.GPXFile;
+
+public class WikivoyageArticle {
+
+ String id;
+ String title;
+ String content;
+ String isPartOf;
+ double lat;
+ double lon;
+ String imageTitle;
+ GPXFile gpxFile;
+ long cityId;
+ long originalId;
+ String lang;
+
+ public String getId() {
+ return id;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public String getContent() {
+ return content;
+ }
+
+ public String getIsPartOf() {
+ return isPartOf;
+ }
+
+ public double getLat() {
+ return lat;
+ }
+
+ public double getLon() {
+ return lon;
+ }
+
+ public String getImageTitle() {
+ return imageTitle;
+ }
+
+ public GPXFile getGpxFile() {
+ return gpxFile;
+ }
+
+ public long getCityId() {
+ return cityId;
+ }
+
+ public long getOriginalId() {
+ return originalId;
+ }
+
+ public String getLang() {
+ return lang;
+ }
+}
diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/data/WikivoyageDbHelper.java b/OsmAnd/src/net/osmand/plus/wikivoyage/data/WikivoyageDbHelper.java
new file mode 100644
index 0000000000..afa0aec260
--- /dev/null
+++ b/OsmAnd/src/net/osmand/plus/wikivoyage/data/WikivoyageDbHelper.java
@@ -0,0 +1,159 @@
+package net.osmand.plus.wikivoyage.data;
+
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
+import net.osmand.IndexConstants;
+import net.osmand.plus.OsmandApplication;
+import net.osmand.plus.api.SQLiteAPI.SQLiteConnection;
+import net.osmand.plus.api.SQLiteAPI.SQLiteCursor;
+import net.osmand.util.Algorithms;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+public class WikivoyageDbHelper {
+
+ private static final String DB_NAME = "wikivoyage.sqlite";
+
+ private static final String ARTICLES_TABLE_NAME = "wikivoyage_articles";
+ private static final String ARTICLES_COL_ID = "article_id";
+ private static final String ARTICLES_COL_TITLE = "title";
+ private static final String ARTICLES_COL_CONTENT = "content_gz";
+ private static final String ARTICLES_COL_IS_PART_OF = "is_part_of";
+ private static final String ARTICLES_COL_LAT = "lat";
+ private static final String ARTICLES_COL_LON = "lon";
+ private static final String ARTICLES_COL_IMAGE_TITLE = "image_title";
+ private static final String ARTICLES_COL_GPX_GZ = "gpx_gz";
+ private static final String ARTICLES_COL_CITY_ID = "city_id";
+ private static final String ARTICLES_COL_ORIGINAL_ID = "original_id";
+ private static final String ARTICLES_COL_LANG = "lang";
+
+ private static final String ARTICLES_TABLE_SELECT = "SELECT " +
+ ARTICLES_COL_ID + ", " +
+ ARTICLES_COL_TITLE + ", " +
+ ARTICLES_COL_CONTENT + ", " +
+ ARTICLES_COL_IS_PART_OF + ", " +
+ ARTICLES_COL_LAT + ", " +
+ ARTICLES_COL_LON + ", " +
+ ARTICLES_COL_IMAGE_TITLE + ", " +
+ ARTICLES_COL_GPX_GZ + ", " +
+ ARTICLES_COL_CITY_ID + ", " +
+ ARTICLES_COL_ORIGINAL_ID + ", " +
+ ARTICLES_COL_LANG +
+ " FROM " + ARTICLES_TABLE_NAME;
+
+ private static final String SEARCH_TABLE_NAME = "wikivoyage_search";
+ private static final String SEARCH_COL_SEARCH_TERM = "search_term";
+ private static final String SEARCH_COL_CITY_ID = "city_id";
+ private static final String SEARCH_COL_ARTICLE_TITLE = "article_title";
+ private static final String SEARCH_COL_LANG = "lang";
+
+ private static final String SEARCH_TABLE_SELECT = "SELECT " +
+ SEARCH_COL_SEARCH_TERM + ", " +
+ SEARCH_COL_CITY_ID + ", " +
+ SEARCH_COL_ARTICLE_TITLE + ", " +
+ SEARCH_COL_LANG +
+ " FROM " + SEARCH_TABLE_NAME;
+
+ private final OsmandApplication application;
+
+ public WikivoyageDbHelper(OsmandApplication application) {
+ this.application = application;
+ }
+
+ @NonNull
+ public List search(String searchQuery) {
+ List res = new ArrayList<>();
+ SQLiteConnection conn = openConnection();
+ if (conn != null) {
+ try {
+ String dbQuery = SEARCH_TABLE_SELECT + " WHERE " + SEARCH_COL_SEARCH_TERM + " LIKE ?";
+ SQLiteCursor cursor = conn.rawQuery(dbQuery, new String[]{"%" + searchQuery + "%"});
+ if (cursor.moveToFirst()) {
+ do {
+ res.add(readSearchResult(cursor));
+ } while (cursor.moveToNext());
+ }
+ cursor.close();
+ } finally {
+ conn.close();
+ }
+ }
+ return res;
+ }
+
+ @Nullable
+ public WikivoyageArticle getArticle(SearchResult searchResult) {
+ WikivoyageArticle res = null;
+ SQLiteConnection conn = openConnection();
+ if (conn != null) {
+ try {
+ SQLiteCursor cursor = conn.rawQuery(ARTICLES_TABLE_SELECT + " WHERE " +
+ ARTICLES_COL_CITY_ID + " = ? AND " +
+ ARTICLES_COL_TITLE + " = ? AND " +
+ ARTICLES_COL_LANG + " = ?",
+ new String[]{String.valueOf(searchResult.cityId), searchResult.articleTitle, searchResult.lang});
+ if (cursor.moveToFirst()) {
+ res = readArticle(cursor);
+ }
+ cursor.close();
+ } finally {
+ conn.close();
+ }
+ }
+ return res;
+ }
+
+ @Nullable
+ private SQLiteConnection openConnection() {
+ String path = getDbFile(application).getAbsolutePath();
+ return application.getSQLiteAPI().openByAbsolutePath(path, true);
+ }
+
+ @NonNull
+ private SearchResult readSearchResult(SQLiteCursor cursor) {
+ SearchResult res = new SearchResult();
+
+ res.searchTerm = cursor.getString(0);
+ res.cityId = cursor.getLong(1);
+ res.articleTitle = cursor.getString(2);
+ res.lang = cursor.getString(3);
+
+ return res;
+ }
+
+ @NonNull
+ private WikivoyageArticle readArticle(SQLiteCursor cursor) {
+ WikivoyageArticle res = new WikivoyageArticle();
+
+ res.id = cursor.getString(0);
+ res.title = cursor.getString(1);
+ try {
+ res.content = Algorithms.gzipToString(cursor.getBlob(2));
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ res.isPartOf = cursor.getString(3);
+ res.lat = cursor.getDouble(4);
+ res.lon = cursor.getDouble(5);
+ res.imageTitle = cursor.getString(6);
+ byte[] gpxFileBlob = cursor.getBlob(7);
+ res.cityId = cursor.getLong(8);
+ res.originalId = cursor.getLong(9);
+ res.lang = cursor.getString(10);
+
+ return res;
+ }
+
+ public static boolean isDbFileExists(OsmandApplication app) {
+ return getDbFile(app).exists();
+ }
+
+ @NonNull
+ private static File getDbFile(OsmandApplication app) {
+ return app.getAppPath(IndexConstants.WIKIVOYAGE_INDEX_DIR + DB_NAME);
+ }
+}
diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/search/SearchRecyclerViewAdapter.java b/OsmAnd/src/net/osmand/plus/wikivoyage/search/SearchRecyclerViewAdapter.java
new file mode 100644
index 0000000000..6cfa787cf7
--- /dev/null
+++ b/OsmAnd/src/net/osmand/plus/wikivoyage/search/SearchRecyclerViewAdapter.java
@@ -0,0 +1,71 @@
+package net.osmand.plus.wikivoyage.search;
+
+import android.support.v7.widget.RecyclerView;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import net.osmand.plus.R;
+import net.osmand.plus.wikivoyage.data.SearchResult;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class SearchRecyclerViewAdapter extends RecyclerView.Adapter {
+
+ private List items = new ArrayList<>();
+
+ private View.OnClickListener onItemClickListener;
+
+ public void setOnItemClickListener(View.OnClickListener onItemClickListener) {
+ this.onItemClickListener = onItemClickListener;
+ }
+
+ @Override
+ public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
+ View itemView = LayoutInflater.from(viewGroup.getContext())
+ .inflate(R.layout.wikivoyage_search_list_item, viewGroup, false);
+ itemView.setOnClickListener(onItemClickListener);
+ return new ViewHolder(itemView);
+ }
+
+ @Override
+ public void onBindViewHolder(ViewHolder viewHolder, int i) {
+ SearchResult item = items.get(i);
+ viewHolder.searchTerm.setText(item.getSearchTerm());
+ viewHolder.cityId.setText(String.valueOf(item.getCityId()));
+ viewHolder.articleTitle.setText(item.getArticleTitle());
+ viewHolder.lang.setText(item.getLang());
+ }
+
+ @Override
+ public int getItemCount() {
+ return items.size();
+ }
+
+ public SearchResult getItem(int pos) {
+ return items.get(pos);
+ }
+
+ public void setItems(List items) {
+ this.items = items;
+ notifyDataSetChanged();
+ }
+
+ static class ViewHolder extends RecyclerView.ViewHolder {
+
+ final TextView searchTerm;
+ final TextView cityId;
+ final TextView articleTitle;
+ final TextView lang;
+
+ public ViewHolder(View itemView) {
+ super(itemView);
+ searchTerm = (TextView) itemView.findViewById(R.id.search_term);
+ cityId = (TextView) itemView.findViewById(R.id.city_id);
+ articleTitle = (TextView) itemView.findViewById(R.id.article_title);
+ lang = (TextView) itemView.findViewById(R.id.lang);
+ }
+ }
+}
diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/search/WikivoyageSearchDialogFragment.java b/OsmAnd/src/net/osmand/plus/wikivoyage/search/WikivoyageSearchDialogFragment.java
new file mode 100644
index 0000000000..311a271c95
--- /dev/null
+++ b/OsmAnd/src/net/osmand/plus/wikivoyage/search/WikivoyageSearchDialogFragment.java
@@ -0,0 +1,100 @@
+package net.osmand.plus.wikivoyage.search;
+
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v4.app.FragmentManager;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.Toolbar;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.inputmethod.EditorInfo;
+import android.widget.EditText;
+import android.widget.ImageButton;
+import android.widget.TextView;
+
+import net.osmand.plus.R;
+import net.osmand.plus.base.BaseOsmAndDialogFragment;
+import net.osmand.plus.wikivoyage.WikivoyageArticleDialogFragment;
+import net.osmand.plus.wikivoyage.data.WikivoyageDbHelper;
+
+public class WikivoyageSearchDialogFragment extends BaseOsmAndDialogFragment {
+
+ public static final String TAG = "WikivoyageSearchDialogFragment";
+
+ private WikivoyageDbHelper dbHelper;
+
+ private SearchRecyclerViewAdapter adapter;
+ private EditText searchEt;
+
+ @Nullable
+ @Override
+ public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+ dbHelper = getMyApplication().getWikivoyageDbHelper();
+
+ final View mainView = inflater.inflate(R.layout.fragment_wikivoyage_search_dialog, container);
+
+ Toolbar toolbar = (Toolbar) mainView.findViewById(R.id.toolbar);
+ toolbar.setNavigationIcon(getContentIcon(R.drawable.ic_arrow_back));
+ toolbar.setNavigationContentDescription(R.string.access_shared_string_navigate_up);
+ toolbar.setNavigationOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ dismiss();
+ }
+ });
+
+ searchEt = (EditText) toolbar.findViewById(R.id.search_edit_text);
+ searchEt.setOnEditorActionListener(new TextView.OnEditorActionListener() {
+ @Override
+ public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
+ if (actionId == EditorInfo.IME_ACTION_SEARCH) {
+ runSearch();
+ return true;
+ }
+ return false;
+ }
+ });
+
+ ImageButton searchBtn = (ImageButton) mainView.findViewById(R.id.search_button);
+ searchBtn.setImageDrawable(getContentIcon(R.drawable.ic_action_search_dark));
+ searchBtn.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ runSearch();
+ }
+ });
+
+ adapter = new SearchRecyclerViewAdapter();
+ final RecyclerView rv = (RecyclerView) mainView.findViewById(R.id.recycler_view);
+ rv.setLayoutManager(new LinearLayoutManager(getContext()));
+ rv.setAdapter(adapter);
+ adapter.setOnItemClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ int pos = rv.getChildAdapterPosition(v);
+ if (pos != RecyclerView.NO_POSITION) {
+ WikivoyageArticleDialogFragment.showInstance(getFragmentManager(), adapter.getItem(pos));
+ }
+ }
+ });
+
+ return mainView;
+ }
+
+ private void runSearch() {
+ adapter.setItems(dbHelper.search((searchEt).getText().toString()));
+ }
+
+ public static boolean showInstance(FragmentManager fm) {
+ try {
+ WikivoyageSearchDialogFragment fragment = new WikivoyageSearchDialogFragment();
+ fragment.show(fm, TAG);
+ return true;
+ } catch (RuntimeException e) {
+ return false;
+ }
+ }
+}