commit
9d26310ca0
39 changed files with 2640 additions and 1091 deletions
|
@ -29,7 +29,7 @@ public interface ITileSource {
|
|||
public long getExpirationTimeMillis();
|
||||
|
||||
public int getExpirationTimeMinutes();
|
||||
|
||||
|
||||
public String getReferer();
|
||||
|
||||
public void deleteTiles(String path);
|
||||
|
|
|
@ -1,31 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="20dp">
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="@dimen/title_padding">
|
||||
|
||||
<android.support.v7.widget.SwitchCompat
|
||||
android:id="@+id/switchItem"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/content_padding"
|
||||
android:layout_marginEnd="@dimen/content_padding"
|
||||
android:minHeight="48dp"
|
||||
android:text="@string/shared_string_include_data"
|
||||
android:textSize="@dimen/default_list_text_size"
|
||||
tools:text="@string/shared_string_include_data" />
|
||||
|
||||
<ExpandableListView
|
||||
android:id="@+id/list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:divider="@null"
|
||||
android:dividerHeight="0dp"
|
||||
android:drawSelectorOnTop="false"
|
||||
android:groupIndicator="@android:color/transparent"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
<ExpandableListView
|
||||
android:id="@+id/list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:divider="@null"
|
||||
android:headerDividersEnabled="false"
|
||||
android:dividerHeight="0dp"
|
||||
android:drawSelectorOnTop="false"
|
||||
android:groupIndicator="@android:color/transparent"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</LinearLayout>
|
56
OsmAnd/res/layout/button_with_icon_and_subtext.xml
Normal file
56
OsmAnd/res/layout/button_with_icon_and_subtext.xml
Normal file
|
@ -0,0 +1,56 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:osmand="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="@dimen/dialog_button_ex_height">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/button_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/content_padding_small"
|
||||
android:layout_marginLeft="@dimen/content_padding_small"
|
||||
tools:src="@drawable/ic_action_keep_both" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/content_padding_small"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
osmand:typeface="@string/font_roboto_medium"
|
||||
tools:text="Main text" />
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/sub_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="2"
|
||||
android:textSize="@dimen/default_sub_text_size"
|
||||
osmand:typeface="@string/font_roboto_medium"
|
||||
tools:text="Long subtext about two lines" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</FrameLayout>
|
136
OsmAnd/res/layout/fragment_import.xml
Normal file
136
OsmAnd/res/layout/fragment_import.xml
Normal file
|
@ -0,0 +1,136 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:osmand="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/activity_background_basic"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/toolbar_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/colorPrimary"
|
||||
android:orientation="vertical">
|
||||
|
||||
<android.support.v7.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/toolbar_height"
|
||||
android:minHeight="@dimen/toolbar_height" />
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="@dimen/content_padding"
|
||||
android:paddingTop="@dimen/list_header_settings_top_margin"
|
||||
android:paddingEnd="@dimen/content_padding"
|
||||
android:paddingBottom="@dimen/list_header_settings_top_margin"
|
||||
android:text="@string/shared_string_import"
|
||||
android:textColor="?attr/app_bar_primary_item_color"
|
||||
android:textSize="@dimen/dialog_header_text_size"
|
||||
osmand:typeface="@string/font_roboto_medium" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/bg_color"
|
||||
android:paddingStart="@dimen/content_padding"
|
||||
android:paddingTop="@dimen/list_header_settings_top_margin"
|
||||
android:paddingEnd="@dimen/content_padding"
|
||||
android:paddingBottom="@dimen/list_header_settings_top_margin"
|
||||
android:text="@string/select_data_to_import"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="@dimen/default_list_text_size"
|
||||
osmand:typeface="@string/font_roboto_medium" />
|
||||
|
||||
<include layout="@layout/card_bottom_divider" />
|
||||
|
||||
<ExpandableListView
|
||||
android:id="@+id/list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:divider="@null"
|
||||
android:dividerHeight="0dp"
|
||||
android:drawSelectorOnTop="false"
|
||||
android:groupIndicator="@android:color/transparent"
|
||||
android:listSelector="@android:color/transparent" />
|
||||
|
||||
<include layout="@layout/card_top_divider" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/buttons_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/dialog_button_ex_height"
|
||||
android:background="?attr/bg_color"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal"
|
||||
android:paddingLeft="@dimen/content_padding"
|
||||
android:paddingTop="@dimen/content_padding_small"
|
||||
android:paddingRight="@dimen/content_padding"
|
||||
android:paddingBottom="@dimen/content_padding_small">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1">
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/select_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:ellipsize="end"
|
||||
android:gravity="start|center_vertical"
|
||||
android:maxLines="1"
|
||||
android:paddingLeft="@dimen/content_padding_small"
|
||||
android:paddingTop="@dimen/content_padding_half"
|
||||
android:paddingRight="@dimen/content_padding_small"
|
||||
android:paddingBottom="@dimen/content_padding_half"
|
||||
android:text="@string/shared_string_select_all"
|
||||
android:textColor="?attr/active_color_basic"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
osmand:typeface="@string/font_roboto_medium"
|
||||
tools:text="Select all" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="@dimen/content_padding"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:background="?attr/dlg_btn_primary">
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/continue_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:ellipsize="end"
|
||||
android:gravity="end|center_vertical"
|
||||
android:maxLines="1"
|
||||
android:paddingLeft="@dimen/content_padding_small"
|
||||
android:paddingTop="@dimen/content_padding_half"
|
||||
android:paddingRight="@dimen/content_padding_small"
|
||||
android:paddingBottom="@dimen/content_padding_half"
|
||||
android:text="@string/shared_string_continue"
|
||||
android:textColor="?attr/dlg_btn_primary_text"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
osmand:typeface="@string/font_roboto_medium"
|
||||
tools:text="Continue" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
107
OsmAnd/res/layout/fragment_import_duplicates.xml
Normal file
107
OsmAnd/res/layout/fragment_import_duplicates.xml
Normal file
|
@ -0,0 +1,107 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:osmand="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/activity_background_basic"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/colorPrimary"
|
||||
android:orientation="vertical">
|
||||
|
||||
<android.support.v7.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/toolbar_height"
|
||||
android:minHeight="@dimen/toolbar_height" />
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="@dimen/content_padding"
|
||||
android:paddingTop="@dimen/list_header_settings_top_margin"
|
||||
android:paddingEnd="@dimen/content_padding"
|
||||
android:paddingBottom="@dimen/list_header_settings_top_margin"
|
||||
android:text="@string/import_duplicates_title"
|
||||
android:textColor="?attr/app_bar_primary_item_color"
|
||||
android:textSize="@dimen/dialog_header_text_size"
|
||||
osmand:typeface="@string/font_roboto_medium" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/bg_color"
|
||||
android:paddingStart="@dimen/content_padding"
|
||||
android:paddingTop="@dimen/list_header_settings_top_margin"
|
||||
android:paddingEnd="@dimen/content_padding"
|
||||
android:paddingBottom="@dimen/list_header_settings_top_margin"
|
||||
android:text="@string/import_duplicates_description"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="@dimen/default_list_text_size"
|
||||
osmand:typeface="@string/font_roboto_medium" />
|
||||
|
||||
<include
|
||||
android:id="@+id/description_divider"
|
||||
layout="@layout/card_bottom_divider" />
|
||||
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<include
|
||||
layout="@layout/card_top_divider" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/bg_color"
|
||||
android:orientation="vertical"
|
||||
android:padding="@dimen/content_padding">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/content_padding_half"
|
||||
android:background="?attr/dlg_btn_secondary">
|
||||
|
||||
<net.osmand.view.ComplexButton
|
||||
android:id="@+id/keep_both_btn"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
osmand:setSubText="@string/keep_both_desc"
|
||||
osmand:setSubTextColor="?android:textColorSecondary"
|
||||
osmand:setText="@string/keep_both"
|
||||
osmand:setTextColor="?attr/active_color_basic" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/dlg_btn_primary">
|
||||
|
||||
<net.osmand.view.ComplexButton
|
||||
android:id="@+id/replace_all_btn"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
osmand:setSubText="@string/replace_all_desc"
|
||||
osmand:setSubTextColor="?android:textColorTertiaryInverse"
|
||||
osmand:setText="@string/replace_all"
|
||||
osmand:setTextColor="?attr/dlg_btn_primary_text" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
56
OsmAnd/res/layout/item_header_export_expand_list.xml
Normal file
56
OsmAnd/res/layout/item_header_export_expand_list.xml
Normal file
|
@ -0,0 +1,56 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:animateLayoutChanges="true"
|
||||
android:background="?attr/activity_background_basic"
|
||||
android:orientation="vertical">
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/bg_color"
|
||||
android:letterSpacing="@dimen/text_button_letter_spacing"
|
||||
android:minHeight="@dimen/bottom_sheet_list_item_height"
|
||||
android:paddingLeft="@dimen/content_padding"
|
||||
android:paddingTop="@dimen/content_padding"
|
||||
android:paddingRight="@dimen/content_padding"
|
||||
android:paddingBottom="@dimen/content_padding"
|
||||
android:text="@string/export_profile_dialog_description"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="@dimen/default_list_text_size"
|
||||
app:typeface="@string/font_roboto_regular" />
|
||||
|
||||
<include
|
||||
android:id="@+id/topSwitchDivider"
|
||||
layout="@layout/card_bottom_divider"
|
||||
android:visibility="gone" />
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/bg_color">
|
||||
|
||||
<android.support.v7.widget.SwitchCompat
|
||||
android:id="@+id/switchItem"
|
||||
android:layout_width="match_parent"
|
||||
android:focusable="false"
|
||||
android:focusableInTouchMode="false"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/activity_background_basic"
|
||||
android:minHeight="48dp"
|
||||
android:text="@string/shared_string_include_data"
|
||||
android:textSize="@dimen/default_list_text_size"
|
||||
tools:text="@string/shared_string_include_data" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<include
|
||||
android:id="@+id/bottomSwitchDivider"
|
||||
layout="@layout/divider"
|
||||
android:visibility="gone" />
|
||||
|
||||
</LinearLayout>
|
44
OsmAnd/res/layout/list_item_header_import.xml
Normal file
44
OsmAnd/res/layout/list_item_header_import.xml
Normal file
|
@ -0,0 +1,44 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<include
|
||||
android:id="@+id/top_divider"
|
||||
layout="@layout/card_top_divider"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/bg_color"
|
||||
android:gravity="center_vertical"
|
||||
android:minHeight="66dp"
|
||||
android:orientation="vertical"
|
||||
android:paddingStart="@dimen/content_padding"
|
||||
android:paddingTop="@dimen/list_header_settings_top_margin"
|
||||
android:paddingEnd="@dimen/content_padding"
|
||||
android:paddingBottom="@dimen/list_header_settings_top_margin">
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/preference_category_title"
|
||||
android:textSize="@dimen/default_list_text_size"
|
||||
tools:text="Quick actions" />
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/sub_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
tools:text="Listed quick actions, already exist in OsmAnd." />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
54
OsmAnd/res/layout/list_item_import.xml
Normal file
54
OsmAnd/res/layout/list_item_import.xml
Normal file
|
@ -0,0 +1,54 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/bg_color"
|
||||
android:gravity="center_vertical"
|
||||
android:minHeight="66dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/content_padding"
|
||||
tools:src="@drawable/ic_action_offroad" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="@dimen/default_list_text_size"
|
||||
tools:text="OffRoad" />
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/sub_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
tools:text="Navigation type: Car" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<include
|
||||
android:id="@+id/bottom_divider"
|
||||
layout="@layout/card_bottom_divider"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</LinearLayout>
|
|
@ -1,49 +1,82 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="vertical">
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center_vertical"
|
||||
android:minHeight="66dp">
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/bg_color">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/content_padding"
|
||||
tools:src="@drawable/ic_action_info_dark" />
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:gravity="center_vertical"
|
||||
android:minHeight="66dp">
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/title_tv"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="@dimen/default_list_text_size"
|
||||
tools:text="Quick actions" />
|
||||
<ImageView
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/content_padding"
|
||||
tools:src="@drawable/ic_action_info_dark" />
|
||||
|
||||
<android.support.v7.widget.AppCompatCheckBox
|
||||
android:id="@+id/check_box"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/content_padding"
|
||||
android:layout_marginEnd="@dimen/content_padding"
|
||||
android:focusable="false" />
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
</LinearLayout>
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/title_tv"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="@dimen/default_list_text_size"
|
||||
tools:text="Quick actions" />
|
||||
|
||||
<View
|
||||
android:id="@+id/divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="?attr/list_divider"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/sub_title_tv"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
android:visibility="gone"
|
||||
tools:text="description"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<android.support.v7.widget.AppCompatCheckBox
|
||||
android:id="@+id/check_box"
|
||||
android:layout_width="wrap_content"
|
||||
android:focusableInTouchMode="false"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/content_padding"
|
||||
android:layout_marginEnd="@dimen/content_padding"
|
||||
android:focusable="false" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<View
|
||||
android:id="@+id/divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="?attr/list_divider"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<include
|
||||
android:id="@+id/card_bottom_divider"
|
||||
layout="@layout/card_bottom_divider"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</LinearLayout>
|
|
@ -1,72 +1,92 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center_vertical"
|
||||
android:minHeight="66dp"
|
||||
android:orientation="horizontal">
|
||||
<include
|
||||
android:id="@+id/card_top_divider"
|
||||
layout="@layout/card_top_divider"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/explist_indicator"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/content_padding"
|
||||
android:src="@drawable/ic_action_arrow_down" />
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/bg_color">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="vertical">
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:gravity="center_vertical"
|
||||
android:minHeight="66dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/title_tv"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="@dimen/default_list_text_size"
|
||||
tools:text="Quick actions" />
|
||||
<ImageView
|
||||
android:id="@+id/explist_indicator"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/content_padding"
|
||||
android:src="@drawable/ic_action_arrow_down" />
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/sub_text_tv"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
tools:text="8 of 4" />
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="vertical">
|
||||
|
||||
</LinearLayout>
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/title_tv"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="@dimen/default_list_text_size"
|
||||
tools:text="Quick actions" />
|
||||
|
||||
<View
|
||||
android:id="@+id/vertical_divider"
|
||||
android:layout_width="1dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="@dimen/content_padding"
|
||||
android:layout_marginBottom="@dimen/content_padding"
|
||||
android:background="?attr/list_divider" />
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/sub_text_tv"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
tools:text="8 of 4" />
|
||||
|
||||
<android.support.v7.widget.AppCompatCheckBox
|
||||
android:id="@+id/check_box"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/content_padding"
|
||||
android:focusable="false" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
<View
|
||||
android:id="@+id/vertical_divider"
|
||||
android:layout_width="1dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="@dimen/content_padding"
|
||||
android:layout_marginBottom="@dimen/content_padding"
|
||||
android:background="?attr/list_divider" />
|
||||
|
||||
<View
|
||||
android:id="@+id/divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="?attr/list_divider"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
<net.osmand.view.ThreeStateCheckbox
|
||||
android:id="@+id/check_box"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/content_padding"
|
||||
android:focusable="false" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<View
|
||||
android:id="@+id/divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="?attr/list_divider"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<include
|
||||
android:id="@+id/card_bottom_divider"
|
||||
layout="@layout/card_bottom_divider"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</LinearLayout>
|
|
@ -163,6 +163,15 @@
|
|||
<attr name="typeface" format="string|reference"/>
|
||||
<attr name="textAllCapsCompat" format="reference|boolean" />
|
||||
</declare-styleable>
|
||||
<!--<declare-styleable name="ButtonEx" parent="TextViewEx" />
|
||||
<declare-styleable name="SwitchEx" parent="ButtonEx" />-->
|
||||
|
||||
<declare-styleable name="ComplexButton">
|
||||
<attr name="setText" format="string" />
|
||||
<attr name="setTextColor" format="color" />
|
||||
<attr name="setSubText" format="string" />
|
||||
<attr name="setSubTextColor" format="color" />
|
||||
<attr name="setIcon" format="reference" />
|
||||
</declare-styleable>
|
||||
|
||||
<!--<declare-styleable name="ButtonEx" parent="TextViewEx" />
|
||||
<declare-styleable name="SwitchEx" parent="ButtonEx" />-->
|
||||
</resources>
|
||||
|
|
|
@ -17,6 +17,19 @@
|
|||
<string name="recalc_angle_dialog_descr">Extra straight segment between my location and calculated route will be displayed until the route is recalculated</string>
|
||||
<string name="recalc_angle_dialog_title">Minimum angle between my location and route</string>
|
||||
<string name="shared_string_app_default_w_val">App Default (%s)</string>
|
||||
<string name="shared_string_preparing">Preparing</string>
|
||||
<string name="shared_string_poi_types">POI types</string>
|
||||
<string name="shared_string_nothing_selected">Nothing selected</string>
|
||||
<string name="shared_string_quick_actions">Quick actions</string>
|
||||
<string name="shared_string_profiles">Profiles</string>
|
||||
<string name="listed_exist">Listed %1$s, already exist in OsmAnd.</string>
|
||||
<string name="replace_all_desc">Current items will be replaced with items from the file</string>
|
||||
<string name="replace_all">Replace all</string>
|
||||
<string name="keep_both">Keep both</string>
|
||||
<string name="keep_both_desc">Imported items will be added with prexif</string>
|
||||
<string name="import_duplicates_description">OsmAnd already has elements with the same names as those imported.\n\nSelect an action.</string>
|
||||
<string name="import_duplicates_title">Some items already exist</string>
|
||||
<string name="select_data_to_import">Select the data to be imported.</string>
|
||||
<string name="please_provide_profile_name_message">Please provide a name for the profile</string>
|
||||
<string name="no_recalculation_setting">Disable recalculation</string>
|
||||
<string name="open_settings">Open settings</string>
|
||||
|
|
|
@ -40,6 +40,7 @@ import net.osmand.plus.mapmarkers.MapMarkersDbHelper;
|
|||
import net.osmand.plus.monitoring.LiveMonitoringHelper;
|
||||
import net.osmand.plus.monitoring.OsmandMonitoringPlugin;
|
||||
import net.osmand.plus.poi.PoiFiltersHelper;
|
||||
import net.osmand.plus.quickaction.QuickActionRegistry;
|
||||
import net.osmand.plus.render.MapRenderRepositories;
|
||||
import net.osmand.plus.render.NativeOsmandLibrary;
|
||||
import net.osmand.plus.render.RendererRegistry;
|
||||
|
@ -527,6 +528,7 @@ public class AppInitializer implements IProgress {
|
|||
app.travelDbHelper = startupInit(app.travelDbHelper, TravelDbHelper.class);
|
||||
app.lockHelper = startupInit(new LockHelper(app), LockHelper.class);
|
||||
app.settingsHelper = startupInit(new SettingsHelper(app), SettingsHelper.class);
|
||||
app.quickActionRegistry = startupInit(new QuickActionRegistry(app.getSettings()), QuickActionRegistry.class);
|
||||
|
||||
|
||||
initOpeningHoursParser();
|
||||
|
|
|
@ -609,6 +609,11 @@ public class ApplicationMode {
|
|||
}
|
||||
|
||||
public String toJson() {
|
||||
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
|
||||
return gson.toJson(toModeBean());
|
||||
}
|
||||
|
||||
public ApplicationModeBean toModeBean(){
|
||||
ApplicationModeBean mb = new ApplicationModeBean();
|
||||
mb.stringKey = stringKey;
|
||||
mb.userProfileName = getUserProfileName();
|
||||
|
@ -620,8 +625,7 @@ public class ApplicationMode {
|
|||
mb.locIcon = getLocationIcon();
|
||||
mb.navIcon = getNavigationIcon();
|
||||
mb.order = getOrder();
|
||||
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
|
||||
return gson.toJson(mb);
|
||||
return mb;
|
||||
}
|
||||
|
||||
public static void deleteCustomModes(List<ApplicationMode> modes, OsmandApplication app) {
|
||||
|
@ -797,25 +801,25 @@ public class ApplicationMode {
|
|||
}
|
||||
}
|
||||
|
||||
static class ApplicationModeBean {
|
||||
public static class ApplicationModeBean {
|
||||
@Expose
|
||||
String stringKey;
|
||||
public String stringKey;
|
||||
@Expose
|
||||
String userProfileName;
|
||||
public String userProfileName;
|
||||
@Expose
|
||||
String parent;
|
||||
public String parent;
|
||||
@Expose
|
||||
String iconName = "map_world_globe_dark";
|
||||
public String iconName = "map_world_globe_dark";
|
||||
@Expose
|
||||
ProfileIconColors iconColor = ProfileIconColors.DEFAULT;
|
||||
public ProfileIconColors iconColor = ProfileIconColors.DEFAULT;
|
||||
@Expose
|
||||
String routingProfile = null;
|
||||
public String routingProfile = null;
|
||||
@Expose
|
||||
RouteService routeService = RouteService.OSMAND;
|
||||
public RouteService routeService = RouteService.OSMAND;
|
||||
@Expose
|
||||
LocationIcon locIcon = null;
|
||||
public LocationIcon locIcon = null;
|
||||
@Expose
|
||||
NavigationIcon navIcon = null;
|
||||
public NavigationIcon navIcon = null;
|
||||
@Expose
|
||||
int order = -1;
|
||||
}
|
||||
|
|
|
@ -59,6 +59,7 @@ import net.osmand.plus.inapp.InAppPurchaseHelper;
|
|||
import net.osmand.plus.mapmarkers.MapMarkersDbHelper;
|
||||
import net.osmand.plus.monitoring.LiveMonitoringHelper;
|
||||
import net.osmand.plus.poi.PoiFiltersHelper;
|
||||
import net.osmand.plus.quickaction.QuickActionRegistry;
|
||||
import net.osmand.plus.render.RendererRegistry;
|
||||
import net.osmand.plus.resources.ResourceManager;
|
||||
import net.osmand.plus.routepreparationmenu.RoutingOptionsHelper;
|
||||
|
@ -142,6 +143,7 @@ public class OsmandApplication extends MultiDexApplication {
|
|||
LockHelper lockHelper;
|
||||
SettingsHelper settingsHelper;
|
||||
GpxDbHelper gpxDbHelper;
|
||||
QuickActionRegistry quickActionRegistry;
|
||||
|
||||
private Resources localizedResources;
|
||||
|
||||
|
@ -271,7 +273,10 @@ public class OsmandApplication extends MultiDexApplication {
|
|||
public OsmAndAppCustomization getAppCustomization() {
|
||||
return appCustomization;
|
||||
}
|
||||
|
||||
|
||||
public QuickActionRegistry getQuickActionRegistry() {
|
||||
return quickActionRegistry;
|
||||
}
|
||||
|
||||
public void setAppCustomization(OsmAndAppCustomization appCustomization) {
|
||||
this.appCustomization = appCustomization;
|
||||
|
|
|
@ -107,6 +107,21 @@ public class SQLiteTileSource implements ITileSource {
|
|||
this.inversiveZoom = inversiveZoom;
|
||||
}
|
||||
|
||||
public SQLiteTileSource(SQLiteTileSource tileSource, String name, OsmandApplication ctx) {
|
||||
this.ctx = ctx;
|
||||
this.name = name;
|
||||
this.urlTemplate = tileSource.getUrlTemplate();
|
||||
this.maxZoom = tileSource.getMaximumZoomSupported();
|
||||
this.minZoom = tileSource.getMinimumZoomSupported();
|
||||
this.isEllipsoid = tileSource.isEllipticYTile();
|
||||
this.expirationTimeMillis = tileSource.getExpirationTimeMillis();
|
||||
this.randoms = tileSource.getRandoms();
|
||||
this.referer = tileSource.getReferer();
|
||||
this.invertedY = tileSource.isInvertedYTile();
|
||||
this.timeSupported = tileSource.isTimeSupported();
|
||||
this.inversiveZoom = tileSource.getInversiveZoom();
|
||||
}
|
||||
|
||||
public void createDataBase() {
|
||||
db = ctx.getSQLiteAPI().getOrCreateDatabase(
|
||||
ctx.getAppPath(TILES_INDEX_DIR).getAbsolutePath() + "/" + name + SQLITE_EXT, true);
|
||||
|
@ -114,7 +129,6 @@ public class SQLiteTileSource implements ITileSource {
|
|||
db.execSQL("CREATE TABLE tiles (x int, y int, z int, s int, image blob, time long, PRIMARY KEY (x,y,z,s))");
|
||||
db.execSQL("CREATE INDEX IND on tiles (x,y,z,s)");
|
||||
db.execSQL("CREATE TABLE info(tilenumbering,minzoom,maxzoom)");
|
||||
db.execSQL("CREATE TABLE android_metadata (locale TEXT)");
|
||||
db.execSQL("INSERT INTO info (tilenumbering,minzoom,maxzoom) VALUES ('simple','" + minZoom + "','" + maxZoom + "');");
|
||||
|
||||
addInfoColumn(URL, urlTemplate);
|
||||
|
@ -128,7 +142,7 @@ public class SQLiteTileSource implements ITileSource {
|
|||
|
||||
db.close();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getBitDensity() {
|
||||
return base != null ? base.getBitDensity() : 16;
|
||||
|
|
|
@ -2,8 +2,8 @@ package net.osmand.plus;
|
|||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.AsyncTask;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
@ -12,6 +12,7 @@ import android.support.v7.app.AlertDialog;
|
|||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import net.osmand.IndexConstants;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.map.ITileSource;
|
||||
import net.osmand.map.TileSourceManager;
|
||||
|
@ -20,10 +21,9 @@ import net.osmand.osm.PoiCategory;
|
|||
import net.osmand.plus.ApplicationMode.ApplicationModeBean;
|
||||
import net.osmand.plus.ApplicationMode.ApplicationModeBuilder;
|
||||
import net.osmand.plus.OsmandSettings.OsmandPreference;
|
||||
import net.osmand.plus.activities.MapActivity;
|
||||
import net.osmand.plus.poi.PoiUIFilter;
|
||||
import net.osmand.plus.quickaction.QuickAction;
|
||||
import net.osmand.plus.quickaction.QuickActionFactory;
|
||||
import net.osmand.plus.quickaction.QuickActionRegistry;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
@ -47,6 +47,7 @@ import java.io.OutputStream;
|
|||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
|
@ -60,7 +61,6 @@ import java.util.zip.ZipInputStream;
|
|||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
import static net.osmand.IndexConstants.OSMAND_SETTINGS_FILE_EXT;
|
||||
import static net.osmand.IndexConstants.TILES_INDEX_DIR;
|
||||
|
||||
/*
|
||||
Usage:
|
||||
|
@ -153,6 +153,8 @@ public class SettingsHelper {
|
|||
|
||||
private SettingsItemType type;
|
||||
|
||||
boolean shouldReplace = false;
|
||||
|
||||
SettingsItem(@NonNull SettingsItemType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
@ -176,10 +178,14 @@ public class SettingsHelper {
|
|||
@NonNull
|
||||
public abstract String getFileName();
|
||||
|
||||
public Boolean shouldReadOnCollecting() {
|
||||
public boolean shouldReadOnCollecting() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setShouldReplace(boolean shouldReplace) {
|
||||
this.shouldReplace = shouldReplace;
|
||||
}
|
||||
|
||||
static SettingsItemType parseItemType(@NonNull JSONObject json) throws IllegalArgumentException, JSONException {
|
||||
return SettingsItemType.valueOf(json.getString("type"));
|
||||
}
|
||||
|
@ -231,6 +237,35 @@ public class SettingsHelper {
|
|||
}
|
||||
}
|
||||
|
||||
public abstract static class CollectionSettingsItem<T> extends SettingsItem {
|
||||
|
||||
protected List<T> items;
|
||||
protected List<T> duplicateItems;
|
||||
protected List<T> existingItems;
|
||||
|
||||
CollectionSettingsItem(@NonNull SettingsItemType type, @NonNull List<T> items) {
|
||||
super(type);
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
CollectionSettingsItem(@NonNull SettingsItemType type, @NonNull JSONObject json) throws JSONException {
|
||||
super(type, json);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public List<T> getItems() {
|
||||
return items;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public abstract List<T> excludeDuplicateItems();
|
||||
|
||||
public abstract boolean isDuplicate(@NonNull T item);
|
||||
|
||||
@NonNull
|
||||
public abstract T renameItem(@NonNull T item);
|
||||
}
|
||||
|
||||
public abstract static class SettingsItemReader<T extends SettingsItem> {
|
||||
|
||||
private T item;
|
||||
|
@ -423,28 +458,43 @@ public class SettingsHelper {
|
|||
|
||||
public static class ProfileSettingsItem extends OsmandSettingsItem {
|
||||
|
||||
private OsmandApplication app;
|
||||
private ApplicationMode appMode;
|
||||
private ApplicationModeBuilder builder;
|
||||
private ApplicationModeBean modeBean;
|
||||
private Set<String> appModeBeanPrefsIds;
|
||||
|
||||
|
||||
public ProfileSettingsItem(@NonNull OsmandSettings settings, @NonNull ApplicationMode appMode) {
|
||||
super(SettingsItemType.PROFILE, settings);
|
||||
public ProfileSettingsItem(@NonNull OsmandApplication app, @NonNull ApplicationMode appMode) {
|
||||
super(SettingsItemType.PROFILE, app.getSettings());
|
||||
this.app = app;
|
||||
this.appMode = appMode;
|
||||
appModeBeanPrefsIds = new HashSet<>(Arrays.asList(settings.appModeBeanPrefsIds));
|
||||
appModeBeanPrefsIds = new HashSet<>(Arrays.asList(app.getSettings().appModeBeanPrefsIds));
|
||||
}
|
||||
|
||||
public ProfileSettingsItem(@NonNull OsmandSettings settings, @NonNull JSONObject json) throws JSONException {
|
||||
super(SettingsItemType.PROFILE, settings, json);
|
||||
readFromJson(settings.getContext(), json);
|
||||
appModeBeanPrefsIds = new HashSet<>(Arrays.asList(settings.appModeBeanPrefsIds));
|
||||
public ProfileSettingsItem(@NonNull OsmandApplication app, @NonNull ApplicationModeBean modeBean) {
|
||||
super(SettingsItemType.PROFILE, app.getSettings());
|
||||
this.app = app;
|
||||
this.modeBean = modeBean;
|
||||
builder = ApplicationMode.fromModeBean(app, modeBean);
|
||||
appMode = builder.getApplicationMode();
|
||||
appModeBeanPrefsIds = new HashSet<>(Arrays.asList(app.getSettings().appModeBeanPrefsIds));
|
||||
}
|
||||
|
||||
public ProfileSettingsItem(@NonNull OsmandApplication app, @NonNull JSONObject json) throws JSONException {
|
||||
super(SettingsItemType.PROFILE, app.getSettings(), json);
|
||||
this.app = app;
|
||||
readFromJson(app.getSettings().getContext(), json);
|
||||
appModeBeanPrefsIds = new HashSet<>(Arrays.asList(app.getSettings().appModeBeanPrefsIds));
|
||||
}
|
||||
|
||||
public ApplicationMode getAppMode() {
|
||||
return appMode;
|
||||
}
|
||||
|
||||
public ApplicationModeBean getModeBean() {
|
||||
return modeBean;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String getName() {
|
||||
|
@ -485,11 +535,44 @@ public class SettingsHelper {
|
|||
return builder != null && ApplicationMode.valueOfStringKey(getName(), null) != null;
|
||||
}
|
||||
|
||||
private void renameProfile() {
|
||||
int number = 0;
|
||||
while (true) {
|
||||
number++;
|
||||
String key = modeBean.stringKey + "_" + number;
|
||||
if (ApplicationMode.valueOfStringKey(key, null) == null) {
|
||||
modeBean.stringKey = key;
|
||||
modeBean.userProfileName = modeBean.userProfileName + "_" + number;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply() {
|
||||
if (appMode.isCustomProfile()) {
|
||||
appMode = ApplicationMode.saveProfile(builder, getSettings().getContext());
|
||||
if (!appMode.isCustomProfile() && !shouldReplace) {
|
||||
ApplicationMode parent = ApplicationMode.valueOfStringKey(modeBean.stringKey, null);
|
||||
renameProfile();
|
||||
ApplicationMode.ApplicationModeBuilder builder = ApplicationMode
|
||||
.createCustomMode(parent, modeBean.stringKey, app)
|
||||
.setIconResName(modeBean.iconName)
|
||||
.setUserProfileName(modeBean.userProfileName)
|
||||
.setRoutingProfile(modeBean.routingProfile)
|
||||
.setRouteService(modeBean.routeService)
|
||||
.setIconColor(modeBean.iconColor)
|
||||
.setLocationIcon(modeBean.locIcon)
|
||||
.setNavigationIcon(modeBean.navIcon);
|
||||
app.getSettings().copyPreferencesFromProfile(parent, builder.getApplicationMode());
|
||||
appMode = ApplicationMode.saveProfile(builder, app);
|
||||
} else if (!shouldReplace && exists()) {
|
||||
renameProfile();
|
||||
builder = ApplicationMode.fromModeBean(app, modeBean);
|
||||
appMode = ApplicationMode.saveProfile(builder, app);
|
||||
} else {
|
||||
builder = ApplicationMode.fromModeBean(app, modeBean);
|
||||
appMode = ApplicationMode.saveProfile(builder, app);
|
||||
}
|
||||
ApplicationMode.changeProfileAvailability(appMode, true, app);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -698,13 +781,31 @@ public class SettingsHelper {
|
|||
return file.exists();
|
||||
}
|
||||
|
||||
private File renameFile(File file) {
|
||||
int number = 0;
|
||||
String path = file.getAbsolutePath();
|
||||
while (true) {
|
||||
number++;
|
||||
String copyName = path.replaceAll(file.getName(), file.getName().replaceFirst("[.]", "_" + number + "."));
|
||||
File copyFile = new File(copyName);
|
||||
if (!copyFile.exists()) {
|
||||
return copyFile;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
SettingsItemReader getReader() {
|
||||
return new StreamSettingsItemReader(this) {
|
||||
@Override
|
||||
public void readFromStream(@NonNull InputStream inputStream) throws IOException, IllegalArgumentException {
|
||||
OutputStream output = new FileOutputStream(file);
|
||||
OutputStream output;
|
||||
if (shouldReplace || !file.exists()) {
|
||||
output = new FileOutputStream(file);
|
||||
} else {
|
||||
output = new FileOutputStream(renameFile(file));
|
||||
}
|
||||
byte[] buffer = new byte[BUFFER];
|
||||
int count;
|
||||
try {
|
||||
|
@ -731,49 +832,78 @@ public class SettingsHelper {
|
|||
}
|
||||
}
|
||||
|
||||
public static class QuickActionSettingsItem extends OsmandSettingsItem {
|
||||
|
||||
private List<QuickAction> quickActions;
|
||||
public static class QuickActionSettingsItem extends CollectionSettingsItem<QuickAction> {
|
||||
|
||||
private OsmandApplication app;
|
||||
private QuickActionRegistry actionRegistry;
|
||||
|
||||
public QuickActionSettingsItem(@NonNull OsmandApplication app,
|
||||
@NonNull List<QuickAction> quickActions) {
|
||||
super(SettingsItemType.QUICK_ACTION, app.getSettings());
|
||||
@NonNull List<QuickAction> items) {
|
||||
super(SettingsItemType.QUICK_ACTION, items);
|
||||
this.app = app;
|
||||
this.quickActions = quickActions;
|
||||
actionRegistry = app.getQuickActionRegistry();
|
||||
existingItems = actionRegistry.getQuickActions();
|
||||
}
|
||||
|
||||
public QuickActionSettingsItem(@NonNull OsmandApplication app,
|
||||
@NonNull JSONObject jsonObject) throws JSONException {
|
||||
super(SettingsItemType.QUICK_ACTION, app.getSettings(), jsonObject);
|
||||
QuickActionSettingsItem(@NonNull OsmandApplication app,
|
||||
@NonNull JSONObject json) throws JSONException {
|
||||
super(SettingsItemType.QUICK_ACTION, json);
|
||||
this.app = app;
|
||||
actionRegistry = app.getQuickActionRegistry();
|
||||
existingItems = actionRegistry.getQuickActions();
|
||||
}
|
||||
|
||||
public List<QuickAction> getQuickActions() {
|
||||
return quickActions;
|
||||
@Override
|
||||
public boolean isDuplicate(@NonNull QuickAction item) {
|
||||
return !actionRegistry.isNameUnique(item, app);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public QuickAction renameItem(@NonNull QuickAction item) {
|
||||
return actionRegistry.generateUniqueName(item, app);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public List<QuickAction> excludeDuplicateItems() {
|
||||
duplicateItems = new ArrayList<>();
|
||||
for (QuickAction item : items) {
|
||||
if (isDuplicate(item)) {
|
||||
duplicateItems.add(item);
|
||||
}
|
||||
}
|
||||
items.removeAll(duplicateItems);
|
||||
return duplicateItems;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply() {
|
||||
if (!quickActions.isEmpty()) {
|
||||
QuickActionFactory factory = new QuickActionFactory();
|
||||
List<QuickAction> savedActions = factory.parseActiveActionsList(getSettings().QUICK_ACTION_LIST.get());
|
||||
List<QuickAction> newActions = new ArrayList<>(savedActions);
|
||||
for (QuickAction action : quickActions) {
|
||||
for (QuickAction savedAction : savedActions) {
|
||||
if (action.getName(app).equals(savedAction.getName(app))) {
|
||||
newActions.remove(savedAction);
|
||||
if (!items.isEmpty() || !duplicateItems.isEmpty()) {
|
||||
List<QuickAction> newActions = new ArrayList<>(existingItems);
|
||||
if (!duplicateItems.isEmpty()) {
|
||||
if (shouldReplace) {
|
||||
for (QuickAction duplicateItem : duplicateItems) {
|
||||
for (QuickAction savedAction : existingItems) {
|
||||
if (duplicateItem.getName(app).equals(savedAction.getName(app))) {
|
||||
newActions.remove(savedAction);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (QuickAction duplicateItem : duplicateItems) {
|
||||
renameItem(duplicateItem);
|
||||
}
|
||||
}
|
||||
newActions.addAll(duplicateItems);
|
||||
}
|
||||
newActions.addAll(quickActions);
|
||||
((MapActivity) app.getSettingsHelper().getActivity()).getMapLayers().getQuickActionRegistry().updateQuickActions(newActions);
|
||||
newActions.addAll(items);
|
||||
actionRegistry.updateQuickActions(newActions);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean shouldReadOnCollecting() {
|
||||
public boolean shouldReadOnCollecting() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -798,13 +928,7 @@ public class SettingsHelper {
|
|||
@NonNull
|
||||
@Override
|
||||
SettingsItemReader getReader() {
|
||||
return new OsmandSettingsItemReader(this, getSettings()) {
|
||||
|
||||
@Override
|
||||
protected void readPreferenceFromJson(@NonNull OsmandPreference<?> preference, @NonNull JSONObject json) throws JSONException {
|
||||
|
||||
}
|
||||
|
||||
return new SettingsItemReader(this) {
|
||||
@Override
|
||||
public void readFromStream(@NonNull InputStream inputStream) throws IOException, IllegalArgumentException {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
|
@ -823,22 +947,24 @@ public class SettingsHelper {
|
|||
}
|
||||
final JSONObject json;
|
||||
try {
|
||||
quickActions = new ArrayList<>();
|
||||
items = new ArrayList<>();
|
||||
Gson gson = new Gson();
|
||||
Type type = new TypeToken<HashMap<String, String>>() {
|
||||
}.getType();
|
||||
json = new JSONObject(jsonStr);
|
||||
JSONArray items = json.getJSONArray("items");
|
||||
for (int i = 0; i < items.length(); i++) {
|
||||
JSONObject object = items.getJSONObject(i);
|
||||
JSONArray itemsJson = json.getJSONArray("items");
|
||||
for (int i = 0; i < itemsJson.length(); i++) {
|
||||
JSONObject object = itemsJson.getJSONObject(i);
|
||||
String name = object.getString("name");
|
||||
int actionType = object.getInt("type");
|
||||
String paramsString = object.getString("params");
|
||||
HashMap<String, String> params = gson.fromJson(paramsString, type);
|
||||
QuickAction quickAction = new QuickAction(actionType);
|
||||
quickAction.setName(name);
|
||||
if (!name.isEmpty()) {
|
||||
quickAction.setName(name);
|
||||
}
|
||||
quickAction.setParams(params);
|
||||
quickActions.add(quickAction);
|
||||
items.add(quickAction);
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
throw new IllegalArgumentException("Json parse error", e);
|
||||
|
@ -850,59 +976,115 @@ public class SettingsHelper {
|
|||
@NonNull
|
||||
@Override
|
||||
SettingsItemWriter getWriter() {
|
||||
return new OsmandSettingsItemWriter(this, getSettings()) {
|
||||
return new SettingsItemWriter(this) {
|
||||
@Override
|
||||
protected void writePreferenceToJson(@NonNull OsmandPreference<?> preference, @NonNull JSONObject json) throws JSONException {
|
||||
JSONArray items = new JSONArray();
|
||||
public boolean writeToStream(@NonNull OutputStream outputStream) throws IOException {
|
||||
JSONObject json = new JSONObject();
|
||||
JSONArray jsonArray = new JSONArray();
|
||||
Gson gson = new Gson();
|
||||
Type type = new TypeToken<HashMap<String, String>>() {
|
||||
}.getType();
|
||||
if (!quickActions.isEmpty()) {
|
||||
for (QuickAction action : quickActions) {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("name", action.getName(app));
|
||||
jsonObject.put("type", action.getType());
|
||||
jsonObject.put("params", gson.toJson(action.getParams(), type));
|
||||
items.put(jsonObject);
|
||||
if (!items.isEmpty()) {
|
||||
try {
|
||||
for (QuickAction action : items) {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("name", action.hasCustomName(app)
|
||||
? action.getName(app) : "");
|
||||
jsonObject.put("type", action.getType());
|
||||
jsonObject.put("params", gson.toJson(action.getParams(), type));
|
||||
jsonArray.put(jsonObject);
|
||||
}
|
||||
json.put("items", jsonArray);
|
||||
} catch (JSONException e) {
|
||||
LOG.error("Failed write to json", e);
|
||||
}
|
||||
json.put("items", items);
|
||||
}
|
||||
if (json.length() > 0) {
|
||||
try {
|
||||
String s = json.toString(2);
|
||||
outputStream.write(s.getBytes("UTF-8"));
|
||||
} catch (JSONException e) {
|
||||
LOG.error("Failed to write json to stream", e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public static class PoiUiFilterSettingsItem extends OsmandSettingsItem {
|
||||
|
||||
private List<PoiUIFilter> poiUIFilters;
|
||||
public static class PoiUiFilterSettingsItem extends CollectionSettingsItem<PoiUIFilter> {
|
||||
|
||||
private OsmandApplication app;
|
||||
|
||||
public PoiUiFilterSettingsItem(OsmandApplication app, List<PoiUIFilter> poiUIFilters) {
|
||||
super(SettingsItemType.POI_UI_FILTERS, app.getSettings());
|
||||
public PoiUiFilterSettingsItem(@NonNull OsmandApplication app, @NonNull List<PoiUIFilter> items) {
|
||||
super(SettingsItemType.POI_UI_FILTERS, items);
|
||||
this.app = app;
|
||||
this.poiUIFilters = poiUIFilters;
|
||||
existingItems = app.getPoiFilters().getUserDefinedPoiFilters(false);
|
||||
}
|
||||
|
||||
public PoiUiFilterSettingsItem(OsmandApplication app, JSONObject jsonObject) throws JSONException {
|
||||
super(SettingsItemType.POI_UI_FILTERS, app.getSettings(), jsonObject);
|
||||
PoiUiFilterSettingsItem(@NonNull OsmandApplication app, @NonNull JSONObject json) throws JSONException {
|
||||
super(SettingsItemType.POI_UI_FILTERS, json);
|
||||
this.app = app;
|
||||
}
|
||||
|
||||
public List<PoiUIFilter> getPoiUIFilters() {
|
||||
return this.poiUIFilters != null ? this.poiUIFilters : new ArrayList<PoiUIFilter>();
|
||||
existingItems = app.getPoiFilters().getUserDefinedPoiFilters(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply() {
|
||||
if (!poiUIFilters.isEmpty()) {
|
||||
for (PoiUIFilter filter : poiUIFilters) {
|
||||
if (!items.isEmpty() || !duplicateItems.isEmpty()) {
|
||||
for (PoiUIFilter duplicate : duplicateItems) {
|
||||
items.add(shouldReplace ? duplicate : renameItem(duplicate));
|
||||
}
|
||||
for (PoiUIFilter filter : items) {
|
||||
app.getPoiFilters().createPoiFilter(filter, false);
|
||||
}
|
||||
app.getSearchUICore().refreshCustomPoiFilters();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDuplicate(@NonNull PoiUIFilter item) {
|
||||
String savedName = item.getName();
|
||||
for (PoiUIFilter filter : existingItems) {
|
||||
if (filter.getName().equals(savedName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public List<PoiUIFilter> excludeDuplicateItems() {
|
||||
duplicateItems = new ArrayList<>();
|
||||
if (!items.isEmpty()) {
|
||||
for (PoiUIFilter item : items) {
|
||||
if (isDuplicate(item)) {
|
||||
duplicateItems.add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
items.removeAll(duplicateItems);
|
||||
return duplicateItems;
|
||||
}
|
||||
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public PoiUIFilter renameItem(@NonNull PoiUIFilter item) {
|
||||
int number = 0;
|
||||
while (true) {
|
||||
number++;
|
||||
PoiUIFilter renamedItem = new PoiUIFilter(item,
|
||||
item.getName() + "_" + number,
|
||||
item.getFilterId() + "_" + number);
|
||||
if (!isDuplicate(renamedItem)) {
|
||||
return renamedItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String getName() {
|
||||
|
@ -912,11 +1094,11 @@ public class SettingsHelper {
|
|||
@NonNull
|
||||
@Override
|
||||
public String getPublicName(@NonNull Context ctx) {
|
||||
return null;
|
||||
return "poi_ui_filters";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean shouldReadOnCollecting() {
|
||||
public boolean shouldReadOnCollecting() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -929,12 +1111,7 @@ public class SettingsHelper {
|
|||
@NonNull
|
||||
@Override
|
||||
SettingsItemReader getReader() {
|
||||
return new OsmandSettingsItemReader(this, getSettings()) {
|
||||
@Override
|
||||
protected void readPreferenceFromJson(@NonNull OsmandPreference<?> preference, @NonNull JSONObject json) throws JSONException {
|
||||
|
||||
}
|
||||
|
||||
return new SettingsItemReader(this) {
|
||||
@Override
|
||||
public void readFromStream(@NonNull InputStream inputStream) throws IOException, IllegalArgumentException {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
|
@ -953,15 +1130,15 @@ public class SettingsHelper {
|
|||
}
|
||||
final JSONObject json;
|
||||
try {
|
||||
poiUIFilters = new ArrayList<>();
|
||||
items = new ArrayList<>();
|
||||
json = new JSONObject(jsonStr);
|
||||
JSONArray items = json.getJSONArray("items");
|
||||
JSONArray jsonArray = json.getJSONArray("items");
|
||||
Gson gson = new Gson();
|
||||
Type type = new TypeToken<HashMap<String, LinkedHashSet<String>>>() {
|
||||
}.getType();
|
||||
MapPoiTypes poiTypes = app.getPoiTypes();
|
||||
for (int i = 0; i < items.length(); i++) {
|
||||
JSONObject object = items.getJSONObject(i);
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
JSONObject object = jsonArray.getJSONObject(i);
|
||||
String name = object.getString("name");
|
||||
String filterId = object.getString("filterId");
|
||||
String acceptedTypesString = object.getString("acceptedTypes");
|
||||
|
@ -972,7 +1149,7 @@ public class SettingsHelper {
|
|||
acceptedTypesDone.put(a, mapItem.getValue());
|
||||
}
|
||||
PoiUIFilter filter = new PoiUIFilter(name, filterId, acceptedTypesDone, app);
|
||||
poiUIFilters.add(filter);
|
||||
items.add(filter);
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
throw new IllegalArgumentException("Json parse error", e);
|
||||
|
@ -984,62 +1161,149 @@ public class SettingsHelper {
|
|||
@NonNull
|
||||
@Override
|
||||
SettingsItemWriter getWriter() {
|
||||
return new OsmandSettingsItemWriter(this, getSettings()) {
|
||||
return new SettingsItemWriter(this) {
|
||||
@Override
|
||||
protected void writePreferenceToJson(@NonNull OsmandPreference<?> preference, @NonNull JSONObject json) throws JSONException {
|
||||
JSONArray items = new JSONArray();
|
||||
public boolean writeToStream(@NonNull OutputStream outputStream) throws IOException {
|
||||
JSONObject json = new JSONObject();
|
||||
JSONArray jsonArray = new JSONArray();
|
||||
Gson gson = new Gson();
|
||||
Type type = new TypeToken<HashMap<PoiCategory, LinkedHashSet<String>>>() {
|
||||
}.getType();
|
||||
if (!poiUIFilters.isEmpty()) {
|
||||
for (PoiUIFilter filter : poiUIFilters) {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("name", filter.getName());
|
||||
jsonObject.put("filterId", filter.getFilterId());
|
||||
jsonObject.put("acceptedTypes", gson.toJson(filter.getAcceptedTypes(), type));
|
||||
items.put(jsonObject);
|
||||
if (!items.isEmpty()) {
|
||||
try {
|
||||
for (PoiUIFilter filter : items) {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("name", filter.getName());
|
||||
jsonObject.put("filterId", filter.getFilterId());
|
||||
jsonObject.put("acceptedTypes", gson.toJson(filter.getAcceptedTypes(), type));
|
||||
jsonArray.put(jsonObject);
|
||||
}
|
||||
json.put("items", jsonArray);
|
||||
} catch (JSONException e) {
|
||||
LOG.error("Failed write to json", e);
|
||||
}
|
||||
json.put("items", items);
|
||||
}
|
||||
if (json.length() > 0) {
|
||||
try {
|
||||
String s = json.toString(2);
|
||||
outputStream.write(s.getBytes("UTF-8"));
|
||||
} catch (JSONException e) {
|
||||
LOG.error("Failed to write json to stream", e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public static class MapSourcesSettingsItem extends OsmandSettingsItem {
|
||||
public static class MapSourcesSettingsItem extends CollectionSettingsItem<ITileSource> {
|
||||
|
||||
private OsmandApplication app;
|
||||
private List<String> existingItemsNames;
|
||||
|
||||
private List<ITileSource> mapSources;
|
||||
|
||||
public MapSourcesSettingsItem(OsmandApplication app, List<ITileSource> mapSources) {
|
||||
super(SettingsItemType.MAP_SOURCES, app.getSettings());
|
||||
public MapSourcesSettingsItem(@NonNull OsmandApplication app, @NonNull List<ITileSource> items) {
|
||||
super(SettingsItemType.MAP_SOURCES, items);
|
||||
this.app = app;
|
||||
this.mapSources = mapSources;
|
||||
Collection values = new LinkedHashMap<>(app.getSettings().getTileSourceEntries(true)).values();
|
||||
existingItemsNames = new ArrayList(values);
|
||||
}
|
||||
|
||||
public MapSourcesSettingsItem(OsmandApplication app, JSONObject jsonObject) throws JSONException {
|
||||
super(SettingsItemType.MAP_SOURCES, app.getSettings(), jsonObject);
|
||||
MapSourcesSettingsItem(@NonNull OsmandApplication app, @NonNull JSONObject json) throws JSONException {
|
||||
super(SettingsItemType.MAP_SOURCES, json);
|
||||
this.app = app;
|
||||
}
|
||||
|
||||
public List<ITileSource> getMapSources() {
|
||||
return this.mapSources;
|
||||
Collection values = new LinkedHashMap<>(app.getSettings().getTileSourceEntries(true)).values();
|
||||
existingItemsNames = new ArrayList(values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply() {
|
||||
if (!mapSources.isEmpty()) {
|
||||
for (ITileSource template : mapSources) {
|
||||
if (template instanceof TileSourceManager.TileSourceTemplate) {
|
||||
getSettings().installTileSource((TileSourceManager.TileSourceTemplate) template);
|
||||
} else {
|
||||
((SQLiteTileSource) template).createDataBase();
|
||||
if (!items.isEmpty() || !duplicateItems.isEmpty()) {
|
||||
if (shouldReplace) {
|
||||
for (ITileSource tileSource : duplicateItems) {
|
||||
if (tileSource instanceof SQLiteTileSource) {
|
||||
File f = app.getAppPath(IndexConstants.TILES_INDEX_DIR + tileSource.getName() + IndexConstants.SQLITE_EXT);
|
||||
if (f != null && f.exists()) {
|
||||
if (f.delete()) {
|
||||
items.add(tileSource);
|
||||
}
|
||||
}
|
||||
} else if (tileSource instanceof TileSourceManager.TileSourceTemplate) {
|
||||
File f = app.getAppPath(IndexConstants.TILES_INDEX_DIR + tileSource.getName());
|
||||
if (f != null && f.exists() && f.isDirectory()) {
|
||||
if (f.delete()) {
|
||||
items.add(tileSource);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (ITileSource tileSource : duplicateItems) {
|
||||
items.add(renameItem(tileSource));
|
||||
}
|
||||
}
|
||||
for (ITileSource tileSource : items) {
|
||||
if (tileSource instanceof TileSourceManager.TileSourceTemplate) {
|
||||
app.getSettings().installTileSource((TileSourceManager.TileSourceTemplate) tileSource);
|
||||
} else if (tileSource instanceof SQLiteTileSource) {
|
||||
((SQLiteTileSource) tileSource).createDataBase();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public List<ITileSource> excludeDuplicateItems() {
|
||||
duplicateItems = new ArrayList<>();
|
||||
for (String name : existingItemsNames) {
|
||||
for (ITileSource tileSource : items) {
|
||||
if (name.equals(tileSource.getName())) {
|
||||
duplicateItems.add(tileSource);
|
||||
}
|
||||
}
|
||||
}
|
||||
items.removeAll(duplicateItems);
|
||||
return duplicateItems;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ITileSource renameItem(@NonNull ITileSource item) {
|
||||
int number = 0;
|
||||
while (true) {
|
||||
number++;
|
||||
if (item instanceof SQLiteTileSource) {
|
||||
SQLiteTileSource oldItem = (SQLiteTileSource) item;
|
||||
SQLiteTileSource renamedItem = new SQLiteTileSource(
|
||||
oldItem,
|
||||
oldItem.getName() + "_" + number,
|
||||
app);
|
||||
if (!isDuplicate(renamedItem)) {
|
||||
return renamedItem;
|
||||
}
|
||||
} else if (item instanceof TileSourceManager.TileSourceTemplate) {
|
||||
TileSourceManager.TileSourceTemplate oldItem = (TileSourceManager.TileSourceTemplate) item;
|
||||
oldItem.setName(oldItem.getName() + "_" + number);
|
||||
if (!isDuplicate(oldItem)) {
|
||||
return oldItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDuplicate(@NonNull ITileSource item) {
|
||||
for (String name : existingItemsNames) {
|
||||
if (name.equals(item.getName())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String getName() {
|
||||
|
@ -1049,11 +1313,11 @@ public class SettingsHelper {
|
|||
@NonNull
|
||||
@Override
|
||||
public String getPublicName(@NonNull Context ctx) {
|
||||
return null;
|
||||
return "map_sources";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean shouldReadOnCollecting() {
|
||||
public boolean shouldReadOnCollecting() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1066,12 +1330,7 @@ public class SettingsHelper {
|
|||
@NonNull
|
||||
@Override
|
||||
SettingsItemReader getReader() {
|
||||
return new OsmandSettingsItemReader(this, getSettings()) {
|
||||
@Override
|
||||
protected void readPreferenceFromJson(@NonNull OsmandPreference<?> preference, @NonNull JSONObject json) throws JSONException {
|
||||
|
||||
}
|
||||
|
||||
return new SettingsItemReader(this) {
|
||||
@Override
|
||||
public void readFromStream(@NonNull InputStream inputStream) throws IOException, IllegalArgumentException {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
|
@ -1090,11 +1349,11 @@ public class SettingsHelper {
|
|||
}
|
||||
final JSONObject json;
|
||||
try {
|
||||
mapSources = new ArrayList<>();
|
||||
items = new ArrayList<>();
|
||||
json = new JSONObject(jsonStr);
|
||||
JSONArray items = json.getJSONArray("items");
|
||||
for (int i = 0; i < items.length(); i++) {
|
||||
JSONObject object = items.getJSONObject(i);
|
||||
JSONArray jsonArray = json.getJSONArray("items");
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
JSONObject object = jsonArray.getJSONObject(i);
|
||||
boolean sql = object.optBoolean("sql");
|
||||
String name = object.optString("name");
|
||||
int minZoom = object.optInt("minZoom");
|
||||
|
@ -1107,7 +1366,6 @@ public class SettingsHelper {
|
|||
boolean timesupported = object.optBoolean("timesupported", false);
|
||||
long expire = object.optLong("expire");
|
||||
boolean inversiveZoom = object.optBoolean("inversiveZoom", false);
|
||||
|
||||
String ext = object.optString("ext");
|
||||
int tileSize = object.optInt("tileSize");
|
||||
int bitDensity = object.optInt("bitDensity");
|
||||
|
@ -1120,7 +1378,7 @@ public class SettingsHelper {
|
|||
} else {
|
||||
template = new SQLiteTileSource(app, name, minZoom, maxZoom, url, randoms, ellipsoid, invertedY, referer, timesupported, expire, inversiveZoom);
|
||||
}
|
||||
mapSources.add(template);
|
||||
items.add(template);
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
throw new IllegalArgumentException("Json parse error", e);
|
||||
|
@ -1132,37 +1390,51 @@ public class SettingsHelper {
|
|||
@NonNull
|
||||
@Override
|
||||
SettingsItemWriter getWriter() {
|
||||
return new OsmandSettingsItemWriter(this, getSettings()) {
|
||||
return new SettingsItemWriter(this) {
|
||||
@Override
|
||||
protected void writePreferenceToJson(@NonNull OsmandPreference<?> preference, @NonNull JSONObject json) throws JSONException {
|
||||
JSONArray items = new JSONArray();
|
||||
if (!mapSources.isEmpty()) {
|
||||
for (ITileSource template : mapSources) {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
boolean sql = template instanceof SQLiteTileSource;
|
||||
jsonObject.put("sql", sql);
|
||||
jsonObject.put("name", template.getName());
|
||||
jsonObject.put("minZoom", template.getMinimumZoomSupported());
|
||||
jsonObject.put("maxZoom", template.getMaximumZoomSupported());
|
||||
jsonObject.put("url", template.getUrlTemplate());
|
||||
jsonObject.put("randoms", template.getRandoms());
|
||||
jsonObject.put("ellipsoid", template.isEllipticYTile());
|
||||
jsonObject.put("inverted_y", template.isInvertedYTile());
|
||||
jsonObject.put("referer", template.getReferer());
|
||||
jsonObject.put("timesupported", template.isTimeSupported());
|
||||
jsonObject.put("expire", template.getExpirationTimeMillis());
|
||||
jsonObject.put("inversiveZoom", template.getInversiveZoom());
|
||||
public boolean writeToStream(@NonNull OutputStream outputStream) throws IOException {
|
||||
JSONObject json = new JSONObject();
|
||||
JSONArray jsonArray = new JSONArray();
|
||||
if (!items.isEmpty()) {
|
||||
try {
|
||||
for (ITileSource template : items) {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
boolean sql = template instanceof SQLiteTileSource;
|
||||
jsonObject.put("sql", sql);
|
||||
jsonObject.put("name", template.getName());
|
||||
jsonObject.put("minZoom", template.getMinimumZoomSupported());
|
||||
jsonObject.put("maxZoom", template.getMaximumZoomSupported());
|
||||
jsonObject.put("url", template.getUrlTemplate());
|
||||
jsonObject.put("randoms", template.getRandoms());
|
||||
jsonObject.put("ellipsoid", template.isEllipticYTile());
|
||||
jsonObject.put("inverted_y", template.isInvertedYTile());
|
||||
jsonObject.put("referer", template.getReferer());
|
||||
jsonObject.put("timesupported", template.isTimeSupported());
|
||||
jsonObject.put("expire", template.getExpirationTimeMillis());
|
||||
jsonObject.put("inversiveZoom", template.getInversiveZoom());
|
||||
jsonObject.put("ext", template.getTileFormat());
|
||||
jsonObject.put("tileSize", template.getTileSize());
|
||||
jsonObject.put("bitDensity", template.getBitDensity());
|
||||
jsonObject.put("avgSize", template.getAvgSize());
|
||||
jsonObject.put("rule", template.getRule());
|
||||
jsonArray.put(jsonObject);
|
||||
}
|
||||
json.put("items", jsonArray);
|
||||
|
||||
jsonObject.put("ext", template.getTileFormat());
|
||||
jsonObject.put("tileSize", template.getTileSize());
|
||||
jsonObject.put("bitDensity", template.getBitDensity());
|
||||
jsonObject.put("avgSize", template.getAvgSize());
|
||||
jsonObject.put("rule", template.getRule());
|
||||
|
||||
items.put(jsonObject);
|
||||
} catch (JSONException e) {
|
||||
LOG.error("Failed write to json", e);
|
||||
}
|
||||
json.put("items", items);
|
||||
}
|
||||
if (json.length() > 0) {
|
||||
try {
|
||||
String s = json.toString(2);
|
||||
outputStream.write(s.getBytes("UTF-8"));
|
||||
} catch (JSONException e) {
|
||||
LOG.error("Failed to write json to stream", e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -1214,7 +1486,7 @@ public class SettingsHelper {
|
|||
item = new GlobalSettingsItem(settings);
|
||||
break;
|
||||
case PROFILE:
|
||||
item = new ProfileSettingsItem(settings, json);
|
||||
item = new ProfileSettingsItem(app, json);
|
||||
break;
|
||||
case PLUGIN:
|
||||
break;
|
||||
|
@ -1470,60 +1742,12 @@ public class SettingsHelper {
|
|||
}
|
||||
importSuspended = false;
|
||||
if (item != null) {
|
||||
if (item.exists()) {
|
||||
switch (item.getType()) {
|
||||
case PROFILE: {
|
||||
String title = activity.getString(R.string.overwrite_profile_q, item.getPublicName(app));
|
||||
dialog = showConfirmDialog(item, title, latestChanges);
|
||||
break;
|
||||
}
|
||||
case FILE:
|
||||
// overwrite now
|
||||
acceptItem(item);
|
||||
break;
|
||||
default:
|
||||
acceptItem(item);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (item.getType() == SettingsItemType.PROFILE && askBeforeImport) {
|
||||
String title = activity.getString(R.string.add_new_profile_q, item.getPublicName(app));
|
||||
dialog = showConfirmDialog(item, title, latestChanges);
|
||||
} else {
|
||||
acceptItem(item);
|
||||
}
|
||||
}
|
||||
acceptItem(item);
|
||||
} else {
|
||||
processNextItem();
|
||||
}
|
||||
}
|
||||
|
||||
private AlertDialog showConfirmDialog(final SettingsItem item, String title, String message) {
|
||||
AlertDialog.Builder b = new AlertDialog.Builder(activity);
|
||||
b.setTitle(title);
|
||||
b.setMessage(message);
|
||||
b.setPositiveButton(R.string.shared_string_yes, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
acceptItem(item);
|
||||
}
|
||||
});
|
||||
b.setNegativeButton(R.string.shared_string_no, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
processNextItem();
|
||||
}
|
||||
});
|
||||
b.setOnDismissListener(new DialogInterface.OnDismissListener() {
|
||||
@Override
|
||||
public void onDismiss(DialogInterface dialog) {
|
||||
ImportAsyncTask.this.dialog = null;
|
||||
}
|
||||
});
|
||||
b.setCancelable(false);
|
||||
return b.show();
|
||||
}
|
||||
|
||||
private void suspendImport() {
|
||||
if (dialog != null) {
|
||||
dialog.dismiss();
|
||||
|
@ -1607,6 +1831,7 @@ public class SettingsHelper {
|
|||
private SettingsExporter exporter;
|
||||
private File file;
|
||||
private SettingsExportListener listener;
|
||||
private ProgressDialog progress;
|
||||
|
||||
ExportAsyncTask(@NonNull File settingsFile,
|
||||
@Nullable SettingsExportListener listener,
|
||||
|
@ -1619,6 +1844,14 @@ public class SettingsHelper {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
super.onPreExecute();
|
||||
if (activity != null) {
|
||||
progress = ProgressDialog.show(activity, app.getString(R.string.export_profile), app.getString(R.string.shared_string_preparing));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Boolean doInBackground(Void... voids) {
|
||||
try {
|
||||
|
@ -1634,8 +1867,11 @@ public class SettingsHelper {
|
|||
|
||||
@Override
|
||||
protected void onPostExecute(Boolean success) {
|
||||
if (listener != null) {
|
||||
listener.onSettingsExportFinished(file, success);
|
||||
if (activity != null) {
|
||||
progress.dismiss();
|
||||
if (listener != null) {
|
||||
listener.onSettingsExportFinished(file, success);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import android.support.v7.view.ContextThemeWrapper;
|
|||
import android.support.v7.widget.SwitchCompat;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.ImageView;
|
||||
|
@ -537,4 +538,12 @@ public class UiUtilities {
|
|||
public static Context getThemedContext(Context context, boolean nightMode, int lightStyle, int darkStyle) {
|
||||
return new ContextThemeWrapper(context, nightMode ? darkStyle : lightStyle);
|
||||
}
|
||||
|
||||
public static void setMargins(View v, int l, int t, int r, int b) {
|
||||
if (v.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
|
||||
ViewGroup.MarginLayoutParams p = (ViewGroup.MarginLayoutParams) v.getLayoutParams();
|
||||
p.setMargins(l, t, r, b);
|
||||
v.requestLayout();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -35,7 +35,6 @@ import net.osmand.plus.helpers.GpxUiHelper;
|
|||
import net.osmand.plus.measurementtool.MeasurementToolLayer;
|
||||
import net.osmand.plus.poi.PoiFiltersHelper;
|
||||
import net.osmand.plus.poi.PoiUIFilter;
|
||||
import net.osmand.plus.quickaction.QuickActionRegistry;
|
||||
import net.osmand.plus.rastermaps.OsmandRasterMapsPlugin;
|
||||
import net.osmand.plus.render.MapVectorLayer;
|
||||
import net.osmand.plus.render.RenderingIcons;
|
||||
|
@ -92,7 +91,6 @@ public class MapActivityLayers {
|
|||
private MapQuickActionLayer mapQuickActionLayer;
|
||||
private DownloadedRegionsLayer downloadedRegionsLayer;
|
||||
private MapWidgetRegistry mapWidgetRegistry;
|
||||
private QuickActionRegistry quickActionRegistry;
|
||||
private MeasurementToolLayer measurementToolLayer;
|
||||
|
||||
private StateChangedListener<Integer> transparencyListener;
|
||||
|
@ -100,11 +98,6 @@ public class MapActivityLayers {
|
|||
public MapActivityLayers(MapActivity activity) {
|
||||
this.activity = activity;
|
||||
this.mapWidgetRegistry = new MapWidgetRegistry(activity.getMyApplication());
|
||||
this.quickActionRegistry = new QuickActionRegistry(activity.getMyApplication().getSettings());
|
||||
}
|
||||
|
||||
public QuickActionRegistry getQuickActionRegistry() {
|
||||
return quickActionRegistry;
|
||||
}
|
||||
|
||||
public MapWidgetRegistry getMapWidgetRegistry() {
|
||||
|
|
|
@ -192,7 +192,7 @@ public abstract class MenuBottomSheetDialogFragment extends BottomSheetDialogFra
|
|||
|
||||
final View contentView = useScrollableItemsContainer() ? mainView.findViewById(R.id.scroll_view) : itemsContainer;
|
||||
if (contentView.getHeight() > contentHeight) {
|
||||
if (useScrollableItemsContainer()) {
|
||||
if (useScrollableItemsContainer() || useExpandableList()) {
|
||||
contentView.getLayoutParams().height = contentHeight;
|
||||
} else {
|
||||
contentView.getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT;
|
||||
|
@ -231,6 +231,10 @@ public abstract class MenuBottomSheetDialogFragment extends BottomSheetDialogFra
|
|||
return true;
|
||||
}
|
||||
|
||||
protected boolean useExpandableList() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean hideButtonsContainer() {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ public class SelectMapViewQuickActionsBottomSheet extends MenuBottomSheetDialogF
|
|||
long id = args.getLong(SwitchableAction.KEY_ID);
|
||||
OsmandApplication app = mapActivity.getMyApplication();
|
||||
|
||||
QuickActionRegistry quickActionRegistry = mapActivity.getMapLayers().getQuickActionRegistry();
|
||||
QuickActionRegistry quickActionRegistry = app.getQuickActionRegistry();
|
||||
action = quickActionRegistry.getQuickAction(id);
|
||||
action = QuickActionFactory.produceAction(action);
|
||||
if (action == null) {
|
||||
|
|
|
@ -50,8 +50,8 @@ import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem;
|
|||
import net.osmand.plus.base.bottomsheetmenu.simpleitems.DividerHalfItem;
|
||||
import net.osmand.plus.base.bottomsheetmenu.simpleitems.ShortDescriptionItem;
|
||||
import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem;
|
||||
import net.osmand.plus.profiles.ExportImportProfileBottomSheet;
|
||||
import net.osmand.plus.rastermaps.OsmandRasterMapsPlugin;
|
||||
import net.osmand.plus.settings.ImportSettingsFragment;
|
||||
import net.osmand.plus.views.OsmandMapTileView;
|
||||
import net.osmand.router.RoutingConfiguration;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
@ -780,11 +780,7 @@ public class ImportHelper {
|
|||
if (succeed) {
|
||||
FragmentManager fragmentManager = activity.getSupportFragmentManager();
|
||||
if (fragmentManager != null) {
|
||||
ExportImportProfileBottomSheet.showInstance(
|
||||
fragmentManager,
|
||||
ExportImportProfileBottomSheet.State.IMPORT,
|
||||
file,
|
||||
items);
|
||||
ImportSettingsFragment.showInstance(fragmentManager, items, file);
|
||||
}
|
||||
} else {
|
||||
app.showShortToastMessage(app.getString(R.string.file_import_error, name, app.getString(R.string.shared_string_unexpected_error)));
|
||||
|
|
|
@ -125,6 +125,18 @@ public class PoiUIFilter implements SearchPoiTypeFilter, Comparable<PoiUIFilter>
|
|||
name = app.getPoiFilters().getFiltersName(filtersToMerge);
|
||||
}
|
||||
|
||||
public PoiUIFilter(PoiUIFilter filter, String name, String filterId) {
|
||||
this.app = filter.app;
|
||||
this.name = name;
|
||||
this.filterId = filterId;
|
||||
isStandardFilter = false;
|
||||
poiTypes = filter.poiTypes;
|
||||
acceptedTypes = filter.getAcceptedTypes();
|
||||
poiAdditionals = filter.getPoiAdditionals();
|
||||
filterByName = filter.filterByName;
|
||||
savedFilterByName = filter.savedFilterByName;
|
||||
}
|
||||
|
||||
public boolean isDeleted() {
|
||||
return deleted;
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ public class AdditionalDataWrapper {
|
|||
}
|
||||
|
||||
public enum Type {
|
||||
PROFILE,
|
||||
QUICK_ACTIONS,
|
||||
POI_TYPES,
|
||||
MAP_SOURCES,
|
||||
|
|
|
@ -1,711 +0,0 @@
|
|||
package net.osmand.plus.profiles;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.LayerDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v4.widget.CompoundButtonCompat;
|
||||
import android.support.v7.widget.SwitchCompat;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.ExpandableListView;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.IndexConstants;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.map.ITileSource;
|
||||
import net.osmand.map.TileSourceManager;
|
||||
import net.osmand.plus.ApplicationMode;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.SQLiteTileSource;
|
||||
import net.osmand.plus.SettingsHelper;
|
||||
import net.osmand.plus.UiUtilities;
|
||||
import net.osmand.plus.activities.OsmandBaseExpandableListAdapter;
|
||||
import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem;
|
||||
import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithCompoundButton;
|
||||
import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithDescription;
|
||||
import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem;
|
||||
import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem;
|
||||
import net.osmand.plus.poi.PoiUIFilter;
|
||||
import net.osmand.plus.quickaction.QuickAction;
|
||||
import net.osmand.plus.quickaction.QuickActionFactory;
|
||||
import net.osmand.plus.render.RenderingIcons;
|
||||
import net.osmand.plus.settings.BaseSettingsFragment;
|
||||
import net.osmand.plus.settings.bottomsheets.BasePreferenceBottomSheet;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ExportImportProfileBottomSheet extends BasePreferenceBottomSheet {
|
||||
|
||||
private static final Log LOG = PlatformUtil.getLog(ExportImportProfileBottomSheet.class);
|
||||
|
||||
public static final String TAG = ExportImportProfileBottomSheet.class.getSimpleName();
|
||||
|
||||
private static final String STATE_KEY = "EXPORT_IMPORT_DIALOG_STATE_KEY";
|
||||
|
||||
private static final String INCLUDE_ADDITIONAL_DATA_KEY = "INCLUDE_ADDITIONAL_DATA_KEY";
|
||||
|
||||
private boolean includeAdditionalData = false;
|
||||
|
||||
private boolean containsAdditionalData = false;
|
||||
|
||||
private OsmandApplication app;
|
||||
|
||||
private ApplicationMode profile;
|
||||
|
||||
private State state;
|
||||
|
||||
private List<AdditionalDataWrapper> dataList = new ArrayList<>();
|
||||
|
||||
private List<? super Object> dataToOperate = new ArrayList<>();
|
||||
|
||||
private List<SettingsHelper.SettingsItem> settingsItems;
|
||||
|
||||
private ExpandableListView listView;
|
||||
|
||||
private ProfileAdditionalDataAdapter adapter;
|
||||
|
||||
private SettingsHelper.ProfileSettingsItem profileSettingsItem;
|
||||
|
||||
private File file;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
if (savedInstanceState != null) {
|
||||
includeAdditionalData = savedInstanceState.getBoolean(INCLUDE_ADDITIONAL_DATA_KEY);
|
||||
}
|
||||
super.onCreate(savedInstanceState);
|
||||
app = requiredMyApplication();
|
||||
Bundle bundle = getArguments();
|
||||
if (bundle != null) {
|
||||
this.state = (State) getArguments().getSerializable(STATE_KEY);
|
||||
}
|
||||
if (state == State.IMPORT) {
|
||||
if (settingsItems == null) {
|
||||
settingsItems = app.getSettingsHelper().getSettingsItems();
|
||||
}
|
||||
if (file == null) {
|
||||
file = app.getSettingsHelper().getSettingsFile();
|
||||
}
|
||||
containsAdditionalData = checkAdditionalDataContains();
|
||||
} else {
|
||||
dataList = getAdditionalData();
|
||||
for (AdditionalDataWrapper dataWrapper : dataList) {
|
||||
dataToOperate.addAll(dataWrapper.getItems());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putBoolean(INCLUDE_ADDITIONAL_DATA_KEY, includeAdditionalData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createMenuItems(Bundle savedInstanceState) {
|
||||
final Context context = getContext();
|
||||
if (context == null) {
|
||||
return;
|
||||
}
|
||||
LayoutInflater inflater = UiUtilities.getInflater(app, nightMode);
|
||||
|
||||
profile = state == State.IMPORT ? getAppModeFromSettingsItems() : getAppMode();
|
||||
|
||||
int profileColor = profile.getIconColorInfo().getColor(nightMode);
|
||||
int colorNoAlpha = ContextCompat.getColor(context, profileColor);
|
||||
|
||||
Drawable backgroundIcon = UiUtilities.getColoredSelectableDrawable(context, colorNoAlpha, 0.3f);
|
||||
Drawable[] layers = {new ColorDrawable(UiUtilities.getColorWithAlpha(colorNoAlpha, 0.10f)), backgroundIcon};
|
||||
|
||||
items.add(new TitleItem(state == State.EXPORT ?
|
||||
getString(R.string.export_profile)
|
||||
: getString(R.string.import_profile)));
|
||||
|
||||
BaseBottomSheetItem profileItem = new BottomSheetItemWithCompoundButton.Builder()
|
||||
.setChecked(true)
|
||||
.setCompoundButtonColorId(profileColor)
|
||||
.setButtonTintList(ColorStateList.valueOf(getResolvedColor(profileColor)))
|
||||
.setDescription(BaseSettingsFragment.getAppModeDescription(context, profile))
|
||||
.setIcon(getIcon(profile.getIconRes(), profileColor))
|
||||
.setTitle(profile.toHumanString())
|
||||
.setBackground(new LayerDrawable(layers))
|
||||
.setLayoutId(R.layout.preference_profile_item_with_radio_btn)
|
||||
.create();
|
||||
items.add(profileItem);
|
||||
|
||||
if (state == State.IMPORT && containsAdditionalData || state == State.EXPORT && !dataList.isEmpty()) {
|
||||
BaseBottomSheetItem descriptionItem = new BottomSheetItemWithDescription.Builder()
|
||||
.setDescription(state == State.EXPORT ?
|
||||
getString(R.string.export_profile_dialog_description)
|
||||
: getString(R.string.import_profile_dialog_description))
|
||||
.setLayoutId(R.layout.bottom_sheet_item_pref_info)
|
||||
.create();
|
||||
items.add(descriptionItem);
|
||||
|
||||
final View additionalDataView = inflater.inflate(R.layout.bottom_sheet_item_additional_data, null);
|
||||
listView = additionalDataView.findViewById(R.id.list);
|
||||
SwitchCompat switchItem = additionalDataView.findViewById(R.id.switchItem);
|
||||
switchItem.setTextColor(getResources().getColor(nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light));
|
||||
switchItem.setChecked(includeAdditionalData);
|
||||
switchItem.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
includeAdditionalData = !includeAdditionalData;
|
||||
listView.setVisibility(includeAdditionalData ?
|
||||
View.VISIBLE : View.GONE);
|
||||
if (includeAdditionalData && state == State.IMPORT) {
|
||||
updateDataToOperateFromSettingsItems();
|
||||
}
|
||||
setupHeightAndBackground(getView());
|
||||
}
|
||||
});
|
||||
listView.setVisibility(includeAdditionalData ? View.VISIBLE : View.GONE);
|
||||
adapter = new ProfileAdditionalDataAdapter(app, dataList, profileColor);
|
||||
listView.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
|
||||
@Override
|
||||
public void onGroupExpand(int i) {
|
||||
setupHeightAndBackground(getView());
|
||||
}
|
||||
});
|
||||
listView.setAdapter(adapter);
|
||||
final SimpleBottomSheetItem titleItem = (SimpleBottomSheetItem) new SimpleBottomSheetItem.Builder()
|
||||
.setCustomView(additionalDataView)
|
||||
.create();
|
||||
items.add(titleItem);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getRightBottomButtonTextId() {
|
||||
return state == State.EXPORT ? R.string.shared_string_export : R.string.shared_string_import;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRightBottomButtonClick() {
|
||||
super.onRightBottomButtonClick();
|
||||
if (state == State.EXPORT) {
|
||||
prepareFile();
|
||||
} else {
|
||||
importSettings();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getDismissButtonTextId() {
|
||||
return R.string.shared_string_cancel;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean useScrollableItemsContainer() {
|
||||
return false;
|
||||
}
|
||||
|
||||
private ApplicationMode getAppModeFromSettingsItems() {
|
||||
for (SettingsHelper.SettingsItem item : settingsItems) {
|
||||
if (item.getType().equals(SettingsHelper.SettingsItemType.PROFILE)) {
|
||||
profileSettingsItem = ((SettingsHelper.ProfileSettingsItem) item);
|
||||
return ((SettingsHelper.ProfileSettingsItem) item).getAppMode();
|
||||
}
|
||||
}
|
||||
return getAppMode();
|
||||
}
|
||||
|
||||
private List<AdditionalDataWrapper> getAdditionalData() {
|
||||
List<AdditionalDataWrapper> dataList = new ArrayList<>();
|
||||
|
||||
QuickActionFactory factory = new QuickActionFactory();
|
||||
List<QuickAction> actionsList = factory.parseActiveActionsList(app.getSettings().QUICK_ACTION_LIST.get());
|
||||
if (!actionsList.isEmpty()) {
|
||||
dataList.add(new AdditionalDataWrapper(
|
||||
AdditionalDataWrapper.Type.QUICK_ACTIONS, actionsList));
|
||||
}
|
||||
|
||||
List<PoiUIFilter> poiList = app.getPoiFilters().getUserDefinedPoiFilters(false);
|
||||
if (!poiList.isEmpty()) {
|
||||
dataList.add(new AdditionalDataWrapper(
|
||||
AdditionalDataWrapper.Type.POI_TYPES,
|
||||
poiList
|
||||
));
|
||||
}
|
||||
|
||||
List<ITileSource> iTileSources = new ArrayList<>();
|
||||
final LinkedHashMap<String, String> tileSourceEntries = new LinkedHashMap<>(app.getSettings().getTileSourceEntries(true));
|
||||
for (Map.Entry<String, String> entry : tileSourceEntries.entrySet()) {
|
||||
File f = app.getAppPath(IndexConstants.TILES_INDEX_DIR + entry.getKey());
|
||||
if (f != null) {
|
||||
ITileSource template;
|
||||
if (f.getName().endsWith(SQLiteTileSource.EXT)) {
|
||||
template = new SQLiteTileSource(app, f, TileSourceManager.getKnownSourceTemplates());
|
||||
} else {
|
||||
template = TileSourceManager.createTileSourceTemplate(f);
|
||||
}
|
||||
if (template != null && template.getUrlTemplate() != null) {
|
||||
iTileSources.add(template);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!iTileSources.isEmpty()) {
|
||||
dataList.add(new AdditionalDataWrapper(
|
||||
AdditionalDataWrapper.Type.MAP_SOURCES,
|
||||
iTileSources
|
||||
));
|
||||
}
|
||||
|
||||
Map<String, File> externalRenderers = app.getRendererRegistry().getExternalRenderers();
|
||||
if (!externalRenderers.isEmpty()) {
|
||||
dataList.add(new AdditionalDataWrapper(
|
||||
AdditionalDataWrapper.Type.CUSTOM_RENDER_STYLE,
|
||||
new ArrayList<>(externalRenderers.values())
|
||||
));
|
||||
}
|
||||
|
||||
File routingProfilesFolder = app.getAppPath(IndexConstants.ROUTING_PROFILES_DIR);
|
||||
if (routingProfilesFolder.exists() && routingProfilesFolder.isDirectory()) {
|
||||
File[] fl = routingProfilesFolder.listFiles();
|
||||
if (fl != null && fl.length > 0) {
|
||||
dataList.add(new AdditionalDataWrapper(
|
||||
AdditionalDataWrapper.Type.CUSTOM_ROUTING,
|
||||
Arrays.asList(fl)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
return dataList;
|
||||
}
|
||||
|
||||
private List<SettingsHelper.SettingsItem> prepareSettingsItemsForExport() {
|
||||
List<SettingsHelper.SettingsItem> settingsItems = new ArrayList<>();
|
||||
settingsItems.add(new SettingsHelper.ProfileSettingsItem(app.getSettings(), profile));
|
||||
if (includeAdditionalData) {
|
||||
settingsItems.addAll(prepareAdditionalSettingsItems());
|
||||
}
|
||||
return settingsItems;
|
||||
}
|
||||
|
||||
private List<SettingsHelper.SettingsItem> prepareAdditionalSettingsItems() {
|
||||
List<SettingsHelper.SettingsItem> settingsItems = new ArrayList<>();
|
||||
List<QuickAction> quickActions = new ArrayList<>();
|
||||
List<PoiUIFilter> poiUIFilters = new ArrayList<>();
|
||||
List<ITileSource> tileSourceTemplates = new ArrayList<>();
|
||||
for (Object object : dataToOperate) {
|
||||
if (object instanceof QuickAction) {
|
||||
quickActions.add((QuickAction) object);
|
||||
} else if (object instanceof PoiUIFilter) {
|
||||
poiUIFilters.add((PoiUIFilter) object);
|
||||
} else if (object instanceof TileSourceManager.TileSourceTemplate
|
||||
|| object instanceof SQLiteTileSource) {
|
||||
tileSourceTemplates.add((ITileSource) object);
|
||||
} else if (object instanceof File) {
|
||||
settingsItems.add(new SettingsHelper.FileSettingsItem(app, (File) object));
|
||||
}
|
||||
}
|
||||
if (!quickActions.isEmpty()) {
|
||||
settingsItems.add(new SettingsHelper.QuickActionSettingsItem(app, quickActions));
|
||||
}
|
||||
if (!poiUIFilters.isEmpty()) {
|
||||
settingsItems.add(new SettingsHelper.PoiUiFilterSettingsItem(app, poiUIFilters));
|
||||
}
|
||||
if (!tileSourceTemplates.isEmpty()) {
|
||||
settingsItems.add(new SettingsHelper.MapSourcesSettingsItem(app, tileSourceTemplates));
|
||||
}
|
||||
return settingsItems;
|
||||
}
|
||||
|
||||
private Boolean checkAdditionalDataContains() {
|
||||
boolean containsData = false;
|
||||
for (SettingsHelper.SettingsItem item : settingsItems) {
|
||||
containsData = item.getType().equals(SettingsHelper.SettingsItemType.QUICK_ACTION)
|
||||
|| item.getType().equals(SettingsHelper.SettingsItemType.POI_UI_FILTERS)
|
||||
|| item.getType().equals(SettingsHelper.SettingsItemType.MAP_SOURCES)
|
||||
|| item.getType().equals(SettingsHelper.SettingsItemType.FILE);
|
||||
if (containsData) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return containsData;
|
||||
}
|
||||
|
||||
private void updateDataToOperateFromSettingsItems() {
|
||||
List<AdditionalDataWrapper> dataList = new ArrayList<>();
|
||||
List<QuickAction> quickActions = new ArrayList<>();
|
||||
List<PoiUIFilter> poiUIFilters = new ArrayList<>();
|
||||
List<ITileSource> tileSourceTemplates = new ArrayList<>();
|
||||
List<File> routingFilesList = new ArrayList<>();
|
||||
List<File> renderFilesList = new ArrayList<>();
|
||||
|
||||
for (SettingsHelper.SettingsItem item : settingsItems) {
|
||||
if (item.getType().equals(SettingsHelper.SettingsItemType.QUICK_ACTION)) {
|
||||
quickActions.addAll(((SettingsHelper.QuickActionSettingsItem) item).getQuickActions());
|
||||
} else if (item.getType().equals(SettingsHelper.SettingsItemType.POI_UI_FILTERS)) {
|
||||
poiUIFilters.addAll(((SettingsHelper.PoiUiFilterSettingsItem) item).getPoiUIFilters());
|
||||
} else if (item.getType().equals(SettingsHelper.SettingsItemType.MAP_SOURCES)) {
|
||||
tileSourceTemplates.addAll(((SettingsHelper.MapSourcesSettingsItem) item).getMapSources());
|
||||
} else if (item.getType().equals(SettingsHelper.SettingsItemType.FILE)) {
|
||||
if (item.getName().startsWith("/rendering/")) {
|
||||
renderFilesList.add(((SettingsHelper.FileSettingsItem) item).getFile());
|
||||
} else if (item.getName().startsWith("/routing/")) {
|
||||
routingFilesList.add(((SettingsHelper.FileSettingsItem) item).getFile());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!quickActions.isEmpty()) {
|
||||
dataList.add(new AdditionalDataWrapper(
|
||||
AdditionalDataWrapper.Type.QUICK_ACTIONS,
|
||||
quickActions));
|
||||
dataToOperate.addAll(quickActions);
|
||||
}
|
||||
if (!poiUIFilters.isEmpty()) {
|
||||
dataList.add(new AdditionalDataWrapper(
|
||||
AdditionalDataWrapper.Type.POI_TYPES,
|
||||
poiUIFilters));
|
||||
dataToOperate.addAll(poiUIFilters);
|
||||
}
|
||||
if (!tileSourceTemplates.isEmpty()) {
|
||||
dataList.add(new AdditionalDataWrapper(
|
||||
AdditionalDataWrapper.Type.MAP_SOURCES,
|
||||
tileSourceTemplates
|
||||
));
|
||||
dataToOperate.addAll(tileSourceTemplates);
|
||||
}
|
||||
if (!renderFilesList.isEmpty()) {
|
||||
dataList.add(new AdditionalDataWrapper(
|
||||
AdditionalDataWrapper.Type.CUSTOM_RENDER_STYLE,
|
||||
renderFilesList
|
||||
));
|
||||
dataToOperate.addAll(renderFilesList);
|
||||
}
|
||||
if (!routingFilesList.isEmpty()) {
|
||||
dataList.add(new AdditionalDataWrapper(
|
||||
AdditionalDataWrapper.Type.CUSTOM_ROUTING,
|
||||
routingFilesList
|
||||
));
|
||||
dataToOperate.addAll(routingFilesList);
|
||||
}
|
||||
adapter.updateList(dataList);
|
||||
}
|
||||
|
||||
private void importSettings() {
|
||||
List<SettingsHelper.SettingsItem> list = new ArrayList<>();
|
||||
list.add(profileSettingsItem);
|
||||
if (includeAdditionalData) {
|
||||
list.addAll(prepareAdditionalSettingsItems());
|
||||
}
|
||||
app.getSettingsHelper().importSettings(file, list, "", 1, new SettingsHelper.SettingsImportListener() {
|
||||
@Override
|
||||
public void onSettingsImportFinished(boolean succeed, boolean empty, @NonNull List<SettingsHelper.SettingsItem> items) {
|
||||
if (succeed) {
|
||||
app.showShortToastMessage(app.getString(R.string.file_imported_successfully, file.getName()));
|
||||
} else if (empty) {
|
||||
app.showShortToastMessage(app.getString(R.string.file_import_error, file.getName(), app.getString(R.string.shared_string_unexpected_error)));
|
||||
}
|
||||
}
|
||||
});
|
||||
dismiss();
|
||||
}
|
||||
|
||||
private void prepareFile() {
|
||||
if (app != null) {
|
||||
File tempDir = app.getAppPath(IndexConstants.TEMP_DIR);
|
||||
if (!tempDir.exists()) {
|
||||
tempDir.mkdirs();
|
||||
}
|
||||
String fileName = profile.toHumanString();
|
||||
app.getSettingsHelper().exportSettings(tempDir, fileName, new SettingsHelper.SettingsExportListener() {
|
||||
@Override
|
||||
public void onSettingsExportFinished(@NonNull File file, boolean succeed) {
|
||||
if (succeed) {
|
||||
shareProfile(file, profile);
|
||||
} else {
|
||||
app.showToastMessage(R.string.export_profile_failed);
|
||||
}
|
||||
}
|
||||
}, prepareSettingsItemsForExport());
|
||||
}
|
||||
}
|
||||
|
||||
private void shareProfile(@NonNull File file, @NonNull ApplicationMode profile) {
|
||||
try {
|
||||
final Intent sendIntent = new Intent();
|
||||
sendIntent.setAction(Intent.ACTION_SEND);
|
||||
sendIntent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.exported_osmand_profile, profile.toHumanString()));
|
||||
sendIntent.putExtra(Intent.EXTRA_STREAM, AndroidUtils.getUriForFile(getMyApplication(), file));
|
||||
sendIntent.setType("*/*");
|
||||
sendIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
startActivity(sendIntent);
|
||||
dismiss();
|
||||
} catch (Exception e) {
|
||||
Toast.makeText(requireContext(), R.string.export_profile_failed, Toast.LENGTH_SHORT).show();
|
||||
LOG.error("Share profile error", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean showInstance(@NonNull FragmentManager fragmentManager,
|
||||
State state,
|
||||
Fragment target,
|
||||
@NonNull ApplicationMode appMode) {
|
||||
try {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putSerializable(STATE_KEY, state);
|
||||
ExportImportProfileBottomSheet fragment = new ExportImportProfileBottomSheet();
|
||||
fragment.setArguments(bundle);
|
||||
fragment.setAppMode(appMode);
|
||||
fragment.setTargetFragment(target, 0);
|
||||
fragment.show(fragmentManager, TAG);
|
||||
return true;
|
||||
} catch (RuntimeException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean showInstance(@NonNull FragmentManager fragmentManager,
|
||||
State state,
|
||||
File file,
|
||||
List<SettingsHelper.SettingsItem> items) {
|
||||
try {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putSerializable(STATE_KEY, state);
|
||||
ExportImportProfileBottomSheet fragment = new ExportImportProfileBottomSheet();
|
||||
fragment.setArguments(bundle);
|
||||
fragment.setSettingsItems(items);
|
||||
fragment.setFile(file);
|
||||
fragment.show(fragmentManager, TAG);
|
||||
return true;
|
||||
} catch (RuntimeException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void setSettingsItems(List<SettingsHelper.SettingsItem> settingsItems) {
|
||||
this.settingsItems = settingsItems;
|
||||
}
|
||||
|
||||
public File getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
public void setFile(File file) {
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
public enum State {
|
||||
EXPORT,
|
||||
IMPORT
|
||||
}
|
||||
|
||||
class ProfileAdditionalDataAdapter extends OsmandBaseExpandableListAdapter {
|
||||
|
||||
private OsmandApplication app;
|
||||
|
||||
private List<AdditionalDataWrapper> list;
|
||||
|
||||
private int profileColor;
|
||||
|
||||
ProfileAdditionalDataAdapter(OsmandApplication app, List<AdditionalDataWrapper> list, int profileColor) {
|
||||
this.app = app;
|
||||
this.list = list;
|
||||
this.profileColor = profileColor;
|
||||
}
|
||||
|
||||
public void updateList(List<AdditionalDataWrapper> list) {
|
||||
this.list = list;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getGroupCount() {
|
||||
return list.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChildrenCount(int i) {
|
||||
return list.get(i).getItems().size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getGroup(int i) {
|
||||
return list.get(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getChild(int groupPosition, int childPosition) {
|
||||
return list.get(groupPosition).getItems().get(childPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getGroupId(int i) {
|
||||
return i;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getChildId(int groupPosition, int childPosition) {
|
||||
return groupPosition * 10000 + childPosition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasStableIds() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
|
||||
View group = convertView;
|
||||
if (group == null) {
|
||||
LayoutInflater inflater = UiUtilities.getInflater(app, nightMode);
|
||||
group = inflater.inflate(R.layout.profile_data_list_item_group, parent, false);
|
||||
}
|
||||
|
||||
boolean isLastGroup = groupPosition == getGroupCount() - 1;
|
||||
final AdditionalDataWrapper.Type type = list.get(groupPosition).getType();
|
||||
|
||||
TextView titleTv = group.findViewById(R.id.title_tv);
|
||||
TextView subTextTv = group.findViewById(R.id.sub_text_tv);
|
||||
final CheckBox checkBox = group.findViewById(R.id.check_box);
|
||||
ImageView expandIv = group.findViewById(R.id.explist_indicator);
|
||||
View divider = group.findViewById(R.id.divider);
|
||||
|
||||
titleTv.setText(getGroupTitle(type));
|
||||
divider.setVisibility(isExpanded || isLastGroup ? View.GONE : View.VISIBLE);
|
||||
CompoundButtonCompat.setButtonTintList(checkBox, ColorStateList.valueOf(ContextCompat.getColor(app, profileColor)));
|
||||
|
||||
final List<?> listItems = list.get(groupPosition).getItems();
|
||||
subTextTv.setText(String.valueOf(listItems.size()));
|
||||
|
||||
checkBox.setChecked(dataToOperate.containsAll(listItems));
|
||||
checkBox.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
|
||||
if (checkBox.isChecked()) {
|
||||
for (Object object : listItems) {
|
||||
if (!dataToOperate.contains(object)) {
|
||||
dataToOperate.add(object);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
dataToOperate.removeAll(listItems);
|
||||
}
|
||||
notifyDataSetInvalidated();
|
||||
}
|
||||
});
|
||||
|
||||
adjustIndicator(app, groupPosition, isExpanded, group, true);
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getChildView(int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
|
||||
View child = convertView;
|
||||
if (child == null) {
|
||||
LayoutInflater inflater = UiUtilities.getInflater(app, nightMode);
|
||||
child = inflater.inflate(R.layout.profile_data_list_item_child, parent, false);
|
||||
}
|
||||
final Object currentItem = list.get(groupPosition).getItems().get(childPosition);
|
||||
|
||||
|
||||
boolean isLastGroup = groupPosition == getGroupCount() - 1;
|
||||
final AdditionalDataWrapper.Type type = list.get(groupPosition).getType();
|
||||
|
||||
TextView title = child.findViewById(R.id.title_tv);
|
||||
final CheckBox checkBox = child.findViewById(R.id.check_box);
|
||||
ImageView icon = child.findViewById(R.id.icon);
|
||||
View divider = child.findViewById(R.id.divider);
|
||||
|
||||
divider.setVisibility(isLastChild && !isLastGroup ? View.VISIBLE : View.GONE);
|
||||
CompoundButtonCompat.setButtonTintList(checkBox, ColorStateList.valueOf(ContextCompat.getColor(app, profileColor)));
|
||||
|
||||
checkBox.setChecked(dataToOperate.contains(currentItem));
|
||||
checkBox.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (checkBox.isChecked()) {
|
||||
dataToOperate.add(currentItem);
|
||||
} else {
|
||||
dataToOperate.remove(currentItem);
|
||||
}
|
||||
notifyDataSetInvalidated();
|
||||
}
|
||||
});
|
||||
|
||||
switch (type) {
|
||||
case QUICK_ACTIONS:
|
||||
title.setText(((QuickAction) currentItem).getName(app.getApplicationContext()));
|
||||
icon.setVisibility(View.INVISIBLE);
|
||||
icon.setImageResource(R.drawable.ic_action_info_dark);
|
||||
break;
|
||||
case POI_TYPES:
|
||||
title.setText(((PoiUIFilter) currentItem).getName());
|
||||
icon.setVisibility(View.VISIBLE);
|
||||
int iconRes = RenderingIcons.getBigIconResourceId(((PoiUIFilter) currentItem).getIconId());
|
||||
icon.setImageDrawable(app.getUIUtilities().getIcon(iconRes != 0 ? iconRes : R.drawable.ic_person, profileColor));
|
||||
break;
|
||||
case MAP_SOURCES:
|
||||
title.setText(((ITileSource) currentItem).getName());
|
||||
icon.setVisibility(View.INVISIBLE);
|
||||
icon.setImageResource(R.drawable.ic_action_info_dark);
|
||||
break;
|
||||
case CUSTOM_RENDER_STYLE:
|
||||
String renderName = ((File) currentItem).getName();
|
||||
renderName = renderName.replace('_', ' ').replaceAll(".render.xml", "");
|
||||
title.setText(renderName);
|
||||
icon.setVisibility(View.INVISIBLE);
|
||||
icon.setImageResource(R.drawable.ic_action_info_dark);
|
||||
break;
|
||||
case CUSTOM_ROUTING:
|
||||
String routingName = ((File) currentItem).getName();
|
||||
routingName = routingName.replace('_', ' ').replaceAll(".xml", "");
|
||||
title.setText(routingName);
|
||||
icon.setVisibility(View.INVISIBLE);
|
||||
icon.setImageResource(R.drawable.ic_action_info_dark);
|
||||
break;
|
||||
default:
|
||||
return child;
|
||||
}
|
||||
return child;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChildSelectable(int i, int i1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
private int getGroupTitle(AdditionalDataWrapper.Type type) {
|
||||
switch (type) {
|
||||
case QUICK_ACTIONS:
|
||||
return R.string.configure_screen_quick_action;
|
||||
case POI_TYPES:
|
||||
return R.string.poi_dialog_poi_type;
|
||||
case MAP_SOURCES:
|
||||
return R.string.quick_action_map_source_title;
|
||||
case CUSTOM_RENDER_STYLE:
|
||||
return R.string.shared_string_custom_rendering_style;
|
||||
case CUSTOM_ROUTING:
|
||||
return R.string.shared_string_routing;
|
||||
default:
|
||||
return R.string.access_empty_list;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -49,7 +49,7 @@ public class AddQuickActionDialog extends DialogFragment {
|
|||
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
|
||||
|
||||
List<QuickAction> active = ((MapActivity) getActivity())
|
||||
.getMapLayers()
|
||||
.getMyApplication()
|
||||
.getQuickActionRegistry()
|
||||
.getQuickActions();
|
||||
|
||||
|
|
|
@ -106,7 +106,7 @@ public class CreateEditActionDialog extends DialogFragment {
|
|||
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
quickActionRegistry = ((MapActivity) getActivity()).getMapLayers().getQuickActionRegistry();
|
||||
quickActionRegistry = getApplication().getQuickActionRegistry();
|
||||
|
||||
long actionId = savedInstanceState == null
|
||||
? getArguments().getLong(KEY_ACTION_ID)
|
||||
|
|
|
@ -157,5 +157,8 @@ public class QuickAction {
|
|||
result = 31 * result + (name != null ? name.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasCustomName(Context context) {
|
||||
return !getName(context).equals(context.getString(nameRes));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@ public class QuickActionListFragment extends BaseOsmAndFragment implements Quick
|
|||
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
quickActionRegistry = getMapActivity().getMapLayers().getQuickActionRegistry();
|
||||
quickActionRegistry = getMyApplication().getQuickActionRegistry();
|
||||
|
||||
setUpToolbar(view);
|
||||
setUpQuickActionRV();
|
||||
|
|
|
@ -28,20 +28,16 @@ import android.widget.TextView;
|
|||
import android.widget.Toast;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.IndexConstants;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.plus.ApplicationMode;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.OsmandPlugin;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.SettingsHelper;
|
||||
import net.osmand.plus.SettingsHelper.ProfileSettingsItem;
|
||||
import net.osmand.plus.UiUtilities;
|
||||
import net.osmand.plus.activities.MapActivity;
|
||||
import net.osmand.plus.helpers.AndroidUiHelper;
|
||||
import net.osmand.plus.helpers.FontCache;
|
||||
import net.osmand.plus.openseamapsplugin.NauticalMapsPlugin;
|
||||
import net.osmand.plus.profiles.ExportImportProfileBottomSheet;
|
||||
import net.osmand.plus.profiles.SelectCopyAppModeBottomSheet;
|
||||
import net.osmand.plus.profiles.SelectCopyAppModeBottomSheet.CopyAppModePrefsListener;
|
||||
import net.osmand.plus.settings.bottomsheets.ResetProfilePrefsBottomSheet;
|
||||
|
@ -403,9 +399,8 @@ public class ConfigureProfileFragment extends BaseSettingsFragment implements Co
|
|||
} else if (EXPORT_PROFILE.equals(prefId)) {
|
||||
FragmentManager fragmentManager = getFragmentManager();
|
||||
if (fragmentManager != null) {
|
||||
ExportImportProfileBottomSheet.showInstance(
|
||||
ExportProfileBottomSheet.showInstance(
|
||||
fragmentManager,
|
||||
ExportImportProfileBottomSheet.State.EXPORT,
|
||||
this,
|
||||
getSelectedAppMode());
|
||||
}
|
||||
|
|
|
@ -0,0 +1,177 @@
|
|||
package net.osmand.plus.settings;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.map.ITileSource;
|
||||
import net.osmand.plus.ApplicationMode;
|
||||
import net.osmand.plus.ApplicationMode.ApplicationModeBean;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.UiUtilities;
|
||||
import net.osmand.plus.poi.PoiUIFilter;
|
||||
import net.osmand.plus.profiles.ProfileIconColors;
|
||||
import net.osmand.plus.quickaction.QuickAction;
|
||||
import net.osmand.plus.render.RenderingIcons;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
public class DuplicatesSettingsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
||||
|
||||
private static final int HEADER_TYPE = 0;
|
||||
private static final int ITEM_TYPE = 1;
|
||||
|
||||
private boolean nightMode;
|
||||
private OsmandApplication app;
|
||||
private UiUtilities uiUtilities;
|
||||
private List<? super Object> items;
|
||||
|
||||
DuplicatesSettingsAdapter(OsmandApplication app, List<? super Object> items, boolean nightMode) {
|
||||
this.app = app;
|
||||
this.items = items;
|
||||
this.nightMode = nightMode;
|
||||
this.uiUtilities = app.getUIUtilities();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
LayoutInflater inflater = LayoutInflater.from(app);
|
||||
if (viewType == HEADER_TYPE) {
|
||||
View view = inflater.inflate(R.layout.list_item_header_import, parent, false);
|
||||
return new HeaderViewHolder(view);
|
||||
} else {
|
||||
View view = inflater.inflate(R.layout.list_item_import, parent, false);
|
||||
return new ItemViewHolder(view);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
|
||||
Object currentItem = items.get(position);
|
||||
if (holder instanceof HeaderViewHolder) {
|
||||
HeaderViewHolder headerHolder = (HeaderViewHolder) holder;
|
||||
headerHolder.title.setText((String) currentItem);
|
||||
headerHolder.subTitle.setText(String.format(
|
||||
app.getString(R.string.listed_exist),
|
||||
(String) currentItem));
|
||||
headerHolder.divider.setVisibility(View.VISIBLE);
|
||||
} else if (holder instanceof ItemViewHolder) {
|
||||
ItemViewHolder itemHolder = (ItemViewHolder) holder;
|
||||
if (currentItem instanceof ApplicationModeBean) {
|
||||
ApplicationModeBean modeBean = (ApplicationModeBean) currentItem;
|
||||
String profileName = modeBean.userProfileName;
|
||||
if (Algorithms.isEmpty(profileName)) {
|
||||
ApplicationMode appMode = ApplicationMode.valueOfStringKey(modeBean.stringKey, null);
|
||||
profileName = app.getString(appMode.getNameKeyResource());
|
||||
}
|
||||
itemHolder.title.setText(profileName);
|
||||
String routingProfile = modeBean.routingProfile;
|
||||
if (Algorithms.isEmpty(routingProfile)) {
|
||||
itemHolder.subTitle.setVisibility(View.GONE);
|
||||
} else {
|
||||
itemHolder.subTitle.setText(String.format(
|
||||
app.getString(R.string.ltr_or_rtl_combine_via_colon),
|
||||
app.getString(R.string.nav_type_hint),
|
||||
routingProfile));
|
||||
itemHolder.subTitle.setVisibility(View.VISIBLE);
|
||||
}
|
||||
int profileIconRes = AndroidUtils.getDrawableId(app, modeBean.iconName);
|
||||
ProfileIconColors iconColor = modeBean.iconColor;
|
||||
itemHolder.icon.setImageDrawable(uiUtilities.getIcon(profileIconRes, iconColor.getColor(nightMode)));
|
||||
itemHolder.icon.setVisibility(View.VISIBLE);
|
||||
} else if (currentItem instanceof QuickAction) {
|
||||
QuickAction action = (QuickAction) currentItem;
|
||||
itemHolder.title.setText(action.getName(app));
|
||||
itemHolder.icon.setImageDrawable(uiUtilities.getIcon(action.getIconRes(), nightMode));
|
||||
itemHolder.subTitle.setVisibility(View.GONE);
|
||||
itemHolder.icon.setVisibility(View.VISIBLE);
|
||||
} else if (currentItem instanceof PoiUIFilter) {
|
||||
PoiUIFilter filter = (PoiUIFilter) currentItem;
|
||||
itemHolder.title.setText(filter.getName());
|
||||
int iconRes = RenderingIcons.getBigIconResourceId(filter.getIconId());
|
||||
itemHolder.icon.setImageDrawable(uiUtilities.getIcon(iconRes != 0 ? iconRes : R.drawable.ic_person, nightMode));
|
||||
itemHolder.subTitle.setVisibility(View.GONE);
|
||||
itemHolder.icon.setVisibility(View.VISIBLE);
|
||||
} else if (currentItem instanceof ITileSource) {
|
||||
itemHolder.title.setText(((ITileSource) currentItem).getName());
|
||||
itemHolder.icon.setImageResource(R.drawable.ic_action_info_dark);
|
||||
itemHolder.subTitle.setVisibility(View.GONE);
|
||||
itemHolder.icon.setVisibility(View.INVISIBLE);
|
||||
} else if (currentItem instanceof File) {
|
||||
File file = (File) currentItem;
|
||||
itemHolder.title.setText(file.getName());
|
||||
if (file.getName().contains("/rendering/")) {
|
||||
itemHolder.icon.setImageDrawable(uiUtilities.getIcon(R.drawable.ic_action_map_style, nightMode));
|
||||
itemHolder.icon.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
itemHolder.icon.setImageResource(R.drawable.ic_action_info_dark);
|
||||
itemHolder.icon.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
itemHolder.subTitle.setVisibility(View.GONE);
|
||||
}
|
||||
itemHolder.divider.setVisibility(shouldShowDivider(position) ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return items.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
if (items.get(position) instanceof String) {
|
||||
return HEADER_TYPE;
|
||||
} else {
|
||||
return ITEM_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
private class HeaderViewHolder extends RecyclerView.ViewHolder {
|
||||
TextView title;
|
||||
TextView subTitle;
|
||||
View divider;
|
||||
|
||||
HeaderViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
title = itemView.findViewById(R.id.title);
|
||||
subTitle = itemView.findViewById(R.id.sub_title);
|
||||
divider = itemView.findViewById(R.id.top_divider);
|
||||
}
|
||||
}
|
||||
|
||||
private class ItemViewHolder extends RecyclerView.ViewHolder {
|
||||
TextView title;
|
||||
TextView subTitle;
|
||||
ImageView icon;
|
||||
View divider;
|
||||
|
||||
ItemViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
title = itemView.findViewById(R.id.title);
|
||||
subTitle = itemView.findViewById(R.id.sub_title);
|
||||
icon = itemView.findViewById(R.id.icon);
|
||||
divider = itemView.findViewById(R.id.bottom_divider);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean shouldShowDivider(int position) {
|
||||
boolean isLast = position == items.size() - 1;
|
||||
if (isLast) {
|
||||
return true;
|
||||
} else {
|
||||
Object next = items.get(position + 1);
|
||||
return next instanceof String;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,304 @@
|
|||
package net.osmand.plus.settings;
|
||||
|
||||
import android.content.res.ColorStateList;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v4.widget.CompoundButtonCompat;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.map.ITileSource;
|
||||
import net.osmand.plus.ApplicationMode;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.UiUtilities;
|
||||
import net.osmand.plus.activities.OsmandBaseExpandableListAdapter;
|
||||
import net.osmand.plus.poi.PoiUIFilter;
|
||||
import net.osmand.plus.profiles.AdditionalDataWrapper;
|
||||
import net.osmand.plus.profiles.ProfileIconColors;
|
||||
import net.osmand.plus.quickaction.QuickAction;
|
||||
import net.osmand.plus.render.RenderingIcons;
|
||||
import net.osmand.util.Algorithms;
|
||||
import net.osmand.view.ThreeStateCheckbox;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static net.osmand.view.ThreeStateCheckbox.State.CHECKED;
|
||||
import static net.osmand.view.ThreeStateCheckbox.State.UNCHECKED;
|
||||
import static net.osmand.view.ThreeStateCheckbox.State.MISC;
|
||||
|
||||
class ExportImportSettingsAdapter extends OsmandBaseExpandableListAdapter {
|
||||
|
||||
private OsmandApplication app;
|
||||
private List<? super Object> dataToOperate;
|
||||
private List<AdditionalDataWrapper> dataList;
|
||||
private boolean nightMode;
|
||||
private boolean importState;
|
||||
private int profileColor;
|
||||
|
||||
ExportImportSettingsAdapter(OsmandApplication app, List<AdditionalDataWrapper> dataList, boolean nightMode, boolean importState) {
|
||||
this.app = app;
|
||||
this.dataList = dataList;
|
||||
this.nightMode = nightMode;
|
||||
this.importState = importState;
|
||||
this.dataToOperate = new ArrayList<>();
|
||||
this.profileColor = app.getSettings().getApplicationMode().getIconColorInfo().getColor(nightMode);
|
||||
}
|
||||
|
||||
ExportImportSettingsAdapter(OsmandApplication app, boolean nightMode) {
|
||||
this.app = app;
|
||||
this.nightMode = nightMode;
|
||||
this.dataList = new ArrayList<>();
|
||||
this.dataToOperate = new ArrayList<>();
|
||||
this.profileColor = app.getSettings().getApplicationMode().getIconColorInfo().getColor(nightMode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
|
||||
View group = convertView;
|
||||
if (group == null) {
|
||||
LayoutInflater inflater = UiUtilities.getInflater(app, nightMode);
|
||||
group = inflater.inflate(R.layout.profile_data_list_item_group, parent, false);
|
||||
}
|
||||
|
||||
boolean isLastGroup = groupPosition == getGroupCount() - 1;
|
||||
final AdditionalDataWrapper.Type type = dataList.get(groupPosition).getType();
|
||||
|
||||
TextView titleTv = group.findViewById(R.id.title_tv);
|
||||
TextView subTextTv = group.findViewById(R.id.sub_text_tv);
|
||||
final ThreeStateCheckbox checkBox = group.findViewById(R.id.check_box);
|
||||
ImageView expandIv = group.findViewById(R.id.explist_indicator);
|
||||
View lineDivider = group.findViewById(R.id.divider);
|
||||
View cardTopDivider = group.findViewById(R.id.card_top_divider);
|
||||
View cardBottomDivider = group.findViewById(R.id.card_bottom_divider);
|
||||
|
||||
titleTv.setText(getGroupTitle(type));
|
||||
lineDivider.setVisibility(importState || isExpanded || isLastGroup ? View.GONE : View.VISIBLE);
|
||||
cardTopDivider.setVisibility(importState ? View.VISIBLE : View.GONE);
|
||||
cardBottomDivider.setVisibility(importState && !isExpanded ? View.VISIBLE : View.GONE);
|
||||
CompoundButtonCompat.setButtonTintList(checkBox, ColorStateList.valueOf(ContextCompat.getColor(app, profileColor)));
|
||||
|
||||
final List<?> listItems = dataList.get(groupPosition).getItems();
|
||||
subTextTv.setText(String.valueOf(listItems.size()));
|
||||
|
||||
if (dataToOperate.containsAll(listItems)) {
|
||||
checkBox.setState(CHECKED);
|
||||
} else {
|
||||
boolean contains = false;
|
||||
for (Object object : listItems) {
|
||||
if (dataToOperate.contains(object)) {
|
||||
contains = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
checkBox.setState(contains ? MISC : UNCHECKED);
|
||||
}
|
||||
checkBox.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (checkBox.getState() == CHECKED) {
|
||||
for (Object object : listItems) {
|
||||
if (!dataToOperate.contains(object)) {
|
||||
dataToOperate.add(object);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
dataToOperate.removeAll(listItems);
|
||||
}
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
});
|
||||
adjustIndicator(app, groupPosition, isExpanded, group, true);
|
||||
return group;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getChildView(int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
|
||||
View child = convertView;
|
||||
if (child == null) {
|
||||
LayoutInflater inflater = UiUtilities.getInflater(app, nightMode);
|
||||
child = inflater.inflate(R.layout.profile_data_list_item_child, parent, false);
|
||||
}
|
||||
final Object currentItem = dataList.get(groupPosition).getItems().get(childPosition);
|
||||
|
||||
boolean isLastGroup = groupPosition == getGroupCount() - 1;
|
||||
final AdditionalDataWrapper.Type type = dataList.get(groupPosition).getType();
|
||||
|
||||
TextView title = child.findViewById(R.id.title_tv);
|
||||
TextView subText = child.findViewById(R.id.sub_title_tv);
|
||||
final CheckBox checkBox = child.findViewById(R.id.check_box);
|
||||
ImageView icon = child.findViewById(R.id.icon);
|
||||
View lineDivider = child.findViewById(R.id.divider);
|
||||
View cardBottomDivider = child.findViewById(R.id.card_bottom_divider);
|
||||
|
||||
lineDivider.setVisibility(!importState && isLastChild && !isLastGroup ? View.VISIBLE : View.GONE);
|
||||
cardBottomDivider.setVisibility(importState && isLastChild ? View.VISIBLE : View.GONE);
|
||||
CompoundButtonCompat.setButtonTintList(checkBox, ColorStateList.valueOf(ContextCompat.getColor(app, profileColor)));
|
||||
|
||||
checkBox.setChecked(dataToOperate.contains(currentItem));
|
||||
checkBox.setClickable(false);
|
||||
child.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (dataToOperate.contains(currentItem)) {
|
||||
dataToOperate.remove(currentItem);
|
||||
} else {
|
||||
dataToOperate.add(currentItem);
|
||||
}
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
});
|
||||
|
||||
switch (type) {
|
||||
case PROFILE:
|
||||
String profileName = ((ApplicationMode.ApplicationModeBean) currentItem).userProfileName;
|
||||
if (Algorithms.isEmpty(profileName)) {
|
||||
ApplicationMode appMode = ApplicationMode.valueOfStringKey(((ApplicationMode.ApplicationModeBean) currentItem).stringKey, null);
|
||||
profileName = app.getString(appMode.getNameKeyResource());
|
||||
}
|
||||
title.setText(profileName);
|
||||
String routingProfile = (((ApplicationMode.ApplicationModeBean) currentItem).routingProfile);
|
||||
if (Algorithms.isEmpty(routingProfile)) {
|
||||
subText.setVisibility(View.GONE);
|
||||
} else {
|
||||
subText.setText(String.format(
|
||||
app.getString(R.string.ltr_or_rtl_combine_via_colon),
|
||||
app.getString(R.string.nav_type_hint),
|
||||
routingProfile));
|
||||
subText.setVisibility(View.VISIBLE);
|
||||
}
|
||||
int profileIconRes = AndroidUtils.getDrawableId(app, ((ApplicationMode.ApplicationModeBean) currentItem).iconName);
|
||||
ProfileIconColors iconColor = ((ApplicationMode.ApplicationModeBean) currentItem).iconColor;
|
||||
icon.setImageDrawable(app.getUIUtilities().getIcon(profileIconRes, iconColor.getColor(nightMode)));
|
||||
icon.setVisibility(View.VISIBLE);
|
||||
break;
|
||||
case QUICK_ACTIONS:
|
||||
title.setText(((QuickAction) currentItem).getName(app.getApplicationContext()));
|
||||
icon.setImageDrawable(app.getUIUtilities().getIcon(((QuickAction) currentItem).getIconRes(), nightMode));
|
||||
subText.setVisibility(View.GONE);
|
||||
icon.setVisibility(View.VISIBLE);
|
||||
break;
|
||||
case POI_TYPES:
|
||||
title.setText(((PoiUIFilter) currentItem).getName());
|
||||
int iconRes = RenderingIcons.getBigIconResourceId(((PoiUIFilter) currentItem).getIconId());
|
||||
icon.setImageDrawable(app.getUIUtilities().getIcon(iconRes != 0 ? iconRes : R.drawable.ic_person, profileColor));
|
||||
subText.setVisibility(View.GONE);
|
||||
icon.setVisibility(View.VISIBLE);
|
||||
break;
|
||||
case MAP_SOURCES:
|
||||
title.setText(((ITileSource) currentItem).getName());
|
||||
icon.setImageResource(R.drawable.ic_action_info_dark);
|
||||
subText.setVisibility(View.GONE);
|
||||
icon.setVisibility(View.INVISIBLE);
|
||||
break;
|
||||
case CUSTOM_RENDER_STYLE:
|
||||
String renderName = ((File) currentItem).getName();
|
||||
renderName = renderName.replace('_', ' ').replaceAll(".render.xml", "");
|
||||
title.setText(renderName);
|
||||
icon.setImageResource(R.drawable.ic_action_info_dark);
|
||||
icon.setVisibility(View.INVISIBLE);
|
||||
subText.setVisibility(View.GONE);
|
||||
break;
|
||||
case CUSTOM_ROUTING:
|
||||
String routingName = ((File) currentItem).getName();
|
||||
routingName = routingName.replace('_', ' ').replaceAll(".xml", "");
|
||||
title.setText(routingName);
|
||||
icon.setImageResource(R.drawable.ic_action_map_style);
|
||||
icon.setVisibility(View.VISIBLE);
|
||||
subText.setVisibility(View.GONE);
|
||||
break;
|
||||
default:
|
||||
return child;
|
||||
}
|
||||
return child;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getGroupCount() {
|
||||
return dataList.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChildrenCount(int i) {
|
||||
return dataList.get(i).getItems().size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getGroup(int i) {
|
||||
return dataList.get(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getChild(int groupPosition, int childPosition) {
|
||||
return dataList.get(groupPosition).getItems().get(childPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getGroupId(int i) {
|
||||
return i;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getChildId(int groupPosition, int childPosition) {
|
||||
return groupPosition * 10000 + childPosition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasStableIds() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChildSelectable(int i, int i1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
private int getGroupTitle(AdditionalDataWrapper.Type type) {
|
||||
switch (type) {
|
||||
case PROFILE:
|
||||
return R.string.shared_string_profiles;
|
||||
case QUICK_ACTIONS:
|
||||
return R.string.configure_screen_quick_action;
|
||||
case POI_TYPES:
|
||||
return R.string.poi_dialog_poi_type;
|
||||
case MAP_SOURCES:
|
||||
return R.string.quick_action_map_source_title;
|
||||
case CUSTOM_RENDER_STYLE:
|
||||
return R.string.shared_string_custom_rendering_style;
|
||||
case CUSTOM_ROUTING:
|
||||
return R.string.shared_string_routing;
|
||||
default:
|
||||
return R.string.access_empty_list;
|
||||
}
|
||||
}
|
||||
|
||||
public void updateSettingsList(List<AdditionalDataWrapper> settingsList) {
|
||||
this.dataList = settingsList;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void clearSettingsList() {
|
||||
this.dataList.clear();
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void selectAll(boolean selectAll) {
|
||||
dataToOperate.clear();
|
||||
if (selectAll) {
|
||||
for (AdditionalDataWrapper item : dataList) {
|
||||
dataToOperate.addAll(item.getItems());
|
||||
}
|
||||
}
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
List<? super Object> getDataToOperate() {
|
||||
return this.dataToOperate;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,338 @@
|
|||
package net.osmand.plus.settings;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.LayerDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v7.widget.SwitchCompat;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.ExpandableListView;
|
||||
import android.widget.LinearLayout.LayoutParams;
|
||||
import android.widget.Toast;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.IndexConstants;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.map.ITileSource;
|
||||
import net.osmand.map.TileSourceManager;
|
||||
import net.osmand.plus.ApplicationMode;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.SQLiteTileSource;
|
||||
import net.osmand.plus.SettingsHelper;
|
||||
import net.osmand.plus.UiUtilities;
|
||||
import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem;
|
||||
import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithCompoundButton;
|
||||
import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem;
|
||||
import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem;
|
||||
import net.osmand.plus.poi.PoiUIFilter;
|
||||
import net.osmand.plus.profiles.AdditionalDataWrapper;
|
||||
import net.osmand.plus.quickaction.QuickAction;
|
||||
import net.osmand.plus.quickaction.QuickActionFactory;
|
||||
import net.osmand.plus.settings.bottomsheets.BasePreferenceBottomSheet;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ExportProfileBottomSheet extends BasePreferenceBottomSheet {
|
||||
|
||||
private static final Log LOG = PlatformUtil.getLog(ExportProfileBottomSheet.class);
|
||||
public static final String TAG = ExportProfileBottomSheet.class.getSimpleName();
|
||||
private static final String INCLUDE_ADDITIONAL_DATA_KEY = "INCLUDE_ADDITIONAL_DATA_KEY";
|
||||
private boolean includeAdditionalData = false;
|
||||
private OsmandApplication app;
|
||||
private ApplicationMode profile;
|
||||
private List<AdditionalDataWrapper> dataList = new ArrayList<>();
|
||||
private ExportImportSettingsAdapter adapter;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
if (savedInstanceState != null) {
|
||||
includeAdditionalData = savedInstanceState.getBoolean(INCLUDE_ADDITIONAL_DATA_KEY);
|
||||
}
|
||||
super.onCreate(savedInstanceState);
|
||||
app = requiredMyApplication();
|
||||
dataList = getAdditionalData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putBoolean(INCLUDE_ADDITIONAL_DATA_KEY, includeAdditionalData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createMenuItems(Bundle savedInstanceState) {
|
||||
final Context context = getContext();
|
||||
if (context == null) {
|
||||
return;
|
||||
}
|
||||
LayoutInflater inflater = UiUtilities.getInflater(app, nightMode);
|
||||
|
||||
profile = getAppMode();
|
||||
|
||||
int profileColor = profile.getIconColorInfo().getColor(nightMode);
|
||||
int colorNoAlpha = ContextCompat.getColor(context, profileColor);
|
||||
|
||||
Drawable backgroundIcon = UiUtilities.getColoredSelectableDrawable(context, colorNoAlpha, 0.3f);
|
||||
Drawable[] layers = {new ColorDrawable(UiUtilities.getColorWithAlpha(colorNoAlpha, 0.10f)), backgroundIcon};
|
||||
|
||||
items.add(new TitleItem(getString(R.string.export_profile)));
|
||||
|
||||
BaseBottomSheetItem profileItem = new BottomSheetItemWithCompoundButton.Builder()
|
||||
.setChecked(true)
|
||||
.setCompoundButtonColorId(profileColor)
|
||||
.setButtonTintList(ColorStateList.valueOf(getResolvedColor(profileColor)))
|
||||
.setDescription(BaseSettingsFragment.getAppModeDescription(context, profile))
|
||||
.setIcon(getIcon(profile.getIconRes(), profileColor))
|
||||
.setTitle(profile.toHumanString())
|
||||
.setBackground(new LayerDrawable(layers))
|
||||
.setLayoutId(R.layout.preference_profile_item_with_radio_btn)
|
||||
.create();
|
||||
items.add(profileItem);
|
||||
|
||||
if (!dataList.isEmpty()) {
|
||||
final View additionalDataView = inflater.inflate(R.layout.bottom_sheet_item_additional_data, null);
|
||||
ExpandableListView listView = additionalDataView.findViewById(R.id.list);
|
||||
adapter = new ExportImportSettingsAdapter(app, nightMode);
|
||||
View listHeader = inflater.inflate(R.layout.item_header_export_expand_list, null);
|
||||
final View topSwitchDivider = listHeader.findViewById(R.id.topSwitchDivider);
|
||||
final View bottomSwitchDivider = listHeader.findViewById(R.id.bottomSwitchDivider);
|
||||
final SwitchCompat switchItem = listHeader.findViewById(R.id.switchItem);
|
||||
switchItem.setTextColor(getResources().getColor(nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light));
|
||||
switchItem.setChecked(includeAdditionalData);
|
||||
switchItem.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
includeAdditionalData = !includeAdditionalData;
|
||||
topSwitchDivider.setVisibility(includeAdditionalData ? View.VISIBLE : View.GONE);
|
||||
bottomSwitchDivider.setVisibility(includeAdditionalData ? View.VISIBLE : View.GONE);
|
||||
if (includeAdditionalData) {
|
||||
adapter.updateSettingsList(getAdditionalData());
|
||||
adapter.selectAll(true);
|
||||
} else {
|
||||
adapter.selectAll(false);
|
||||
adapter.clearSettingsList();
|
||||
}
|
||||
updateSwitch(switchItem);
|
||||
setupHeightAndBackground(getView());
|
||||
}
|
||||
});
|
||||
listView.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
|
||||
@Override
|
||||
public void onGroupExpand(int i) {
|
||||
setupHeightAndBackground(getView());
|
||||
}
|
||||
});
|
||||
|
||||
updateSwitch(switchItem);
|
||||
listView.addHeaderView(listHeader);
|
||||
listView.setAdapter(adapter);
|
||||
final SimpleBottomSheetItem titleItem = (SimpleBottomSheetItem) new SimpleBottomSheetItem.Builder()
|
||||
.setCustomView(additionalDataView)
|
||||
.create();
|
||||
items.add(titleItem);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateSwitch(View view) {
|
||||
if (includeAdditionalData) {
|
||||
UiUtilities.setMargins(view, 0, 0, 0, 0);
|
||||
view.setPadding(AndroidUtils.dpToPx(app, 32), 0, AndroidUtils.dpToPx(app, 32), 0);
|
||||
} else {
|
||||
UiUtilities.setMargins(view, AndroidUtils.dpToPx(app, 16), 0, AndroidUtils.dpToPx(app, 16), 0);
|
||||
view.setPadding(AndroidUtils.dpToPx(app, 16), 0, AndroidUtils.dpToPx(app, 16), 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getRightBottomButtonTextId() {
|
||||
return R.string.shared_string_export;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRightBottomButtonClick() {
|
||||
super.onRightBottomButtonClick();
|
||||
prepareFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getDismissButtonTextId() {
|
||||
return R.string.shared_string_cancel;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean useScrollableItemsContainer() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean useExpandableList() {
|
||||
return true;
|
||||
}
|
||||
|
||||
private List<AdditionalDataWrapper> getAdditionalData() {
|
||||
List<AdditionalDataWrapper> dataList = new ArrayList<>();
|
||||
|
||||
QuickActionFactory factory = new QuickActionFactory();
|
||||
List<QuickAction> actionsList = factory.parseActiveActionsList(app.getSettings().QUICK_ACTION_LIST.get());
|
||||
if (!actionsList.isEmpty()) {
|
||||
dataList.add(new AdditionalDataWrapper(
|
||||
AdditionalDataWrapper.Type.QUICK_ACTIONS, actionsList));
|
||||
}
|
||||
|
||||
List<PoiUIFilter> poiList = app.getPoiFilters().getUserDefinedPoiFilters(false);
|
||||
if (!poiList.isEmpty()) {
|
||||
dataList.add(new AdditionalDataWrapper(
|
||||
AdditionalDataWrapper.Type.POI_TYPES,
|
||||
poiList
|
||||
));
|
||||
}
|
||||
|
||||
List<ITileSource> iTileSources = new ArrayList<>();
|
||||
final LinkedHashMap<String, String> tileSourceEntries = new LinkedHashMap<>(app.getSettings().getTileSourceEntries(true));
|
||||
for (Map.Entry<String, String> entry : tileSourceEntries.entrySet()) {
|
||||
File f = app.getAppPath(IndexConstants.TILES_INDEX_DIR + entry.getKey());
|
||||
if (f != null) {
|
||||
ITileSource template;
|
||||
if (f.getName().endsWith(SQLiteTileSource.EXT)) {
|
||||
template = new SQLiteTileSource(app, f, TileSourceManager.getKnownSourceTemplates());
|
||||
} else {
|
||||
template = TileSourceManager.createTileSourceTemplate(f);
|
||||
}
|
||||
if (template != null && template.getUrlTemplate() != null) {
|
||||
iTileSources.add(template);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!iTileSources.isEmpty()) {
|
||||
dataList.add(new AdditionalDataWrapper(
|
||||
AdditionalDataWrapper.Type.MAP_SOURCES,
|
||||
iTileSources
|
||||
));
|
||||
}
|
||||
|
||||
Map<String, File> externalRenderers = app.getRendererRegistry().getExternalRenderers();
|
||||
if (!externalRenderers.isEmpty()) {
|
||||
dataList.add(new AdditionalDataWrapper(
|
||||
AdditionalDataWrapper.Type.CUSTOM_RENDER_STYLE,
|
||||
new ArrayList<>(externalRenderers.values())
|
||||
));
|
||||
}
|
||||
|
||||
File routingProfilesFolder = app.getAppPath(IndexConstants.ROUTING_PROFILES_DIR);
|
||||
if (routingProfilesFolder.exists() && routingProfilesFolder.isDirectory()) {
|
||||
File[] fl = routingProfilesFolder.listFiles();
|
||||
if (fl != null && fl.length > 0) {
|
||||
dataList.add(new AdditionalDataWrapper(
|
||||
AdditionalDataWrapper.Type.CUSTOM_ROUTING,
|
||||
Arrays.asList(fl)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
return dataList;
|
||||
}
|
||||
|
||||
private List<SettingsHelper.SettingsItem> prepareSettingsItemsForExport() {
|
||||
List<SettingsHelper.SettingsItem> settingsItems = new ArrayList<>();
|
||||
settingsItems.add(new SettingsHelper.ProfileSettingsItem(app, profile));
|
||||
if (includeAdditionalData) {
|
||||
settingsItems.addAll(prepareAdditionalSettingsItems());
|
||||
}
|
||||
return settingsItems;
|
||||
}
|
||||
|
||||
private List<SettingsHelper.SettingsItem> prepareAdditionalSettingsItems() {
|
||||
List<SettingsHelper.SettingsItem> settingsItems = new ArrayList<>();
|
||||
List<QuickAction> quickActions = new ArrayList<>();
|
||||
List<PoiUIFilter> poiUIFilters = new ArrayList<>();
|
||||
List<ITileSource> tileSourceTemplates = new ArrayList<>();
|
||||
for (Object object : adapter.getDataToOperate()) {
|
||||
if (object instanceof QuickAction) {
|
||||
quickActions.add((QuickAction) object);
|
||||
} else if (object instanceof PoiUIFilter) {
|
||||
poiUIFilters.add((PoiUIFilter) object);
|
||||
} else if (object instanceof TileSourceManager.TileSourceTemplate
|
||||
|| object instanceof SQLiteTileSource) {
|
||||
tileSourceTemplates.add((ITileSource) object);
|
||||
} else if (object instanceof File) {
|
||||
settingsItems.add(new SettingsHelper.FileSettingsItem(app, (File) object));
|
||||
}
|
||||
}
|
||||
if (!quickActions.isEmpty()) {
|
||||
settingsItems.add(new SettingsHelper.QuickActionSettingsItem(app, quickActions));
|
||||
}
|
||||
if (!poiUIFilters.isEmpty()) {
|
||||
settingsItems.add(new SettingsHelper.PoiUiFilterSettingsItem(app, poiUIFilters));
|
||||
}
|
||||
if (!tileSourceTemplates.isEmpty()) {
|
||||
settingsItems.add(new SettingsHelper.MapSourcesSettingsItem(app, tileSourceTemplates));
|
||||
}
|
||||
return settingsItems;
|
||||
}
|
||||
|
||||
private void prepareFile() {
|
||||
if (app != null) {
|
||||
File tempDir = app.getAppPath(IndexConstants.TEMP_DIR);
|
||||
if (!tempDir.exists()) {
|
||||
tempDir.mkdirs();
|
||||
}
|
||||
String fileName = profile.toHumanString();
|
||||
app.getSettingsHelper().exportSettings(tempDir, fileName, new SettingsHelper.SettingsExportListener() {
|
||||
@Override
|
||||
public void onSettingsExportFinished(@NonNull File file, boolean succeed) {
|
||||
if (succeed) {
|
||||
shareProfile(file, profile);
|
||||
} else {
|
||||
app.showToastMessage(R.string.export_profile_failed);
|
||||
}
|
||||
}
|
||||
}, prepareSettingsItemsForExport());
|
||||
}
|
||||
}
|
||||
|
||||
private void shareProfile(@NonNull File file, @NonNull ApplicationMode profile) {
|
||||
try {
|
||||
final Intent sendIntent = new Intent();
|
||||
sendIntent.setAction(Intent.ACTION_SEND);
|
||||
sendIntent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.exported_osmand_profile, profile.toHumanString()));
|
||||
sendIntent.putExtra(Intent.EXTRA_STREAM, AndroidUtils.getUriForFile(getMyApplication(), file));
|
||||
sendIntent.setType("*/*");
|
||||
sendIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
startActivity(sendIntent);
|
||||
dismiss();
|
||||
} catch (Exception e) {
|
||||
Toast.makeText(requireContext(), R.string.export_profile_failed, Toast.LENGTH_SHORT).show();
|
||||
LOG.error("Share profile error", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean showInstance(@NonNull FragmentManager fragmentManager,
|
||||
Fragment target,
|
||||
@NonNull ApplicationMode appMode) {
|
||||
try {
|
||||
ExportProfileBottomSheet fragment = new ExportProfileBottomSheet();
|
||||
fragment.setAppMode(appMode);
|
||||
fragment.setTargetFragment(target, 0);
|
||||
fragment.show(fragmentManager, TAG);
|
||||
return true;
|
||||
} catch (RuntimeException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,202 @@
|
|||
package net.osmand.plus.settings;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
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.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import net.osmand.map.ITileSource;
|
||||
import net.osmand.plus.ApplicationMode;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.SettingsHelper;
|
||||
import net.osmand.plus.SettingsHelper.SettingsItem;
|
||||
import net.osmand.plus.UiUtilities;
|
||||
import net.osmand.plus.base.BaseOsmAndDialogFragment;
|
||||
import net.osmand.plus.poi.PoiUIFilter;
|
||||
import net.osmand.plus.quickaction.QuickAction;
|
||||
import net.osmand.view.ComplexButton;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class ImportDuplicatesFragment extends BaseOsmAndDialogFragment implements View.OnClickListener {
|
||||
|
||||
public static final String TAG = ImportSettingsFragment.class.getSimpleName();
|
||||
private OsmandApplication app;
|
||||
private RecyclerView list;
|
||||
private List<? super Object> duplicatesList;
|
||||
private List<SettingsItem> settingsItems;
|
||||
private DuplicatesSettingsAdapter adapter;
|
||||
private File file;
|
||||
private boolean nightMode;
|
||||
|
||||
public static void showInstance(@NonNull FragmentManager fm, List<? super Object> duplicatesList,
|
||||
List<SettingsItem> settingsItems, File file) {
|
||||
ImportDuplicatesFragment fragment = new ImportDuplicatesFragment();
|
||||
fragment.setDuplicatesList(duplicatesList);
|
||||
fragment.setSettingsItems(settingsItems);
|
||||
fragment.setFile(file);
|
||||
fragment.setRetainInstance(true);
|
||||
fragment.show(fm, TAG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
app = getMyApplication();
|
||||
nightMode = !getSettings().isLightContent();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
inflater = UiUtilities.getInflater(app, nightMode);
|
||||
View root = inflater.inflate(R.layout.fragment_import_duplicates, container, false);
|
||||
setupToolbar((Toolbar) root.findViewById(R.id.toolbar));
|
||||
ComplexButton replaceAllBtn = root.findViewById(R.id.replace_all_btn);
|
||||
ComplexButton keepBothBtn = root.findViewById(R.id.keep_both_btn);
|
||||
keepBothBtn.setIcon(getPaintedContentIcon(R.drawable.ic_action_keep_both,
|
||||
nightMode
|
||||
? getResources().getColor(R.color.icon_color_active_dark)
|
||||
: getResources().getColor(R.color.icon_color_active_light))
|
||||
);
|
||||
replaceAllBtn.setIcon(getPaintedContentIcon(R.drawable.ic_action_replace,
|
||||
nightMode
|
||||
? getResources().getColor(R.color.active_buttons_and_links_text_dark)
|
||||
: getResources().getColor(R.color.active_buttons_and_links_text_light))
|
||||
);
|
||||
keepBothBtn.setOnClickListener(this);
|
||||
replaceAllBtn.setOnClickListener(this);
|
||||
list = root.findViewById(R.id.list);
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
adapter = new DuplicatesSettingsAdapter(getMyApplication(), prepareDuplicates(), nightMode);
|
||||
list.setLayoutManager(new LinearLayoutManager(getMyApplication()));
|
||||
list.setAdapter(adapter);
|
||||
}
|
||||
|
||||
private List<Object> prepareDuplicates() {
|
||||
List<? super Object> duplicates = new ArrayList<>();
|
||||
List<ApplicationMode.ApplicationModeBean> profiles = new ArrayList<>();
|
||||
List<QuickAction> actions = new ArrayList<>();
|
||||
List<PoiUIFilter> filters = new ArrayList<>();
|
||||
List<ITileSource> tileSources = new ArrayList<>();
|
||||
List<File> renderFilesList = new ArrayList<>();
|
||||
List<File> routingFilesList = new ArrayList<>();
|
||||
|
||||
for (Object object : duplicatesList) {
|
||||
if (object instanceof ApplicationMode.ApplicationModeBean) {
|
||||
profiles.add((ApplicationMode.ApplicationModeBean) object);
|
||||
} else if (object instanceof QuickAction) {
|
||||
actions.add((QuickAction) object);
|
||||
} else if (object instanceof PoiUIFilter) {
|
||||
filters.add((PoiUIFilter) object);
|
||||
} else if (object instanceof ITileSource) {
|
||||
tileSources.add((ITileSource) object);
|
||||
} else if (object instanceof File) {
|
||||
File file = (File) object;
|
||||
if (file.getAbsolutePath().contains("files/rendering")) {
|
||||
renderFilesList.add(file);
|
||||
} else if (file.getAbsolutePath().contains("files/routing")) {
|
||||
routingFilesList.add(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!profiles.isEmpty()) {
|
||||
duplicates.add(getString(R.string.shared_string_profiles));
|
||||
duplicates.addAll(profiles);
|
||||
}
|
||||
if (!actions.isEmpty()) {
|
||||
duplicates.add(getString(R.string.shared_string_quick_actions));
|
||||
duplicates.addAll(actions);
|
||||
}
|
||||
if (!filters.isEmpty()) {
|
||||
duplicates.add(getString(R.string.shared_string_poi_types));
|
||||
duplicates.addAll(filters);
|
||||
}
|
||||
if (!tileSources.isEmpty()) {
|
||||
duplicates.add(getString(R.string.quick_action_map_source_title));
|
||||
duplicates.addAll(tileSources);
|
||||
}
|
||||
if (!routingFilesList.isEmpty()) {
|
||||
duplicates.add(getString(R.string.shared_string_routing));
|
||||
duplicates.addAll(routingFilesList);
|
||||
}
|
||||
if (!renderFilesList.isEmpty()) {
|
||||
duplicates.add(getString(R.string.shared_string_custom_rendering_style));
|
||||
duplicates.addAll(renderFilesList);
|
||||
}
|
||||
return duplicates;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
switch (view.getId()) {
|
||||
case R.id.keep_both_btn: {
|
||||
importItems(false);
|
||||
break;
|
||||
}
|
||||
case R.id.replace_all_btn: {
|
||||
importItems(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void importItems(boolean shouldReplace) {
|
||||
for (SettingsItem item : settingsItems) {
|
||||
item.setShouldReplace(shouldReplace);
|
||||
}
|
||||
app.getSettingsHelper().importSettings(file, settingsItems, "", 1, new SettingsHelper.SettingsImportListener() {
|
||||
@Override
|
||||
public void onSettingsImportFinished(boolean succeed, boolean empty, @NonNull List<SettingsHelper.SettingsItem> items) {
|
||||
if (succeed) {
|
||||
app.showShortToastMessage(app.getString(R.string.file_imported_successfully, file.getName()));
|
||||
} else if (empty) {
|
||||
app.showShortToastMessage(app.getString(R.string.file_import_error, file.getName(), app.getString(R.string.shared_string_unexpected_error)));
|
||||
}
|
||||
}
|
||||
});
|
||||
dismiss();
|
||||
}
|
||||
|
||||
private void setupToolbar(Toolbar toolbar) {
|
||||
toolbar.setNavigationIcon(getPaintedContentIcon(R.drawable.ic_arrow_back,
|
||||
nightMode
|
||||
? getResources().getColor(R.color.active_buttons_and_links_text_dark)
|
||||
: getResources().getColor(R.color.active_buttons_and_links_text_light)));
|
||||
toolbar.setNavigationContentDescription(R.string.access_shared_string_navigate_up);
|
||||
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setDuplicatesList(List<? super Object> duplicatesList) {
|
||||
this.duplicatesList = duplicatesList;
|
||||
}
|
||||
|
||||
public void setSettingsItems(List<SettingsItem> settingsItems) {
|
||||
this.settingsItems = settingsItems;
|
||||
}
|
||||
|
||||
public void setFile(File file) {
|
||||
this.file = file;
|
||||
}
|
||||
}
|
275
OsmAnd/src/net/osmand/plus/settings/ImportSettingsFragment.java
Normal file
275
OsmAnd/src/net/osmand/plus/settings/ImportSettingsFragment.java
Normal file
|
@ -0,0 +1,275 @@
|
|||
package net.osmand.plus.settings;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
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.ExpandableListView;
|
||||
|
||||
import net.osmand.map.ITileSource;
|
||||
import net.osmand.map.TileSourceManager;
|
||||
import net.osmand.plus.ApplicationMode;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.SQLiteTileSource;
|
||||
import net.osmand.plus.SettingsHelper;
|
||||
import net.osmand.plus.SettingsHelper.SettingsItem;
|
||||
import net.osmand.plus.UiUtilities;
|
||||
import net.osmand.plus.base.BaseOsmAndDialogFragment;
|
||||
import net.osmand.plus.poi.PoiUIFilter;
|
||||
import net.osmand.plus.profiles.AdditionalDataWrapper;
|
||||
import net.osmand.plus.quickaction.QuickAction;
|
||||
import net.osmand.plus.widgets.TextViewEx;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ImportSettingsFragment extends BaseOsmAndDialogFragment
|
||||
implements View.OnClickListener {
|
||||
|
||||
public static final String TAG = ImportSettingsFragment.class.getSimpleName();
|
||||
private OsmandApplication app;
|
||||
private ExportImportSettingsAdapter adapter;
|
||||
private ExpandableListView expandableList;
|
||||
private TextViewEx selectBtn;
|
||||
private List<SettingsItem> settingsItems;
|
||||
private File file;
|
||||
private boolean allSelected;
|
||||
private boolean nightMode;
|
||||
|
||||
public static void showInstance(@NonNull FragmentManager fm, @NonNull List<SettingsItem> settingsItems, @NonNull File file) {
|
||||
ImportSettingsFragment fragment = new ImportSettingsFragment();
|
||||
fragment.setSettingsItems(settingsItems);
|
||||
fragment.setFile(file);
|
||||
fragment.show(fm, TAG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
app = getMyApplication();
|
||||
nightMode = !getSettings().isLightContent();
|
||||
if (settingsItems == null) {
|
||||
settingsItems = app.getSettingsHelper().getSettingsItems();
|
||||
}
|
||||
if (file == null) {
|
||||
file = app.getSettingsHelper().getSettingsFile();
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
inflater = UiUtilities.getInflater(app, nightMode);
|
||||
View root = inflater.inflate(R.layout.fragment_import, container, false);
|
||||
setupToolbar((Toolbar) root.findViewById(R.id.toolbar));
|
||||
TextViewEx continueBtn = root.findViewById(R.id.continue_button);
|
||||
selectBtn = root.findViewById(R.id.select_button);
|
||||
expandableList = root.findViewById(R.id.list);
|
||||
continueBtn.setOnClickListener(this);
|
||||
selectBtn.setOnClickListener(this);
|
||||
return root;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
adapter = new ExportImportSettingsAdapter(getMyApplication(), getSettingsToOperate(), nightMode, true);
|
||||
expandableList.setAdapter(adapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
switch (view.getId()) {
|
||||
case R.id.select_button: {
|
||||
allSelected = !allSelected;
|
||||
selectBtn.setText(allSelected ? R.string.shared_string_deselect_all : R.string.shared_string_select_all);
|
||||
adapter.selectAll(allSelected);
|
||||
break;
|
||||
}
|
||||
case R.id.continue_button: {
|
||||
if (adapter.getDataToOperate().isEmpty()) {
|
||||
app.showShortToastMessage(getString(R.string.shared_string_nothing_selected));
|
||||
} else {
|
||||
importItems();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void importItems() {
|
||||
List<SettingsItem> settingsItems = getSettingsItemsFromData(adapter.getDataToOperate());
|
||||
List<Object> duplicateItems = getDuplicatesData(settingsItems);
|
||||
if (duplicateItems.isEmpty()) {
|
||||
app.getSettingsHelper().importSettings(file, settingsItems, "", 1, new SettingsHelper.SettingsImportListener() {
|
||||
@Override
|
||||
public void onSettingsImportFinished(boolean succeed, boolean empty, @NonNull List<SettingsHelper.SettingsItem> items) {
|
||||
if (succeed) {
|
||||
app.showShortToastMessage(app.getString(R.string.file_imported_successfully, file.getName()));
|
||||
} else if (empty) {
|
||||
app.showShortToastMessage(app.getString(R.string.file_import_error, file.getName(), app.getString(R.string.shared_string_unexpected_error)));
|
||||
}
|
||||
}
|
||||
});
|
||||
dismiss();
|
||||
} else {
|
||||
ImportDuplicatesFragment.showInstance(getFragmentManager(), duplicateItems, settingsItems, file);
|
||||
dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private List<Object> getDuplicatesData(List<SettingsItem> items) {
|
||||
List<Object> duplicateItems = new ArrayList<>();
|
||||
for (SettingsItem item : items) {
|
||||
if (item instanceof SettingsHelper.ProfileSettingsItem) {
|
||||
if (item.exists()) {
|
||||
duplicateItems.add(((SettingsHelper.ProfileSettingsItem) item).getModeBean());
|
||||
}
|
||||
} else if (item instanceof SettingsHelper.QuickActionSettingsItem) {
|
||||
List<QuickAction> duplicates = ((SettingsHelper.QuickActionSettingsItem) item).excludeDuplicateItems();
|
||||
if (!duplicates.isEmpty()) {
|
||||
duplicateItems.addAll(duplicates);
|
||||
}
|
||||
} else if (item instanceof SettingsHelper.PoiUiFilterSettingsItem) {
|
||||
List<PoiUIFilter> duplicates = ((SettingsHelper.PoiUiFilterSettingsItem) item).excludeDuplicateItems();
|
||||
if (!duplicates.isEmpty()) {
|
||||
duplicateItems.addAll(duplicates);
|
||||
}
|
||||
} else if (item instanceof SettingsHelper.MapSourcesSettingsItem) {
|
||||
List<ITileSource> duplicates = ((SettingsHelper.MapSourcesSettingsItem) item).excludeDuplicateItems();
|
||||
if (!duplicates.isEmpty()) {
|
||||
duplicateItems.addAll(duplicates);
|
||||
}
|
||||
} else if (item instanceof SettingsHelper.FileSettingsItem) {
|
||||
if (item.exists()) {
|
||||
duplicateItems.add(((SettingsHelper.FileSettingsItem) item).getFile());
|
||||
}
|
||||
}
|
||||
}
|
||||
return duplicateItems;
|
||||
}
|
||||
|
||||
public void setSettingsItems(List<SettingsItem> settingsItems) {
|
||||
this.settingsItems = settingsItems;
|
||||
}
|
||||
|
||||
private List<SettingsItem> getSettingsItemsFromData(List<Object> dataToOperate) {
|
||||
List<SettingsItem> settingsItems = new ArrayList<>();
|
||||
List<QuickAction> quickActions = new ArrayList<>();
|
||||
List<PoiUIFilter> poiUIFilters = new ArrayList<>();
|
||||
List<ITileSource> tileSourceTemplates = new ArrayList<>();
|
||||
for (Object object : dataToOperate) {
|
||||
if (object instanceof ApplicationMode.ApplicationModeBean) {
|
||||
settingsItems.add(new SettingsHelper.ProfileSettingsItem(app, (ApplicationMode.ApplicationModeBean) object));
|
||||
}
|
||||
if (object instanceof QuickAction) {
|
||||
quickActions.add((QuickAction) object);
|
||||
} else if (object instanceof PoiUIFilter) {
|
||||
poiUIFilters.add((PoiUIFilter) object);
|
||||
} else if (object instanceof TileSourceManager.TileSourceTemplate
|
||||
|| object instanceof SQLiteTileSource) {
|
||||
tileSourceTemplates.add((ITileSource) object);
|
||||
} else if (object instanceof File) {
|
||||
settingsItems.add(new SettingsHelper.FileSettingsItem(getMyApplication(), (File) object));
|
||||
}
|
||||
}
|
||||
if (!quickActions.isEmpty()) {
|
||||
settingsItems.add(new SettingsHelper.QuickActionSettingsItem(getMyApplication(), quickActions));
|
||||
}
|
||||
if (!poiUIFilters.isEmpty()) {
|
||||
settingsItems.add(new SettingsHelper.PoiUiFilterSettingsItem(getMyApplication(), poiUIFilters));
|
||||
}
|
||||
if (!tileSourceTemplates.isEmpty()) {
|
||||
settingsItems.add(new SettingsHelper.MapSourcesSettingsItem(getMyApplication(), tileSourceTemplates));
|
||||
}
|
||||
return settingsItems;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private List<AdditionalDataWrapper> getSettingsToOperate() {
|
||||
List<AdditionalDataWrapper> settingsToOperate = new ArrayList<>();
|
||||
List<ApplicationMode.ApplicationModeBean> profiles = new ArrayList<>();
|
||||
List<QuickAction> quickActions = new ArrayList<>();
|
||||
List<PoiUIFilter> poiUIFilters = new ArrayList<>();
|
||||
List<ITileSource> tileSourceTemplates = new ArrayList<>();
|
||||
List<File> routingFilesList = new ArrayList<>();
|
||||
List<File> renderFilesList = new ArrayList<>();
|
||||
|
||||
for (SettingsHelper.SettingsItem item : settingsItems) {
|
||||
if (item.getType().equals(SettingsHelper.SettingsItemType.PROFILE)) {
|
||||
profiles.add(((SettingsHelper.ProfileSettingsItem) item).getModeBean());
|
||||
} else if (item.getType().equals(SettingsHelper.SettingsItemType.QUICK_ACTION)) {
|
||||
quickActions.addAll(((SettingsHelper.QuickActionSettingsItem) item).getItems());
|
||||
} else if (item.getType().equals(SettingsHelper.SettingsItemType.POI_UI_FILTERS)) {
|
||||
poiUIFilters.addAll(((SettingsHelper.PoiUiFilterSettingsItem) item).getItems());
|
||||
} else if (item.getType().equals(SettingsHelper.SettingsItemType.MAP_SOURCES)) {
|
||||
tileSourceTemplates.addAll(((SettingsHelper.MapSourcesSettingsItem) item).getItems());
|
||||
} else if (item.getType().equals(SettingsHelper.SettingsItemType.FILE)) {
|
||||
if (item.getName().startsWith("/rendering/")) {
|
||||
renderFilesList.add(((SettingsHelper.FileSettingsItem) item).getFile());
|
||||
} else if (item.getName().startsWith("/routing/")) {
|
||||
routingFilesList.add(((SettingsHelper.FileSettingsItem) item).getFile());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!profiles.isEmpty()) {
|
||||
settingsToOperate.add(new AdditionalDataWrapper(
|
||||
AdditionalDataWrapper.Type.PROFILE,
|
||||
profiles));
|
||||
}
|
||||
if (!quickActions.isEmpty()) {
|
||||
settingsToOperate.add(new AdditionalDataWrapper(
|
||||
AdditionalDataWrapper.Type.QUICK_ACTIONS,
|
||||
quickActions));
|
||||
}
|
||||
if (!poiUIFilters.isEmpty()) {
|
||||
settingsToOperate.add(new AdditionalDataWrapper(
|
||||
AdditionalDataWrapper.Type.POI_TYPES,
|
||||
poiUIFilters));
|
||||
}
|
||||
if (!tileSourceTemplates.isEmpty()) {
|
||||
settingsToOperate.add(new AdditionalDataWrapper(
|
||||
AdditionalDataWrapper.Type.MAP_SOURCES,
|
||||
tileSourceTemplates
|
||||
));
|
||||
}
|
||||
if (!renderFilesList.isEmpty()) {
|
||||
settingsToOperate.add(new AdditionalDataWrapper(
|
||||
AdditionalDataWrapper.Type.CUSTOM_RENDER_STYLE,
|
||||
renderFilesList
|
||||
));
|
||||
}
|
||||
if (!routingFilesList.isEmpty()) {
|
||||
settingsToOperate.add(new AdditionalDataWrapper(
|
||||
AdditionalDataWrapper.Type.CUSTOM_ROUTING,
|
||||
routingFilesList
|
||||
));
|
||||
}
|
||||
return settingsToOperate;
|
||||
}
|
||||
|
||||
private void setupToolbar(Toolbar toolbar) {
|
||||
toolbar.setNavigationIcon(getPaintedContentIcon(R.drawable.headline_close_button, nightMode
|
||||
? getResources().getColor(R.color.active_buttons_and_links_text_dark)
|
||||
: getResources().getColor(R.color.active_buttons_and_links_text_light)));
|
||||
toolbar.setNavigationContentDescription(R.string.shared_string_close);
|
||||
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setFile(File file) {
|
||||
this.file = file;
|
||||
}
|
||||
}
|
|
@ -81,7 +81,7 @@ public class MapQuickActionLayer extends OsmandMapLayer implements QuickActionRe
|
|||
this.contextMenuLayer = contextMenuLayer;
|
||||
app = activity.getMyApplication();
|
||||
settings = activity.getMyApplication().getSettings();
|
||||
quickActionRegistry = activity.getMapLayers().getQuickActionRegistry();
|
||||
quickActionRegistry = app.getQuickActionRegistry();
|
||||
measurementToolLayer = mapActivity.getMapLayers().getMeasurementToolLayer();
|
||||
mapMarkersLayer = mapActivity.getMapLayers().getMapMarkersLayer();
|
||||
}
|
||||
|
|
|
@ -451,7 +451,7 @@ public class MapWidgetRegistry {
|
|||
contextMenuAdapter.addItem(new ContextMenuItem.ItemBuilder().setTitleId(R.string.map_widget_right, mapActivity)
|
||||
.setCategory(true).setLayout(R.layout.list_group_empty_title_with_switch).createItem());
|
||||
|
||||
boolean selected = mapActivity.getMapLayers().getQuickActionRegistry().isQuickActionOn();
|
||||
boolean selected = app.getQuickActionRegistry().isQuickActionOn();
|
||||
contextMenuAdapter.addItem(new ContextMenuItem.ItemBuilder()
|
||||
.setTitleId(R.string.configure_screen_quick_action, mapActivity)
|
||||
.setIcon(R.drawable.map_quick_action)
|
||||
|
@ -482,7 +482,7 @@ public class MapWidgetRegistry {
|
|||
int position,
|
||||
boolean visible) {
|
||||
|
||||
mapActivity.getMapLayers().getQuickActionRegistry().setQuickActionFabState(visible);
|
||||
app.getQuickActionRegistry().setQuickActionFabState(visible);
|
||||
|
||||
MapQuickActionLayer mil = mapActivity.getMapLayers().getMapQuickActionLayer();
|
||||
if (mil != null) {
|
||||
|
|
95
OsmAnd/src/net/osmand/view/ComplexButton.java
Normal file
95
OsmAnd/src/net/osmand/view/ComplexButton.java
Normal file
|
@ -0,0 +1,95 @@
|
|||
package net.osmand.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.widgets.TextViewEx;
|
||||
|
||||
public class ComplexButton extends FrameLayout {
|
||||
|
||||
private TextViewEx textTv;
|
||||
private TextViewEx subTextTv;
|
||||
private ImageView iconIv;
|
||||
|
||||
public ComplexButton(@NonNull Context context) {
|
||||
super(context);
|
||||
inflateView();
|
||||
}
|
||||
|
||||
public ComplexButton(@NonNull Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
inflateView();
|
||||
initView(attrs);
|
||||
}
|
||||
|
||||
public ComplexButton(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
inflateView();
|
||||
initView(attrs);
|
||||
}
|
||||
|
||||
private void inflateView() {
|
||||
View view = LayoutInflater.from(getContext()).inflate(R.layout.button_with_icon_and_subtext, this);
|
||||
textTv = view.findViewById(R.id.text);
|
||||
subTextTv = view.findViewById(R.id.sub_text);
|
||||
iconIv = view.findViewById(R.id.icon);
|
||||
}
|
||||
|
||||
private void initView(@Nullable AttributeSet attrs) {
|
||||
TypedArray a = getContext().getTheme().obtainStyledAttributes(
|
||||
attrs,
|
||||
R.styleable.ComplexButton,
|
||||
0, 0);
|
||||
try {
|
||||
textTv.setText(a.getString(R.styleable.ComplexButton_setText));
|
||||
textTv.setTextColor(a.getColor(R.styleable.ComplexButton_setTextColor, Color.WHITE));
|
||||
subTextTv.setText(a.getString(R.styleable.ComplexButton_setSubText));
|
||||
subTextTv.setTextColor(a.getColor(R.styleable.ComplexButton_setSubTextColor, Color.WHITE));
|
||||
iconIv.setImageResource(a.getResourceId(R.styleable.ComplexButton_setIcon, 0));
|
||||
} finally {
|
||||
a.recycle();
|
||||
}
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
textTv.setText(text);
|
||||
}
|
||||
|
||||
public void setText(int textRes) {
|
||||
textTv.setText(textRes);
|
||||
}
|
||||
|
||||
public void setTextColor(int color) {
|
||||
textTv.setTextColor(color);
|
||||
}
|
||||
|
||||
public void setSubText(String subText) {
|
||||
subTextTv.setText(subText);
|
||||
}
|
||||
|
||||
public void setSubText(int subTextRes) {
|
||||
subTextTv.setText(subTextRes);
|
||||
}
|
||||
|
||||
public void setSubTextColor(int color) {
|
||||
subTextTv.setTextColor(color);
|
||||
}
|
||||
|
||||
public void setIcon(int iconRes) {
|
||||
iconIv.setImageResource(iconRes);
|
||||
}
|
||||
|
||||
public void setIcon(Drawable drawable) {
|
||||
iconIv.setImageDrawable(drawable);
|
||||
}
|
||||
}
|
78
OsmAnd/src/net/osmand/view/ThreeStateCheckbox.java
Normal file
78
OsmAnd/src/net/osmand/view/ThreeStateCheckbox.java
Normal file
|
@ -0,0 +1,78 @@
|
|||
package net.osmand.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.v7.widget.AppCompatCheckBox;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.CompoundButton;
|
||||
|
||||
import net.osmand.plus.R;
|
||||
|
||||
public class ThreeStateCheckbox extends AppCompatCheckBox {
|
||||
|
||||
private State state;
|
||||
|
||||
public ThreeStateCheckbox(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public ThreeStateCheckbox(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public ThreeStateCheckbox(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
state = State.MISC;
|
||||
updateBtn();
|
||||
setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||
switch (state) {
|
||||
case MISC:
|
||||
case CHECKED:
|
||||
state = State.UNCHECKED;
|
||||
break;
|
||||
case UNCHECKED:
|
||||
state = State.CHECKED;
|
||||
break;
|
||||
}
|
||||
updateBtn();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void updateBtn() {
|
||||
int btnDrawable = R.drawable.ic_checkbox_indeterminate;
|
||||
switch (state) {
|
||||
default:
|
||||
case MISC:
|
||||
break;
|
||||
case UNCHECKED:
|
||||
btnDrawable = R.drawable.ic_check_box_outline_light;
|
||||
break;
|
||||
case CHECKED:
|
||||
btnDrawable = R.drawable.ic_check_box_light;
|
||||
break;
|
||||
}
|
||||
setButtonDrawable(btnDrawable);
|
||||
}
|
||||
|
||||
public State getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public void setState(State state) {
|
||||
this.state = state;
|
||||
updateBtn();
|
||||
}
|
||||
|
||||
public enum State {
|
||||
UNCHECKED,
|
||||
CHECKED,
|
||||
MISC
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue