Compare commits

..

10 commits

Author SHA1 Message Date
androiddevkotlin
e3047f151d Use variable to store data from server 2021-04-22 11:36:41 +03:00
androiddevkotlin
85114b049d Fix compound button 2021-04-21 20:26:52 +03:00
Vitaliy
2ee1b26289 Merge branch 'master' into Redesign-voice 2021-04-21 14:02:14 +03:00
Vitaliy
daf31151f6 Merge branch 'master' into Redesign-voice 2021-04-20 19:12:31 +03:00
androiddevkotlin
d157d686ec Replace block code to createMenuItems, downloadThread field added, padding inline variable 2021-04-19 20:33:09 +03:00
androiddevkotlin
ed113a3835 Refactor, setting added 2021-04-19 19:58:08 +03:00
androiddevkotlin
ea553717d8 Small fixes UI 2021-04-19 15:05:33 +03:00
androiddevkotlin
bd1fbe859e Review 2021-04-19 14:25:53 +03:00
androiddevkotlin
66ba7ff2f6 Spillover from Voice Prompts
Replace string "Languages" > "Language"
"Language" icon ic_action_map_language
It seems 2 dividers below the "Options" header, remove one.
It seems we lost the warning banner below the "Speed cameras" switch.
New headers is blinking after taping on a switch.
Min. item height = 48dp
Remove "Navigation instructions" option
2021-04-18 21:12:43 +03:00
androiddevkotlin
23cc2430f1 New UI
Navigation settings > Voice prompts
0. New UI

    Rename the Voice guidance menu item to Language.
    Language dialog changes:
    • Add toggle between "TTS | Recorded"
    • Remove "Install more" item and download "Recorded" voice packages without leaving the dialog.
    • Delete the "Don't use" option, because currently, we have the main switch on the "Voice prompts" screen in Navigation settings.
    • Add option "Use system language", detect system language (we do similar in Wikipedia, where we get system languages and put them at the top of the list), and use it by default.
2021-04-18 11:46:21 +03:00
120 changed files with 1700 additions and 6389 deletions

View file

@ -186,7 +186,7 @@ public class RouteColorize {
public List<RouteColorizationPoint> getResult(boolean simplify) { public List<RouteColorizationPoint> getResult(boolean simplify) {
List<RouteColorizationPoint> result = new ArrayList<>(); List<RouteColorizationPoint> result = new ArrayList<>();
if (simplify) { if (simplify) {
result = simplify(zoom); result = simplify();
} else { } else {
for (int i = 0; i < latitudes.length; i++) { for (int i = 0; i < latitudes.length; i++) {
result.add(new RouteColorizationPoint(i, latitudes[i], longitudes[i], values[i])); result.add(new RouteColorizationPoint(i, latitudes[i], longitudes[i], values[i]));
@ -200,7 +200,7 @@ public class RouteColorize {
public int getColorByValue(double value) { public int getColorByValue(double value) {
if (Double.isNaN(value)) { if (Double.isNaN(value)) {
value = colorizationType == ColorizationType.SLOPE ? minValue : (minValue + maxValue) / 2; value = (minValue + maxValue) / 2;
} }
for (int i = 0; i < palette.length - 1; i++) { for (int i = 0; i < palette.length - 1; i++) {
if (value == palette[i][VALUE_INDEX]) if (value == palette[i][VALUE_INDEX])
@ -242,7 +242,7 @@ public class RouteColorize {
return rgbaToDecimal(0, 0, 0, 0); return rgbaToDecimal(0, 0, 0, 0);
} }
public List<RouteColorizationPoint> simplify(int zoom) { private List<RouteColorizationPoint> simplify() {
if (dataList == null) { if (dataList == null) {
dataList = new ArrayList<>(); dataList = new ArrayList<>();
for (int i = 0; i < latitudes.length; i++) { for (int i = 0; i < latitudes.length; i++) {
@ -266,8 +266,6 @@ public class RouteColorize {
List<RouteColorizationPoint> sublist = dataList.subList(prevId, currentId); List<RouteColorizationPoint> sublist = dataList.subList(prevId, currentId);
simplified.addAll(getExtremums(sublist)); simplified.addAll(getExtremums(sublist));
} }
Node lastSurvivedPoint = result.get(result.size() - 1);
simplified.add(dataList.get((int) lastSurvivedPoint.getId()));
return simplified; return simplified;
} }

View file

@ -1,274 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="shared_string_select">Označi</string>
<string name="shared_string_enable">Omogući</string>
<string name="altitude">Nadmorska visina</string>
<string name="shared_string_search">Traži</string>
<string name="shared_string_ok">U redu</string>
<string name="shared_string_update">Ažuriraj</string>
<string name="average_altitude">Prosečna visina</string>
<string name="average_speed">Prosečna brzina</string>
<string name="shared_string_map">Karta</string>
<string name="shared_string_add">Dodaj</string>
<string name="shared_string_hide">Sakrij</string>
<string name="shared_string_status">Stanje</string>
<string name="shared_string_disable">Onemogući</string>
<string name="shared_string_save">Sačuvaj</string>
<string name="shared_string_name">Ime</string>
<string name="shared_string_sort">Sortiraj</string>
<string name="shared_string_exit">Izlaz</string>
<string name="shared_string_close">Zatvori</string>
<string name="shared_string_all">Sve</string>
<string name="shared_string_off">Isključeno</string>
<string name="shared_string_install">Instaliraj</string>
<string name="shared_string_share">Deli</string>
<string name="shared_string_back">Nazad</string>
<string name="shared_string_continue">Nastavi</string>
<string name="shared_string_cancel">Otkaži</string>
<string name="shared_string_settings">Postavke</string>
<string name="osmand_service">Pozadinski režim</string>
<string name="yard">yd</string>
<string name="foot">ft</string>
<string name="mile">mi</string>
<string name="km">km</string>
<string name="m">m</string>
<string name="nm">nmi</string>
<string name="min_mile">min/m</string>
<string name="min_km">min/km</string>
<string name="m_s">m/s</string>
<string name="km_h">km/h</string>
<string name="mile_per_hour">mph</string>
<string name="si_kmh">Kilometara na sat</string>
<string name="si_mph">Milja na sat</string>
<string name="si_m_s">Metara u sekundi</string>
<string name="si_min_km">Minuta po kilometru</string>
<string name="si_min_m">Minuta po milji</string>
<string name="si_mi_feet">Milje/stope</string>
<string name="si_mi_yard">Milje/jardi</string>
<string name="si_km_m">Kilometri/metri</string>
<string name="si_nm">Nautičke milje</string>
<string name="si_mi_meters">Milje/metri</string>
<string name="shared_string_apply">Primeni</string>
<string name="shared_string_enabled">Uključen</string>
<string name="units_and_formats">Merne jedinice &amp; formatiranja</string>
<string name="unit_of_length_descr">Promeni jedinice za dužinu.</string>
<string name="unit_of_length">Jedinice dužine</string>
<string name="shared_string_appearance">Izgled</string>
<string name="timeline">Vremenska linija</string>
<string name="live_now">Uživo sada</string>
<string name="my_location">Moja lokacija</string>
<string name="welcome_descr"><b>OsmAnd Pratioc</b> omogućava vam da delite svoju lokaciju i vidite lokaciju drugih u OsmAndu.<br/><br/>Aplikacija koristi Telegram API, pa vam je potreban Telegram nalog.</string>
<string name="shared_string_second_short">sek</string>
<string name="shared_string_minute_short">min</string>
<string name="shared_string_hour_short">č</string>
<string name="si_nm_h">Nautičkih milja na sat (čvorovi)</string>
<string name="nm_h">nmi/č</string>
<string name="shared_string_welcome">Dobrodošli</string>
<string name="shared_string_authorization_descr">Unesite vaš telefonski broj Telegrama u međunarodnom formatu</string>
<string name="shared_string_authorization">Autorizacija</string>
<string name="active_chats">Aktivna ćaskanja</string>
<string name="show_users_on_map">Prikažite korisnike na mapi</string>
<string name="install_osmand">Instalirajte OsmAnd</string>
<string name="install_osmand_dialog_message">Prvo morate instalirati besplatnu ili plaćenu verziju OsmAnda</string>
<string name="osmand_logo">Logo OsmAnda</string>
<string name="process_service">Usluga OsmAnd Pratioca</string>
<string name="sharing_location">Deljenje lokacije</string>
<string name="share_location">Deli lokaciju</string>
<string name="shared_string_distance">Rastojanje</string>
<string name="osmand_service_descr">OsmAnd Pratioc radi u pozadini sa isključenim ekranom.</string>
<string name="location_service_no_gps_available">Izaberite jednog od dobavljača lokacije da bi deliti vašu lokaciju.</string>
<string name="gps_not_available">Uključite „Lokaciju“ u sistemskim podešavanjima</string>
<string name="no_location_permission">Aplikaciji nedostaje dozvola za pristup podacima o lokaciji.</string>
<string name="not_logged_in">Niste prijavljeni</string>
<string name="gps_network_not_enabled">Uključiti „Lokaciju“\?</string>
<string name="closing">Zatvaranje</string>
<string name="logging_out">Odjavljivanje</string>
<string name="initialization">Pokretanje</string>
<string name="shared_string_logout">Odjaviti se</string>
<string name="shared_string_login">Prijavite se</string>
<string name="password_descr">Telegram lozinka</string>
<string name="enter_password">Unesite lozinku</string>
<string name="authentication_code_descr">Telegram vam je poslao kod za OsmAnd radi prijave na vaš nalog.</string>
<string name="authentication_code">Validacioni kod</string>
<string name="enter_code">Unesite kod</string>
<string name="shared_string_password">Lozinka</string>
<string name="phone_number_descr">Broj telefona u međunarodnom formatu</string>
<string name="phone_number_title">Broj telefona</string>
<string name="app_name">OsmAnd Onlajn GPS Pratioc</string>
<string name="show_on_map">Prikaži na mapi</string>
<string name="start_location_sharing">Deli lokaciju</string>
<string name="my_location_search_hint">Pretražite: Grupu ili kontakt</string>
<string name="location_sharing_description">Izaberite kontakte i grupe sa kojima želite da delite lokaciju.</string>
<string name="set_time">Podesite vreme</string>
<string name="set_time_description">Podesite vreme za koji će izabrani kontakti i grupe videti vašu lokaciju u realnom vremenu.</string>
<string name="visible_time_for_all">Vidljivo vreme za sve</string>
<string name="hours_format">%1$ č</string>
<string name="minutes_format">%1$ m</string>
<string name="hours_and_minutes_format">%1$ č %2$ m</string>
<string name="set_visible_time_for_all">Podesite vidljivo vreme za sve</string>
<string name="enter_authentication_code">Unesite kod za validaciju</string>
<string name="enter_phone_number">Unesite broj telefona</string>
<string name="do_not_have_telegram">Nemam Telegram nalog</string>
<string name="already_registered_in_telegram">Potreban vam je registrovani Telegram nalog i broj telefona</string>
<string name="get_telegram_after_creating_account">Tada možete da koristite ovu aplikaciju.</string>
<string name="get_telegram_description_continue">Instalirajte Telegram i otvorite nalog.</string>
<string name="get_telegram_account_first">Za deljenje lokacije potreban vam je Telegram nalog.</string>
<string name="get_telegram_title">Registracija u Telegramu</string>
<string name="shared_string_bot">Bot</string>
<string name="shared_string_live">Uživo</string>
<string name="open_osmand">Otvori OsmAnd</string>
<string name="turn_off_location_sharing">Isključite deljenje lokacije</string>
<string name="stop_sharing_all">Deljenje je uključeno (isključite)</string>
<string name="expire_at">Ističe</string>
<string name="sharing_time">Vreme deljenja</string>
<string name="gps_and_location">Pozicija</string>
<string name="send_my_location">Pošalji moju lokaciju</string>
<string name="send_my_location_desc">Podesite minimalni interval za deljenje lokacije.</string>
<string name="stale_location">Nepomičan</string>
<string name="stale_location_desc">Poslednji put kada se kontakt pomerio.</string>
<string name="location_history">Istorija lokacije</string>
<string name="location_history_desc">Sakrijte kontakte koji se nisu pomerili u datom vremenu.</string>
<string name="osmand_connect">Osmand veza</string>
<string name="osmand_connect_desc">Odaberite verziju OsmAnda koju OsmAnd pratioc koristi za prikazivanje pozicija.</string>
<string name="in_time">u %1$</string>
<string name="shared_string_account">Nalog</string>
<string name="connected_account">Povezani nalog</string>
<string name="logout_help_desc">Kako isključiti OsmAnd pratioca iz Telegrama</string>
<string name="disconnect_from_telegram">Kako isključiti OsmAnd pratioca iz Telegrama</string>
<string name="disconnect_from_telegram_desc">Da biste opozvali pristup deljenju lokacije. Otvorite Telegram, idite na Podešavanja → Privatnost i bezbednost → Sesije i prekinete sesiju OsmAnd pratioca.</string>
<string name="logout_no_internet_msg">Povežite se na Internet kako biste se pravilno odjavili iz Telegrama.</string>
<string name="shared_string_group">Grupa</string>
<string name="last_response">Poslednji odgovor</string>
<string name="time_ago">pre</string>
<string name="turn_off_all">Isključi sve</string>
<string name="disable_all_sharing">Onemogući svako deljenje</string>
<string name="disable_all_sharing_desc">Isključuje deljenje lokacije prema svim izabranim čatovima (%1$).</string>
<string name="choose_osmand">Izaberite verziju OsmAnda koju želite da koristite</string>
<string name="choose_osmand_desc">Izaberite verziju OsmAnda gde će se kontakti prikazati na mapi.</string>
<string name="shared_string_sort_by">Sortiraj po</string>
<string name="by_group">Po grupi</string>
<string name="by_name">Po imenu</string>
<string name="by_distance">Po udaljenosti</string>
<string name="logout_from_osmand_telegram">Odjaviti se sa OsmAnd pratioca\?</string>
<string name="logout_from_osmand_telegram_descr">Jeste li sigurni da se želite odjaviti sa OsmAnd pratioca tako da ne možete da delite lokaciju ili vidite lokaciju drugih\?</string>
<string name="live_now_description">Kontakti i grupe dele lokaciju vama.</string>
<string name="share_location_as">Deljenje lokacije kao</string>
<string name="add_device">Dodajte uređaj</string>
<string name="no_internet_connection">Nema internet konekcije</string>
<string name="no_gps_connection">Nema GPS veze</string>
<string name="location_sharing_status">Deljenje: %1$</string>
<string name="sharing_status">Deljenje statusa</string>
<string name="last_available_location">Poslednja dostupna lokacija</string>
<string name="re_send_location">Ponovo pošalji lokaciju</string>
<string name="not_found_yet">Još nije pronađeno</string>
<string name="not_sent_yet">Još nije poslato</string>
<string name="shared_string_later">Kasnije</string>
<string name="go_to_settings">Idi na Podešavanja</string>
<string name="sharing_in_background">Deljenje u pozadini</string>
<string name="battery_optimization_description">Isključite optimizaciju baterije za OsmAnd pratilac tako da se ne isključi iznenada kad je u pozadini.</string>
<string name="background_work">Rad u pozadini</string>
<string name="background_work_description">Promenite podešavanja za optimizaciju baterije da biste stabilizovali deljenje lokacije.</string>
<string name="connecting_to_the_internet">Povezivanje sa Internetom</string>
<string name="searching_for_gps">Pozicioniranje…</string>
<string name="initializing">Pokretanje</string>
<string name="sending_location_messages">Lokacija se šalje</string>
<string name="waiting_for_response_from_telegram">Čeka se odgovor iz Telegrama</string>
<string name="not_possible_to_send_to_telegram_chats">Nije moguće poslati u Telegram četove:</string>
<string name="successfully_sent_and_updated">Uspešno poslato i ažurirano</string>
<string name="last_updated_location">Poslednja ažurirana lokacija:</string>
<string name="share_location_as_description">Ako želite da povežete više uređaja sa jednim nalogom telegrama, trebate koristiti drugi uređaj da bi delili vašu lokaciju.</string>
<string name="share_location_as_description_second_line">Možete da kreirate i vidite ID uređaja u telegram klijentu koristeći %1$ čat bot. %2$</string>
<string name="device_name">Ime uređaja</string>
<string name="device_name_cannot_be_empty">Ime uređaja ne može biti prazno</string>
<string name="device_name_is_too_long">Ime uređaja predugo</string>
<string name="enter_device_name_description">Imenujte vaš novi uređaj sa maksimalno 200 simbola.</string>
<string name="error_adding_new_device">Nije moguće dodati novi uređaj</string>
<string name="device_added_successfully">%1$ dodato.</string>
<string name="enter_another_device_name">Izaberite ime koje niste već koristili</string>
<string name="last_update_from_telegram">Poslednje ažuriranje od Telegrama</string>
<string name="map_and_text">Mapa i tekst</string>
<string name="shared_string_text">Tekst</string>
<string name="send_location_as_descr">Odaberite kako će izgledati poruke sa vašom lokacijom.</string>
<string name="send_location_as">Pošalji lokaciju kao</string>
<string name="start_date">Početni datum</string>
<string name="end_date">Krajnji datum</string>
<string name="open_in_osmand">Prikaži u OsmAndu</string>
<string name="time_on_the_move">Vreme kretanja</string>
<string name="monitoring_is_disabled">Praćenje je onemogućeno</string>
<string name="monitoring_is_enabled">Praćenje je omogućeno</string>
<string name="shared_string_sent">Poslato</string>
<string name="gps_points">GPS tačke</string>
<string name="shared_string_collected">Prikupljeno</string>
<string name="shared_string_date">Datum</string>
<string name="points_size">%1$ tačaka</string>
<string name="gps_points_in_buffer">poslato (%1$ u baferu)</string>
<string name="please_update_osmand">Ažurirajte OsmAnd da biste videli podatke na mapi</string>
<string name="show_gps_points_descr">Prikaži količinu prikupljenih i poslatih GPS tačaka.</string>
<string name="show_gps_points">Pokaži GPS tačke</string>
<string name="received_gps_points">Primljene GPKS tačke: %1$</string>
<string name="how_it_works">Kako radi</string>
<string name="osmand_privacy_policy">OsmAnd politika privatnosti</string>
<string name="telegram_privacy_policy">Politika privatnosti Telegrama</string>
<string name="shared_string_accept">Prihvati</string>
<string name="privacy_policy_agree">Klikom na „Nastavi“ prihvatate uslove politike privatnosti Telegrama i OsmAnda.</string>
<string name="privacy_policy_telegram_client">OsmAnd pratilac je jedan od klijenata koji koriste otvorenu platformu Telegram. Vaši kontakti mogu da koriste bilo koji drugi Telegram klijent.</string>
<string name="privacy_policy_use_telegram">Telegram (aplikacija za razmenu poruka) koristi se za povezivanje i komunikaciju sa ljudima.</string>
<string name="shared_string_telegram">Telegram</string>
<string name="app_name_short">OsmAnd pratilac</string>
<string name="timeline_description">Omogućite praćenje da biste sačuvali sve lokacije u istoriji.</string>
<string name="location_recording_enabled">Snimanje lokacije omogućeno</string>
<string name="disable_monitoring">Onemogućite praćenje</string>
<string name="timeline_available_for_free_now">Vremenska linija je funkcija koja je sada dostupna besplatno.</string>
<string name="type_contact_or_group_name">Unesite ime kontakta ili grupe</string>
<string name="search_contacts_descr">Pretraga po svim vašim grupama i kontaktima.</string>
<string name="search_contacts">Pretraga kontakta</string>
<string name="bearing">Usmerenje</string>
<string name="precision">Preciznost</string>
<string name="direction">Smer</string>
<string name="privacy">Privatnost</string>
<string name="proxy">Proksi</string>
<string name="proxy_settings">Podešavanja proksija</string>
<string name="proxy_disconnected">Prekinut</string>
<string name="proxy_connected">Povezan</string>
<string name="proxy_type">Tip proksija</string>
<string name="shared_string_connection">Veza</string>
<string name="proxy_server">Server</string>
<string name="proxy_port">Port</string>
<string name="proxy_credentials">Akreditivi</string>
<string name="proxy_username">Korisničko ime</string>
<string name="proxy_password">Lozinka</string>
<string name="proxy_key">Ključ</string>
<string name="gpx_settings">GPX podešavanja</string>
<string name="min_logging_speed_descr">Filter: nema zapisivanja ispod odabrane brzine</string>
<string name="min_logging_speed">Minimalna brzina zapisivanja</string>
<string name="min_logging_accuracy_descr">Filter: Nema zapisa dok se ne dostigne ova tačnost</string>
<string name="min_logging_accuracy">Minimalna tačnost evidentiranja</string>
<string name="min_logging_distance_descr">Filter: minimalna udaljenost za evidentiranje nove tačke</string>
<string name="min_logging_distance">Minimalna udaljenost evidentiranja</string>
<string name="timeline_no_data">Nema podataka</string>
<string name="timeline_no_data_descr">Nemamo prikupljene podatke za izabrani dan</string>
<string name="start_end_date">Početni — Krajnji datum</string>
<string name="set_time_timeline_descr">Izaberite vreme za prikaz</string>
<string name="shared_string_start">Početak</string>
<string name="shared_string_end">Kraj</string>
<string name="saved_messages">Sačuvane poruke</string>
<string name="unit_of_speed_system">Jedinica brzine</string>
<string name="unit_of_speed_system_descr">Definišite jedinicu brzine.</string>
<string name="time_zone">Vremenska zona</string>
<string name="time_zone_descr">Izaberite vremensku zonu koja će se prikazati u porukama lokacije.</string>
<string name="buffer_time">Vreme isteka bafera</string>
<string name="buffer_time_descr">Maksimalno vreme za skladištenje tačaka u bafer</string>
<string name="status_widget_title">Status Tragača OsmAnda</string>
<string name="shared_string_suggested">Predloženo</string>
<string name="back_to_osmand">Povratak na OsmAnd</string>
<string name="duration_ago">Pre %1$</string>
<string name="last_response_duration">Poslednji odgovor: pre %1$</string>
<string name="last_update_from_telegram_duration">Poslednje ažuriranje iz Telegrama: pre %1$</string>
<string name="last_response_date">Poslednji odgovor: %1$</string>
<string name="last_update_from_telegram_date">Poslednje ažuriranje iz Telegrama: %1$</string>
<string name="shared_string_error_short">Greška</string>
<string name="shared_string_export">Izvezi</string>
<string name="logcat_buffer">Logcat bafer</string>
<string name="logcat_buffer_descr">Proverite i podelite detaljne zapise aplikacije</string>
<string name="send_report">Pošalji izveštaj</string>
</resources>

View file

@ -109,7 +109,7 @@
<string name="get_telegram_description_continue">Kérjük, telepítse a Telegramot és hozzon létre egy fiókot.</string> <string name="get_telegram_description_continue">Kérjük, telepítse a Telegramot és hozzon létre egy fiókot.</string>
<string name="get_telegram_after_creating_account">Utána használhatja ezt az alkalmazást.</string> <string name="get_telegram_after_creating_account">Utána használhatja ezt az alkalmazást.</string>
<string name="shared_string_all">Minden</string> <string name="shared_string_all">Minden</string>
<string name="shared_string_off">Kikapcsolva</string> <string name="shared_string_off">Kikapcsolás</string>
<string name="hours_and_minutes_format">%1$d óra %2$d perc</string> <string name="hours_and_minutes_format">%1$d óra %2$d perc</string>
<string name="minutes_format">%1$d perc</string> <string name="minutes_format">%1$d perc</string>
<string name="shared_string_install">Telepítés</string> <string name="shared_string_install">Telepítés</string>

View file

@ -1,10 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M12,22C17.5228,22 22,17.5228 22,12C22,6.4771 17.5228,2 12,2C6.4771,2 2,6.4771 2,12C2,17.5228 6.4771,22 12,22ZM11,14V7H13V14H11ZM11,18V16H13V18H11Z"
android:fillColor="#ffffff"
android:fillType="evenOdd"/>
</vector>

View file

@ -1,18 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M20,12C20,15.4738 17.7859,18.4304 14.692,19.5358L14.9449,21.5593C19.0304,20.3022 22,16.4979 22,12C22,6.4771 17.5228,2 12,2C6.4771,2 2,6.4771 2,12C2,16.4979 4.9696,20.3022 9.0551,21.5593L9.308,19.5358C6.2141,18.4304 4,15.4738 4,12C4,7.5817 7.5817,4 12,4C16.4183,4 20,7.5817 20,12Z"
android:fillColor="#ffffff"/>
<path
android:pathData="M18,12C18,14.4466 16.5357,16.5511 14.4356,17.485L14.1701,15.3607C15.2713,14.6482 16,13.4092 16,12C16,9.7909 14.2091,8 12,8C9.7909,8 8,9.7909 8,12C8,13.4092 8.7287,14.6482 9.8299,15.3607L9.5644,17.485C7.4643,16.5511 6,14.4466 6,12C6,8.6863 8.6863,6 12,6C15.3137,6 18,8.6863 18,12Z"
android:fillColor="#ffffff"/>
<path
android:pathData="M14,12C14,13.1046 13.1046,14 12,14C10.8954,14 10,13.1046 10,12C10,10.8954 10.8954,10 12,10C13.1046,10 14,10.8954 14,12Z"
android:fillColor="#ffffff"/>
<path
android:pathData="M11,15V22H13V15H11Z"
android:fillColor="#ffffff"/>
</vector>

View file

@ -1,15 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M22.0001,12C22.0001,13.9623 21.4349,15.7926 20.4583,17.337L18.9991,15.8777C19.6369,14.7291 20.0001,13.407 20.0001,12C20.0001,7.5817 16.4183,4 12.0001,4C10.5931,4 9.271,4.3632 8.1223,5.0009L6.6631,3.5417C8.2075,2.5652 10.0378,2 12.0001,2C17.5229,2 22.0001,6.4771 22.0001,12Z"
android:fillColor="#ffffff"/>
<path
android:pathData="M18.0001,12C18.0001,12.8478 17.8242,13.6545 17.507,14.3857L15.9203,12.7989C15.9726,12.5407 16.0001,12.2736 16.0001,12C16.0001,9.7909 14.2092,8 12.0001,8C11.7265,8 11.4593,8.0275 11.2012,8.0798L9.6144,6.493C10.3456,6.1758 11.1523,6 12.0001,6C15.3138,6 18.0001,8.6863 18.0001,12Z"
android:fillColor="#ffffff"/>
<path
android:pathData="M14.3449,16.759L14.4357,17.485C14.5806,17.4206 14.7225,17.3506 14.8611,17.2752L16.3203,18.7344C15.8138,19.0599 15.2682,19.33 14.692,19.5358L14.945,21.5593C15.9623,21.2463 16.9105,20.7753 17.7609,20.1749L21.293,23.7071L22.7072,22.2928L2.7072,2.2929L1.293,3.7071L3.8251,6.2392C2.6754,7.8677 2.0001,9.855 2.0001,12C2.0001,16.4979 4.9696,20.3022 9.0552,21.5593L9.3081,19.5358C6.2141,18.4304 4.0001,15.4738 4.0001,12C4.0001,10.4087 4.4647,8.9258 5.2657,7.6798L6.7248,9.1389C6.2626,9.9894 6.0001,10.964 6.0001,12C6.0001,14.4466 7.4644,16.5511 9.5644,17.485L9.83,15.3607C8.7288,14.6482 8.0001,13.4092 8.0001,12C8.0001,11.5256 8.0826,11.0705 8.2342,10.6483L10.0555,12.4696C10.2305,13.197 10.8031,13.7695 11.5305,13.9446L12.5859,15H11.0001V22H13.0001V15.4142L14.3449,16.759Z"
android:fillColor="#ffffff"/>
</vector>

View file

@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M6,18V17.9725C3.75,17.7238 2,15.8163 2,13.5C2,11.0147 4.0147,9 6.5,9C6.5998,9 6.6989,9.0033 6.7971,9.0097C7.8332,7.2109 9.7752,6 12,6C15.3137,6 18,8.6863 18,12C18,12.0574 17.9992,12.1146 17.9976,12.1716C18.3111,12.0605 18.6485,12 19,12C20.6569,12 22,13.3431 22,15C22,16.6569 20.6569,18 19,18H6Z"
android:fillColor="#ffffff"/>
</vector>

View file

@ -1,10 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M6,17.9725V18H19C20.6569,18 22,16.6569 22,15C22,13.3431 20.6569,12 19,12C18.6485,12 18.3111,12.0605 17.9976,12.1716C17.9992,12.1146 18,12.0574 18,12C18,8.6863 15.3137,6 12,6C9.7752,6 7.8332,7.2109 6.7971,9.0097C6.6989,9.0033 6.5998,9 6.5,9C4.0147,9 2,11.0147 2,13.5C2,15.8163 3.75,17.7238 6,17.9725ZM11,13V8H13V13H11ZM11,17V15H13V17H11Z"
android:fillColor="#ffffff"
android:fillType="evenOdd"/>
</vector>

View file

@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M14,18V15H16.5L12.5,10L8.5,15H11V18H6V17.9725C3.75,17.7238 2,15.8163 2,13.5C2,11.0147 4.0147,9 6.5,9C6.5998,9 6.6989,9.0033 6.7971,9.0097C7.8332,7.2109 9.7752,6 12,6C15.3137,6 18,8.6863 18,12C18,12.0574 17.9992,12.1146 17.9976,12.1716C18.3111,12.0605 18.6485,12 19,12C20.6569,12 22,13.3431 22,15C22,16.6569 20.6569,18 19,18H14Z"
android:fillColor="#ffffff"/>
</vector>

View file

@ -1,12 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M6,18V17.9725C3.75,17.7238 2,15.8163 2,13.5C2,11.0147 4.0147,9 6.5,9C6.5998,9 6.6989,9.0033 6.7971,9.0097C7.8332,7.2109 9.7752,6 12,6C15.3137,6 18,8.6863 18,12C18,12.0574 17.9992,12.1146 17.9976,12.1716C18.3111,12.0605 18.6485,12 19,12C20.6569,12 22,13.3431 22,15C22,16.6569 20.6569,18 19,18H6Z"
android:fillColor="#6C19FF"/>
<path
android:pathData="M11,15H8.5L12.5,9.5L16.5,15H14V20H11V15Z"
android:fillColor="#FFC30D"/>
</vector>

View file

@ -1,15 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M14,2L20,8H16C14.8954,8 14,7.1046 14,6V2Z"
android:strokeAlpha="0.5"
android:fillColor="#ffffff"
android:fillAlpha="0.5"/>
<path
android:pathData="M4,4C4,2.8954 4.8954,2 6,2H14V6C14,7.1046 14.8954,8 16,8H20V20C20,21.1046 19.1046,22 18,22H6C4.8954,22 4,21.1046 4,20V4ZM11,18H13V13H15L12,9L9,13H11V18Z"
android:fillColor="#ffffff"
android:fillType="evenOdd"/>
</vector>

View file

@ -1,37 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M12,5C12.5523,5 13,4.5523 13,4H17V8.0549C16.6717,8.0186 16.338,8 16,8C11.0294,8 7,12.0294 7,17V4H11C11,4.5523 11.4477,5 12,5Z"
android:strokeAlpha="0.3"
android:fillColor="#ffffff"
android:fillAlpha="0.3"/>
<path
android:pathData="M7,17C7,18.0519 7.1805,19.0617 7.5121,20H7V17Z"
android:strokeAlpha="0.3"
android:fillColor="#ffffff"
android:fillAlpha="0.3"/>
<path
android:pathData="M17,2.01L7,2C5.9,2 5,2.9 5,4V20C5,21.1 5.9,22 7,22H8.5155C8.1025,21.383 7.7638,20.7121 7.5121,20H7V4H11C11,4.5523 11.4477,5 12,5C12.5523,5 13,4.5523 13,4H17V8.0549C17.6935,8.1316 18.3632,8.287 19,8.5121V4C19,2.9 18.1,2.01 17,2.01Z"
android:strokeAlpha="0.7"
android:fillColor="#ffffff"
android:fillAlpha="0.7"/>
<path
android:pathData="M16,21C18.2091,21 20,19.2091 20,17C20,14.7909 18.2091,13 16,13C13.7909,13 12,14.7909 12,17H14L11,20L8,17H10C10,13.6863 12.6863,11 16,11C19.3137,11 22,13.6863 22,17C22,20.3137 19.3137,23 16,23C14.598,23 13.3082,22.5191 12.2868,21.7132L13.7159,20.2841C14.3635,20.7354 15.1508,21 16,21Z"
android:fillType="evenOdd">
<aapt:attr name="android:fillColor">
<gradient
android:gradientRadius="6.36396"
android:centerX="16"
android:centerY="17"
android:type="radial">
<item android:offset="0" android:color="#FFFFFFFF"/>
<item android:offset="0.8125" android:color="#FFFFFFFF"/>
<item android:offset="1" android:color="#00FFFFFF"/>
</gradient>
</aapt:attr>
</path>
</vector>

View file

@ -1,15 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M6,3C4.8954,3 4,3.8954 4,5V7H20C20,5.8954 19.1046,5 18,5H13L11.4,3H6Z"
android:strokeAlpha="0.5"
android:fillColor="#ffffff"
android:fillAlpha="0.5"/>
<path
android:pathData="M2,7C2,5.8954 2.8954,5 4,5H10L12,7H20C21.1046,7 22,7.8954 22,9V19C22,20.1046 21.1046,21 20,21H4C2.8954,21 2,20.1046 2,19V7ZM17,12C17,13.1046 16.1046,14 15,14C13.8954,14 13,13.1046 13,12C13,10.8954 13.8954,10 15,10C16.1046,10 17,10.8954 17,12ZM10,17.5V19H20V17.5C20,15.5 17,15 15,15C13,15 10,15.5 10,17.5Z"
android:fillColor="#ffffff"
android:fillType="evenOdd"/>
</vector>

View file

@ -1,7 +0,0 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners
android:bottomLeftRadius="@dimen/list_item_button_padding"
android:topLeftRadius="@dimen/list_item_button_padding" />
<solid android:color="@color/list_background_color_dark" />
</shape>

View file

@ -1,11 +0,0 @@
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/active_buttons_and_links_trans_light">
<item android:id="@android:id/mask">
<shape android:shape="rectangle">
<corners
android:bottomLeftRadius="@dimen/list_item_button_padding"
android:topLeftRadius="@dimen/list_item_button_padding" />
<solid android:color="@color/active_color_primary_light" />
</shape>
</item>
</ripple>

View file

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/background">
<shape android:shape="rectangle">
<solid android:color="#4d007eb3" />
<corners android:radius="30dp" />
</shape>
</item>
<item android:id="@+id/progress">
<shape android:shape="rectangle">
<solid android:color="@color/color_white" />
<corners android:radius="30dp" />
</shape>
</item>
</layer-list>

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<item android:id="@+id/thump">
<shape android:shape="oval">
<size
android:width="12dp"
android:height="12dp" />
<solid android:color="@color/profile_icon_color_blue_light" />
</shape>
</item>
</layer-list>

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<size
android:width="2dp"
android:height="2dp" />
<solid android:color="#17181A" />
</shape>

View file

@ -62,12 +62,18 @@
osmand:typeface="@string/font_roboto_medium" osmand:typeface="@string/font_roboto_medium"
tools:text="Normal" /> tools:text="Normal" />
<com.google.android.material.slider.Slider <SeekBar
android:id="@+id/arrival_slider" android:id="@+id/seek_bar_arrival"
style="@style/Widget.AppCompat.SeekBar.Discrete"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/content_padding" android:layout_marginTop="@dimen/pages_item_margin"
android:layout_marginRight="@dimen/content_padding" /> android:maxHeight="2dp"
android:paddingTop="11dp"
android:paddingBottom="11dp"
osmand:tickMark="@drawable/seekbar_tickmark_announcement_time"
tools:max="3"
tools:progress="1" />
<View <View
android:id="@+id/divider" android:id="@+id/divider"

View file

@ -2,7 +2,6 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_width="match_parent" android:layout_width="match_parent"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"> android:orientation="vertical">
<View <View
@ -59,7 +58,7 @@
android:layout_gravity="center_vertical|start" android:layout_gravity="center_vertical|start"
android:textColor="?android:textColorPrimary" android:textColor="?android:textColorPrimary"
android:textSize="@dimen/default_list_text_size_large" android:textSize="@dimen/default_list_text_size_large"
tools:text="Item title"/> android:text="Item title"/>
</LinearLayout> </LinearLayout>

View file

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal" android:orientation="horizontal"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -70,7 +69,7 @@
android:textColor="@color/color_myloc_distance" android:textColor="@color/color_myloc_distance"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:layout_marginTop="2dp" android:layout_marginTop="2dp"
tools:text="Cinema" android:text="Cinema"
android:layout_marginRight="16dp" android:layout_marginRight="16dp"
android:layout_marginEnd="16dp" /> android:layout_marginEnd="16dp" />

View file

@ -5,10 +5,8 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="vertical"
android:padding="@dimen/content_padding"
android:paddingStart="@dimen/content_padding" android:paddingStart="@dimen/content_padding"
android:paddingLeft="@dimen/content_padding"
android:paddingTop="@dimen/content_padding"
android:paddingRight="@dimen/content_padding"
android:paddingEnd="@dimen/content_padding"> android:paddingEnd="@dimen/content_padding">
<View <View
@ -45,9 +43,4 @@
</LinearLayout> </LinearLayout>
<View
android:id="@+id/space"
android:layout_width="match_parent"
android:layout_height="@dimen/content_padding" />
</LinearLayout> </LinearLayout>

View file

@ -79,6 +79,21 @@
</LinearLayout> </LinearLayout>
<androidx.appcompat.widget.AppCompatRadioButton
android:id="@+id/compound_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:scaleType="center"
android:background="@null"
android:layout_marginEnd="@dimen/dashFavDirectionSize"
android:layout_marginRight="@dimen/dashFavDirectionSize"
android:clickable="false"
android:focusable="false"
android:visibility="gone"
android:saveEnabled="false"
tools:visibility="visible"/>
<androidx.appcompat.widget.AppCompatImageView <androidx.appcompat.widget.AppCompatImageView
android:id="@+id/secondary_icon" android:id="@+id/secondary_icon"
android:layout_width="@dimen/list_item_height" android:layout_width="@dimen/list_item_height"

View file

@ -2,7 +2,6 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:layout_height="fill_parent"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical" android:orientation="vertical"
android:paddingLeft="?dialogPreferredPadding" android:paddingLeft="?dialogPreferredPadding"
android:paddingRight="?dialogPreferredPadding" android:paddingRight="?dialogPreferredPadding"
@ -33,7 +32,7 @@
android:id="@+id/user_name_field" android:id="@+id/user_name_field"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
tools:text="NoName"/> android:text="NoName"/>
<TextView <TextView

View file

@ -0,0 +1,37 @@
<?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="@dimen/card_row_min_height"
android:background="?attr/list_background_color"
android:gravity="center_vertical"
android:minHeight="@dimen/bottom_sheet_cancel_button_height"
android:orientation="horizontal">
<androidx.appcompat.widget.AppCompatImageView
android:id="@android:id/icon"
android:layout_width="@dimen/standard_icon_size"
android:layout_height="@dimen/standard_icon_size"
android:layout_gravity="center"
android:layout_marginLeft="@dimen/content_padding"
android:layout_marginRight="@dimen/content_padding"
android:layout_marginStart="@dimen/content_padding"
android:layout_marginEnd="@dimen/content_padding" />
<net.osmand.plus.widgets.TextViewEx
android:id="@android:id/title"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:textColor="@color/preference_category_title"
android:layout_gravity="center_vertical|start"
android:paddingLeft="@dimen/content_padding"
android:paddingRight="@dimen/content_padding"
android:textSize="@dimen/default_desc_text_size"
osmand:typeface="@string/font_roboto_medium"
tools:text="@string/plugin_settings"
android:paddingEnd="@dimen/content_padding"
android:paddingStart="@dimen/content_padding" />
</LinearLayout>

View file

@ -4,7 +4,6 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
xmlns:osmand="http://schemas.android.com/apk/res-auto" xmlns:osmand="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"> android:orientation="vertical">
<com.google.android.material.appbar.AppBarLayout <com.google.android.material.appbar.AppBarLayout
@ -52,7 +51,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:background="@null" android:background="@null"
tools:text="Filling station" android:text="Filling station"
android:textColor="@color/color_white" android:textColor="@color/color_white"
android:textSize="@dimen/default_desc_text_size"/> android:textSize="@dimen/default_desc_text_size"/>

View file

@ -94,7 +94,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:background="@null" android:background="@null"
tools:text="Split interval:" android:text="Split interval:"
android:textColor="?android:attr/textColorPrimary" android:textColor="?android:attr/textColorPrimary"
android:textSize="@dimen/default_desc_text_size" android:textSize="@dimen/default_desc_text_size"
osmand:typeface="@string/font_roboto_medium" /> osmand:typeface="@string/font_roboto_medium" />

View file

@ -2,7 +2,6 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
android:background="?attr/spinnerListBackground" android:background="?attr/spinnerListBackground"
android:orientation="vertical"> android:orientation="vertical">
@ -213,7 +212,7 @@
android:paddingLeft="2dp" android:paddingLeft="2dp"
android:paddingEnd="0dp" android:paddingEnd="0dp"
android:paddingRight="0dp" android:paddingRight="0dp"
tools:text="Ukraine" android:text="Ukraine"
app:drawableEndCompat="@drawable/ic_action_arrow_drop_down" app:drawableEndCompat="@drawable/ic_action_arrow_drop_down"
app:drawableRightCompat="@drawable/ic_action_arrow_drop_down" /> app:drawableRightCompat="@drawable/ic_action_arrow_drop_down" />

View file

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:osmand="http://schemas.android.com/apk/res-auto" <LinearLayout
xmlns:osmand="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
xmlns:tools="http://schemas.android.com/tools"
android:gravity="center_vertical" android:gravity="center_vertical"
android:minHeight="48dp" android:minHeight="48dp"
android:orientation="horizontal" android:orientation="horizontal"
@ -36,7 +36,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
tools:text="Avoid selected roads" android:text="Avoid selected roads"
android:textSize="@dimen/default_list_text_size"/> android:textSize="@dimen/default_list_text_size"/>
<TextView <TextView
@ -44,7 +44,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
tools:text="Select roads you want to avoid during navigation" android:text="Select roads you want to avoid during navigation"
android:textSize="@dimen/default_desc_text_size"/> android:textSize="@dimen/default_desc_text_size"/>
</LinearLayout> </LinearLayout>

View file

@ -118,7 +118,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="@dimen/content_padding" android:layout_marginTop="@dimen/content_padding"
tools:text="Actions" android:text="Actions"
android:textColor="?android:textColorPrimary" android:textColor="?android:textColorPrimary"
android:textSize="@dimen/default_list_text_size" /> android:textSize="@dimen/default_list_text_size" />

View file

@ -2,7 +2,6 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:layout_height="fill_parent"
xmlns:tools="http://schemas.android.com/tools"
android:background="@drawable/popup_bg" android:background="@drawable/popup_bg"
android:gravity="center" android:gravity="center"
android:orientation="horizontal"> android:orientation="horizontal">
@ -38,6 +37,6 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="0" android:layout_weight="0"
android:background="?attr/selectableItemBackground" android:background="?attr/selectableItemBackground"
tools:text="UNDO" android:text="UNDO"
android:textColor="@color/popup_text_color"/> android:textColor="@color/popup_text_color"/>
</LinearLayout> </LinearLayout>

View file

@ -4123,11 +4123,7 @@
<string name="shared_string_route_line">خط المسار</string> <string name="shared_string_route_line">خط المسار</string>
<string name="route_line_use_map_style_appearance">سيستخدم خط الطريق %1$s المحدد في نمط الخريطة المحدد: %2$s.</string> <string name="route_line_use_map_style_appearance">سيستخدم خط الطريق %1$s المحدد في نمط الخريطة المحدد: %2$s.</string>
<string name="specify_color_for_map_mode">حدد لونًا لوضع الخريطة: %1$s.</string> <string name="specify_color_for_map_mode">حدد لونًا لوضع الخريطة: %1$s.</string>
<string name="release_4_0_beta">• خيار مضاف لتنزيل خطوط الكنتور بالقدم <string name="release_4_0_beta">• تم نقل تحديثات OsmAnd Live إلى \"التنزيلات&gt; التحديثات\"
\n
\n• مخطط الطريق الأفقي: علامات تبويب tabs مضافة للتبديل بين النقاط أو الرسوم البيانية
\n
\n• تم نقل تحديثات OsmAnd Live إلى \"التنزيلات&gt; التحديثات\"
\n \n
\n • يمكن تلوين المسارات الآن حسب الارتفاع، السرعة أو المنحدر. \n • يمكن تلوين المسارات الآن حسب الارتفاع، السرعة أو المنحدر.
\n \n
@ -4158,8 +4154,4 @@
<string name="announce_when_exceeded">الإعلان عند التجاوز</string> <string name="announce_when_exceeded">الإعلان عند التجاوز</string>
<string name="user_points">نقاط المستخدم</string> <string name="user_points">نقاط المستخدم</string>
<string name="output">الإخراج</string> <string name="output">الإخراج</string>
<string name="srtm_unit_format">تنسيق وحدة خطوط الكنتور</string>
<string name="srtm_download_list_help_message">OsmAnd يوفر بيانات الخطوط الكنتورية بالأمتار والقدم. ستحتاج إلى إعادة تنزيل الملف لتغيير التنسيق.</string>
<string name="srtm_download_single_help_message">الرجاء تحديد التنسيق المطلوب. ستحتاج إلى إعادة تنزيل الملف لتغيير التنسيق.</string>
<string name="shared_string_feet">قدم</string>
</resources> </resources>

File diff suppressed because it is too large Load diff

View file

@ -1088,7 +1088,7 @@
<string name="lang_ja">Японская</string> <string name="lang_ja">Японская</string>
<string name="lang_ko">Карэйская</string> <string name="lang_ko">Карэйская</string>
<string name="lang_lv">Латышская</string> <string name="lang_lv">Латышская</string>
<string name="lang_lt">Летувіская</string> <string name="lang_lt">Летувісская</string>
<string name="lang_mr">Маратхі</string> <string name="lang_mr">Маратхі</string>
<string name="lang_no">Нарвежская (Bokmål)</string> <string name="lang_no">Нарвежская (Bokmål)</string>
<string name="lang_pl">Польская</string> <string name="lang_pl">Польская</string>

View file

@ -4057,11 +4057,7 @@
<string name="customize_route_line">Routenlinie anpassen</string> <string name="customize_route_line">Routenlinie anpassen</string>
<string name="shared_string_route_line">Routenlinie</string> <string name="shared_string_route_line">Routenlinie</string>
<string name="specify_color_for_map_mode">Legen Sie die Farbe für den Kartenmodus fest: %1$s.</string> <string name="specify_color_for_map_mode">Legen Sie die Farbe für den Kartenmodus fest: %1$s.</string>
<string name="release_4_0_beta">• Option zum Herunterladen von Höhenlinien in Fuß zugefügt <string name="release_4_0_beta">• OsmAnd Live-Updates nach \"Downloads &gt; Updates\" verschoben
\n
\n• Routenplanung im Querformat: Registerkarten zum Umschalten zwischen Punkten oder Diagrammen hinzugefügt
\n
\n• OsmAnd Live-Updates nach \"Downloads &gt; Updates\" verschoben
\n \n
\n• Tracks können nun nach Höhe, Geschwindigkeit oder Steigung eingefärbt werden. \n• Tracks können nun nach Höhe, Geschwindigkeit oder Steigung eingefärbt werden.
\n \n
@ -4093,8 +4089,4 @@
<string name="announce_when_exceeded">Meldung bei Überschreitung</string> <string name="announce_when_exceeded">Meldung bei Überschreitung</string>
<string name="user_points">Anwenderpunkte</string> <string name="user_points">Anwenderpunkte</string>
<string name="output">Leistung</string> <string name="output">Leistung</string>
<string name="shared_string_feet">Fuß</string>
<string name="srtm_unit_format">Einheit der Höhenlinien</string>
<string name="srtm_download_list_help_message">OsmAnd liefert Höhenlinien-Daten in Metern und Fuß. Sie müssen die Datei erneut herunterladen, um das Format zu ändern.</string>
<string name="srtm_download_single_help_message">Bitte wählen Sie das gewünschte Format. Sie müssen die Datei erneut herunterladen, um das Format zu ändern.</string>
</resources> </resources>

View file

@ -4054,11 +4054,7 @@
<string name="customize_route_line">Alĝustigi linion de kurso</string> <string name="customize_route_line">Alĝustigi linion de kurso</string>
<string name="shared_string_route_line">Linio de kurso</string> <string name="shared_string_route_line">Linio de kurso</string>
<string name="route_line_use_map_style_appearance">Por la linio de kurso estos uzata %1$s difinita por la mapstilo: %2$s.</string> <string name="route_line_use_map_style_appearance">Por la linio de kurso estos uzata %1$s difinita por la mapstilo: %2$s.</string>
<string name="release_4_0_beta">• eblo elŝuti nivelkurbojn en futoj <string name="release_4_0_beta">• ĝisdatigoj OsmAnd Live movitaj al “elŝutoj” → “ĝisdatigoj”
\n
\n• horizontala vido por “plani kurson”: aldonitaj langetoj por baskuli inter punktoj kaj diagramoj
\n
\n• ĝisdatigoj OsmAnd Live movitaj al “elŝutoj” → “ĝisdatigoj”
\n \n
\n• eblo kolorigi spurojn laŭ altitudo, rapido aŭ dekliveco \n• eblo kolorigi spurojn laŭ altitudo, rapido aŭ dekliveco
\n \n
@ -4089,8 +4085,4 @@
<string name="exit_number">Numero de elirejo</string> <string name="exit_number">Numero de elirejo</string>
<string name="user_points">Poentoj de uzanto</string> <string name="user_points">Poentoj de uzanto</string>
<string name="output">Eligo</string> <string name="output">Eligo</string>
<string name="shared_string_feet">futoj</string>
<string name="srtm_unit_format">Unuo por nivelkurboj</string>
<string name="srtm_download_list_help_message">OsmAnd liveras nivelkurbojn en metroj kaj en futoj. Ve devos reelŝuti la dosieron por ŝanĝi la formon.</string>
<string name="srtm_download_single_help_message">Elektu la deziratan formon. Vi devos reelŝuti la dosieron por ŝanĝi la formon.</string>
</resources> </resources>

View file

@ -3915,17 +3915,4 @@
<string name="poi_pilates">Pilates</string> <string name="poi_pilates">Pilates</string>
<string name="poi_jiu_jitsu">Ju-jitsu</string> <string name="poi_jiu_jitsu">Ju-jitsu</string>
<string name="poi_karate">Karaté</string> <string name="poi_karate">Karaté</string>
<string name="poi_zurkhaneh_sport">Gymnase Zurkhaneh</string>
<string name="poi_cliff_diving">Plongeon du haut d\'une falaise</string>
<string name="poi_hoops">Anneaux</string>
<string name="poi_club_social">Club social</string>
<string name="poi_plateau">Plateau</string>
<string name="poi_speedway">Voie express</string>
<string name="poi_gladed_yes">Satisfait : oui</string>
<string name="poi_camp_pitch">Emplacement de camping</string>
<string name="poi_mobile_library">Arrêt pour la bibliothèque mobile</string>
<string name="poi_office_diplomatic">Bureau diplomatique</string>
<string name="poi_horseshoes">Fers à cheval</string>
<string name="poi_cycle_polo">Polo-vélo</string>
<string name="poi_bay_filter">Type de baie</string>
</resources> </resources>

View file

@ -3275,7 +3275,7 @@
<string name="add_new_profile_q">Ajouter le profil \'%1$s\' \?</string> <string name="add_new_profile_q">Ajouter le profil \'%1$s\' \?</string>
<string name="save_heading">Inclure la direction</string> <string name="save_heading">Inclure la direction</string>
<string name="save_heading_descr">Inclure la direction de chaque point lors de l\'enregistrement d\'une trace.</string> <string name="save_heading_descr">Inclure la direction de chaque point lors de l\'enregistrement d\'une trace.</string>
<string name="rendering_attr_showCycleNodeNetworkRoutes_name">Afficher les itinéraires cyclables du réseau de nœuds</string> <string name="rendering_attr_showCycleNodeNetworkRoutes_name">Afficher le réseau de nœuds de pistes cyclables</string>
<string name="rendering_value_walkingRoutesOSMCNodes_name">Nœuds de transport</string> <string name="rendering_value_walkingRoutesOSMCNodes_name">Nœuds de transport</string>
<string name="personal_category_name">Personnel</string> <string name="personal_category_name">Personnel</string>
<string name="ltr_or_rtl_combine_via_bold_point">%1$s • %2$s</string> <string name="ltr_or_rtl_combine_via_bold_point">%1$s • %2$s</string>
@ -4040,13 +4040,9 @@
<string name="lost_data_warning">Toutes les données non enregistrées seront perdues.</string> <string name="lost_data_warning">Toutes les données non enregistrées seront perdues.</string>
<string name="show_start_dialog">Afficher la boîte de dialogue de démarrage</string> <string name="show_start_dialog">Afficher la boîte de dialogue de démarrage</string>
<string name="trip_recording_show_start_dialog_setting">Si désactivé, l\'enregistrement débutera dès appui sur le gadget ou dans le menu (sans demande de confirmation).</string> <string name="trip_recording_show_start_dialog_setting">Si désactivé, l\'enregistrement débutera dès appui sur le gadget ou dans le menu (sans demande de confirmation).</string>
<string name="release_4_0_beta">- Ajout d\'une option pour télécharger les Courbes de niveau en pieds <string name="release_4_0_beta">- Les mises à jour d\'OsmAnd Live ont été déplacées vers \"Téléchargements &gt; Mises à jour\"
\n \n
\n- Planification d\'itinéraires en paysage : ajout donglets pour basculer entre Points et Graphs \n - Les traces peuvent maintenant être colorées par altitude, vitesse ou pente.
\n
\n- Les mises à jour d\'OsmAnd Live ont été déplacées vers \"Téléchargements &gt; Mises à jour\"
\n
\n - Les traces peuvent maintenant être colorées par altitude, vitesse ou pente
\n \n
\n - Ajout d\'une option pour modifier l\'apparence de la ligne d\'itinéraire en navigation \n - Ajout d\'une option pour modifier l\'apparence de la ligne d\'itinéraire en navigation
\n \n
@ -4079,8 +4075,4 @@
<string name="exit_number">Numéro de sortie</string> <string name="exit_number">Numéro de sortie</string>
<string name="announce_when_exceeded">Annoncer en cas de dépassement</string> <string name="announce_when_exceeded">Annoncer en cas de dépassement</string>
<string name="output">Sortie</string> <string name="output">Sortie</string>
<string name="srtm_download_list_help_message">OsmAnd fournit des données sur les courbes de niveau en mètres et en pieds. Vous devrez à nouveau télécharger le fichier pour modifier le format.</string>
<string name="srtm_download_single_help_message">Veuillez sélectionner le format souhaité. Vous devrez à nouveau télécharger le fichier pour modifier le format.</string>
<string name="srtm_unit_format">Format d\'unité pour les courbes de niveau</string>
<string name="shared_string_feet">pieds</string>
</resources> </resources>

View file

@ -13,8 +13,8 @@
<string name="shared_string_help">Súgó</string> <string name="shared_string_help">Súgó</string>
<string name="accessibility_mode">Akadálymentes mód</string> <string name="accessibility_mode">Akadálymentes mód</string>
<string name="accessibility_mode_descr">Bekapcsolja a fogyatékkal élőknek szóló funkciókat.</string> <string name="accessibility_mode_descr">Bekapcsolja a fogyatékkal élőknek szóló funkciókat.</string>
<string name="shared_string_on">Bekapcsolva</string> <string name="shared_string_on">Be</string>
<string name="shared_string_off">Kikapcsolva</string> <string name="shared_string_off">Kikapcsolás</string>
<string name="accessibility_default">Android rendszerbeállítások szerint</string> <string name="accessibility_default">Android rendszerbeállítások szerint</string>
<string name="backToMenu">Vissza a menübe</string> <string name="backToMenu">Vissza a menübe</string>
<string name="zoomOut">Kicsinyít</string> <string name="zoomOut">Kicsinyít</string>
@ -1318,7 +1318,7 @@
<string name="shared_string_more">Bővebben…</string> <string name="shared_string_more">Bővebben…</string>
<string name="route_descr_destination">Célpont</string> <string name="route_descr_destination">Célpont</string>
<string name="local_index_description">Egy meglévő elem adatainak megtekintéséhez koppintson rá, inaktiváláshoz vagy törléshez nyomja meg hosszan. Jelenlegi adatok az eszközön (%1$s szabad):</string> <string name="local_index_description">Egy meglévő elem adatainak megtekintéséhez koppintson rá, inaktiváláshoz vagy törléshez nyomja meg hosszan. Jelenlegi adatok az eszközön (%1$s szabad):</string>
<string name="speed_limit_exceed">Sebességkorlátozás túllépésének tűréshatára</string> <string name="speed_limit_exceed">Sebességkorlátozás-tolerancia</string>
<string name="speed_limit_exceed_message">Válassza ki a sebességkorlátozás tűréshatárát, amely fölött hangos figyelmeztetést fog kapni.</string> <string name="speed_limit_exceed_message">Válassza ki a sebességkorlátozás tűréshatárát, amely fölött hangos figyelmeztetést fog kapni.</string>
<string name="fav_point_emoticons_message">A Kedvenc hely át lett nevezve erre: %1$s, hogy a hangulatjeleket tartalmazó szöveget fájlba lehessen menteni.</string> <string name="fav_point_emoticons_message">A Kedvenc hely át lett nevezve erre: %1$s, hogy a hangulatjeleket tartalmazó szöveget fájlba lehessen menteni.</string>
<string name="print_route">Útvonal nyomtatása</string> <string name="print_route">Útvonal nyomtatása</string>
@ -1470,7 +1470,7 @@
<string name="shared_string_release">Megjelent</string> <string name="shared_string_release">Megjelent</string>
<string name="days_behind">napos</string> <string name="days_behind">napos</string>
<string name="welmode_download_maps">Térképek letöltése</string> <string name="welmode_download_maps">Térképek letöltése</string>
<string name="confirm_usage_speed_cameras">Néhány országban (Németország, Franciaország, Olaszország stb.) tilos traffipax-riasztást használni! Az OsmAnd nem vállal felelősséget a szabályok megsértéséért. Koppintson az Igen gombra, ha jogosult a funkció használatára.</string> <string name="confirm_usage_speed_cameras">Néhány országban (Németország, Franciaország, Olaszország és még néhány) tilos a traffipax figyelmeztetés használata! Az OsmAnd nem vállal felelősséget a szabályok megsértéséért. Koppints az Igen gombra, ha jogosult vagy a funkció használatára.</string>
<string name="welcome_select_region">A jelzőtáblák és szabályok helyes értelmezéséhez jelölje ki a vezetési régiót:</string> <string name="welcome_select_region">A jelzőtáblák és szabályok helyes értelmezéséhez jelölje ki a vezetési régiót:</string>
<string name="welcome_text">Az OsmAnd lehetővé teszi a térképek és a navigáció offline használatát az egész világon.</string> <string name="welcome_text">Az OsmAnd lehetővé teszi a térképek és a navigáció offline használatát az egész világon.</string>
<string name="current_route">Jelenlegi útvonal</string> <string name="current_route">Jelenlegi útvonal</string>
@ -3583,7 +3583,7 @@
<string name="uninstall_speed_cameras">Traffipaxok eltávolítása</string> <string name="uninstall_speed_cameras">Traffipaxok eltávolítása</string>
<string name="shared_string_legal">Jogi</string> <string name="shared_string_legal">Jogi</string>
<string name="speed_camera_pois">Traffipax POI-k</string> <string name="speed_camera_pois">Traffipax POI-k</string>
<string name="speed_cameras_legal_descr">Bizonyos országokban és régiókban jogszabály tiltja a traffipaxra figyelmeztető alkalmazások használatát. <string name="speed_cameras_legal_descr">Bizonyos országokban és régiókban a traffipaxra figyelmeztető alkalmazások törvényileg tiltottak.
\n \n
\nDöntsön az ön országának törvényei alapján. \nDöntsön az ön országának törvényei alapján.
\n \n
@ -3592,14 +3592,14 @@
\nVálassza az %2$s lehetőséget, hogy az összes traffipax-szal kapcsolatos adat: riasztások, értesítések, POI-k törlésre kerüljenek az OsmAnd teljes újratelepítéséig.</string> \nVálassza az %2$s lehetőséget, hogy az összes traffipax-szal kapcsolatos adat: riasztások, értesítések, POI-k törlésre kerüljenek az OsmAnd teljes újratelepítéséig.</string>
<string name="keep_active">Maradjanak</string> <string name="keep_active">Maradjanak</string>
<string name="shared_string_uninstall">Eltávolít</string> <string name="shared_string_uninstall">Eltávolít</string>
<string name="speed_cameras_alert">Bizonyos országokban a törvény tiltja a traffipaxriasztást.</string> <string name="speed_cameras_alert">Bizonyos országokban a traffipax riasztások törvényileg tiltottak.</string>
<string name="shared_string_bearing">Tájolás</string> <string name="shared_string_bearing">Tájolás</string>
<string name="item_deleted">%1$s törölve</string> <string name="item_deleted">%1$s törölve</string>
<string name="speed_cameras_restart_descr">A traffipaxadatok végleges törléséhez indítsa újra az alkalmazást.</string> <string name="speed_cameras_restart_descr">A traffipaxadatok végleges törléséhez indítsa újra az alkalmazást.</string>
<string name="shared_string_uninstall_and_restart">Eltávolítás és Újraindítás</string> <string name="shared_string_uninstall_and_restart">Eltávolítás és Újraindítás</string>
<string name="routing_attr_length_description">Adja meg az útvonalakon a járművekre vonatkozó hosszkorlátozást.</string> <string name="routing_attr_length_description">Adja meg az útvonalakon a járművekre vonatkozó hosszkorlátozást.</string>
<string name="routing_attr_length_name">Hosszkorlátozás</string> <string name="routing_attr_length_name">Hosszkorlátozás</string>
<string name="speed_cameras_removed_descr">Az eszköz nem tartalmaz traffipaxadatokat.</string> <string name="speed_cameras_removed_descr">Az eszköz nem tartalmaz traffipax adatokat.</string>
<string name="replace_all_desc">Az jelenlegi elemek lecserélésre kerülnek a fájlban lévőkre</string> <string name="replace_all_desc">Az jelenlegi elemek lecserélésre kerülnek a fájlban lévőkre</string>
<string name="keep_both_desc">Az importált elemek előtaggal lesznek hozzáadva</string> <string name="keep_both_desc">Az importált elemek előtaggal lesznek hozzáadva</string>
<string name="import_duplicates_description">Az OsmAnd már tartalmaz az importálttal megegyező nevű elemeket. <string name="import_duplicates_description">Az OsmAnd már tartalmaz az importálttal megegyező nevű elemeket.
@ -4044,11 +4044,7 @@
<string name="lost_data_warning">Minden nem mentett adat törlődni fog.</string> <string name="lost_data_warning">Minden nem mentett adat törlődni fog.</string>
<string name="show_start_dialog">Kezdő párbeszéd megjelenítése</string> <string name="show_start_dialog">Kezdő párbeszéd megjelenítése</string>
<string name="trip_recording_show_start_dialog_setting">Ha le van tiltva, akkor a felvétel közvetlenül a widget vagy a menüelem megérintése után elindul, kihagyva a megerősítő párbeszédpanelt.</string> <string name="trip_recording_show_start_dialog_setting">Ha le van tiltva, akkor a felvétel közvetlenül a widget vagy a menüelem megérintése után elindul, kihagyva a megerősítő párbeszédpanelt.</string>
<string name="release_4_0_beta">• Új lehetőség: szinvonalak letöltése (méter mellett) lábban <string name="release_4_0_beta">• Az OsmAnd Live frissítések átköltöztek a „Letöltések&gt; Frissítések” helyre
\n
\n• Útvonaltervezési környezet: hozzáadott fülek a pontok és grafikonok közötti váltáshoz
\n
\n• Az OsmAnd Live frissítések átköltöztek a „Letöltések&gt; Frissítések” helyre
\n \n
\n• A nyomvonalak színezhetők magasság, sebesség vagy lejtés szerint. \n• A nyomvonalak színezhetők magasság, sebesség vagy lejtés szerint.
\n \n
@ -4082,8 +4078,4 @@
<string name="announce_when_exceeded">Értesítés túllépéskor</string> <string name="announce_when_exceeded">Értesítés túllépéskor</string>
<string name="user_points">Felhasználói pontok</string> <string name="user_points">Felhasználói pontok</string>
<string name="output">Teljesítmény</string> <string name="output">Teljesítmény</string>
<string name="srtm_download_single_help_message">Kérjük, válassza ki a kívánt mértékegységet. A mértékegység módosításához újra le kell töltenie a fájlt.</string>
<string name="srtm_download_list_help_message">Az OsmAnd méterben és lábban adja meg a szintvonalak magasságát. A mértékegység módosításához újra le kell töltenie a fájlt.</string>
<string name="shared_string_feet">láb</string>
<string name="srtm_unit_format">Szintvonalak mértékegysége</string>
</resources> </resources>

View file

@ -3927,5 +3927,4 @@
<string name="poi_office_diplomatic">Sendiskrifstofa</string> <string name="poi_office_diplomatic">Sendiskrifstofa</string>
<string name="poi_bay_filter">Gerð flóa</string> <string name="poi_bay_filter">Gerð flóa</string>
<string name="poi_plateau">Háslétta</string> <string name="poi_plateau">Háslétta</string>
<string name="poi_club_social">Félagsstarf</string>
</resources> </resources>

View file

@ -4052,11 +4052,7 @@
<string name="rendering_attr_noNatureReserveBoundaries_name">Mörk náttúru</string> <string name="rendering_attr_noNatureReserveBoundaries_name">Mörk náttúru</string>
<string name="trip_recording_logging_interval_info">Millibil skráninga stillir tímabilið milli þess sem OsmAnd biður um staðsetningargögn.</string> <string name="trip_recording_logging_interval_info">Millibil skráninga stillir tímabilið milli þess sem OsmAnd biður um staðsetningargögn.</string>
<string name="trip_recording_show_start_dialog_setting">Ef þetta er óvirkt, mun upptaka hefjast strax eftir að ýtt er á hnappinn eða valmyndarfærsluna og staðfestingarglugga er þá sleppt.</string> <string name="trip_recording_show_start_dialog_setting">Ef þetta er óvirkt, mun upptaka hefjast strax eftir að ýtt er á hnappinn eða valmyndarfærsluna og staðfestingarglugga er þá sleppt.</string>
<string name="release_4_0_beta">• Bætt við möguleika á að sækja hæðarlínur í fetum <string name="release_4_0_beta">• Uppfærslur OsmAnd Live færðar í \"Sótt gögn &gt; Uppfærslur\"
\n
\n• Landslag í leiðaskipulagi: bætt við flipum til að skipta á milli punkta eða grafs
\n
\n• Uppfærslur OsmAnd Live færðar í \"Sótt gögn &gt; Uppfærslur\"
\n \n
\n • Ferla er nú hægt að lita eftir hæð, hraða eða halla. \n • Ferla er nú hægt að lita eftir hæð, hraða eða halla.
\n \n
@ -4095,8 +4091,4 @@
<string name="announce_when_exceeded">Tilkynna þegar farið er yfir</string> <string name="announce_when_exceeded">Tilkynna þegar farið er yfir</string>
<string name="user_points">Punktar notanda</string> <string name="user_points">Punktar notanda</string>
<string name="map_quick_action_pattern">%1$s → …</string> <string name="map_quick_action_pattern">%1$s → …</string>
<string name="shared_string_feet">fet</string>
<string name="srtm_unit_format">Snið eininga hæðarlína</string>
<string name="srtm_download_list_help_message">OsmAnd býður upp á hæðalínugögn í metrum og fetum. Þú þarft að sækja skrána aftur til að breyta sniðinu.</string>
<string name="srtm_download_single_help_message">Veldu rétt snið eininga. Þú þarft að sækja skrána aftur til að breyta sniðinu.</string>
</resources> </resources>

View file

@ -4056,17 +4056,13 @@
<string name="customize_route_line">להתאים קו מסלול אישית</string> <string name="customize_route_line">להתאים קו מסלול אישית</string>
<string name="shared_string_route_line">קו מסלול</string> <string name="shared_string_route_line">קו מסלול</string>
<string name="specify_color_for_map_mode">לציין צבע למצב מפה: %1$s.</string> <string name="specify_color_for_map_mode">לציין צבע למצב מפה: %1$s.</string>
<string name="release_4_0_beta">נוספה אפשרות להוריד קווי מתאר ברגל <string name="release_4_0_beta">העדכונים החיים של OsmAnd הועברו אל „הורדות &gt; עדכונים”
\n \n
\n• תכנון מסלול אופקית: נוספו לשוניות למעבר בין נקודות לתרשימים \n • אפשר לצבוע מסלולים לפי גובה, מהירות או שיפוע.
\n \n
\n• העדכונים החיים של OsmAnd הועברו אל „הורדות &gt; עדכונים” \n • נוספה אפשרות לשנות את מראה קו מסלול הניווט
\n \n
\n• אפשר לצבוע מסלולים לפי גובה, מהירות או שיפוע. \n • החלונית „הקלטת מסלול” עודכנה
\n
\n• נוספה אפשרות לשנות את מראה קו מסלול הניווט
\n
\n• החלונית „הקלטת מסלול” עודכנה
\n \n
\n</string> \n</string>
<string name="osmand_live">OsmAnd חי</string> <string name="osmand_live">OsmAnd חי</string>
@ -4091,8 +4087,4 @@
<string name="announce_when_exceeded">להכריז בחריגה</string> <string name="announce_when_exceeded">להכריז בחריגה</string>
<string name="user_points">נקודות משתמש</string> <string name="user_points">נקודות משתמש</string>
<string name="output">פלט</string> <string name="output">פלט</string>
<string name="shared_string_feet">רגל</string>
<string name="srtm_unit_format">תצורת יחידת קווי מתאר</string>
<string name="srtm_download_list_help_message">OsmAnd מספק נתוני קווי מתאר במטרים וברגל. יהיה עליך להוריד את הקובץ מחדש כדי לשנות את התצורה.</string>
<string name="srtm_download_single_help_message">נא לבחור את התצורה הרצויה. יהיה עליך להוריד את הקובץ מחדש כדי לשנות את התצורה.</string>
</resources> </resources>

View file

@ -3843,7 +3843,7 @@ POIの更新は利用できません</string>
<string name="subscription_expired_title">OsmAndLiveサブスクリプションの有効期限が切れました</string> <string name="subscription_expired_title">OsmAndLiveサブスクリプションの有効期限が切れました</string>
<string name="subscription_paused_title">OsmAndLiveサブスクリプションが一時停止されました</string> <string name="subscription_paused_title">OsmAndLiveサブスクリプションが一時停止されました</string>
<string name="subscription_on_hold_title">OsmAndLiveサブスクリプションは保留中です</string> <string name="subscription_on_hold_title">OsmAndLiveサブスクリプションは保留中です</string>
<string name="markers_history">マーカー履歴</string> <string name="markers_history">マーカー履歴</string>
<string name="send_files_to_openstreetmap">GPXファイルをOpenStreetMapに送信</string> <string name="send_files_to_openstreetmap">GPXファイルをOpenStreetMapに送信</string>
<string name="enter_text_separated">タグはカンマで区切って入力してください。</string> <string name="enter_text_separated">タグはカンマで区切って入力してください。</string>
<string name="gpx_upload_public_visibility_descr">\"公開 \"状態は、追跡機能にてユーザーのGPS追跡、公開GPS追跡リスト、および生データのタイムスタンプ付き公開追跡リストに公開されることを意味します。APIを介して提供されるデータはユーザーの追跡ページを参照しません。追跡ポイントのタイムスタンプはパブリックGPS APIでは利用できず、また追跡ポイントは時系列に並んでいません。</string> <string name="gpx_upload_public_visibility_descr">\"公開 \"状態は、追跡機能にてユーザーのGPS追跡、公開GPS追跡リスト、および生データのタイムスタンプ付き公開追跡リストに公開されることを意味します。APIを介して提供されるデータはユーザーの追跡ページを参照しません。追跡ポイントのタイムスタンプはパブリックGPS APIでは利用できず、また追跡ポイントは時系列に並んでいません。</string>

View file

@ -3927,5 +3927,4 @@
<string name="poi_cliff_diving">Mergulho de falésia</string> <string name="poi_cliff_diving">Mergulho de falésia</string>
<string name="poi_zurkhaneh_sport">Zurkhaneh</string> <string name="poi_zurkhaneh_sport">Zurkhaneh</string>
<string name="poi_bay_filter">Tipo de baía</string> <string name="poi_bay_filter">Tipo de baía</string>
<string name="poi_ultimate">Ultimate</string>
</resources> </resources>

View file

@ -4049,19 +4049,15 @@
<string name="shared_string_route_line">Linha de rota</string> <string name="shared_string_route_line">Linha de rota</string>
<string name="route_line_use_map_style_appearance">A linha de rota seria usada %1$s especificado no estilo de mapa selecionado: %2$s.</string> <string name="route_line_use_map_style_appearance">A linha de rota seria usada %1$s especificado no estilo de mapa selecionado: %2$s.</string>
<string name="specify_color_for_map_mode">Especifique a cor para o modo de mapa: %1$s.</string> <string name="specify_color_for_map_mode">Especifique a cor para o modo de mapa: %1$s.</string>
<string name="release_4_0_beta">"• Adicionada opção para baixar curvas de nível em pés <string name="release_4_0_beta">• As atualizações do OsmAnd Live foram movidas para \"Downloads &gt; Atualizações\"
\n \n
\n • Plano de paisagem da rota: guias adicionadas para alternar entre pontos ou gráficos \n• As trilhas agora podem ser coloridas por altitude, velocidade ou inclinação.
\n \n
\n • As atualizações do OsmAnd Live foram movidas para \"Downloads&gt; Atualizações\" \n• Adicionada opção para alterar a aparência da linha da rota de navegação
\n \n
\n • As trilhas agora podem ser coloridas por altitude, velocidade ou inclinação. \n• Caixa de diálogo \"Gravação de viagem\" atualizada
\n \n
\n • Adicionada opção para alterar a aparência da linha da rota de navegação \n</string>
\n
\n • Caixa de diálogo \"Gravação de viagem\" atualizada
\n
\n"</string>
<string name="no_purchases">Você não tem nenhuma compra</string> <string name="no_purchases">Você não tem nenhuma compra</string>
<string name="new_device_account">Novo dispositivo / nova conta</string> <string name="new_device_account">Novo dispositivo / nova conta</string>
<string name="contact_support_description">Se você tiver alguma dúvida, entre em contato conosco em %1$s.</string> <string name="contact_support_description">Se você tiver alguma dúvida, entre em contato conosco em %1$s.</string>
@ -4085,8 +4081,4 @@
<string name="user_points">Pontos do usuário</string> <string name="user_points">Pontos do usuário</string>
<string name="output">Saída</string> <string name="output">Saída</string>
<string name="map_quick_action_pattern">%1$s → …</string> <string name="map_quick_action_pattern">%1$s → …</string>
<string name="shared_string_feet">pés</string>
<string name="srtm_unit_format">Formato da unidade de curvas de nível</string>
<string name="srtm_download_list_help_message">OsmAnd fornece dados de linhas de contorno em metros e pés. Você precisará baixar novamente o arquivo para alterar o formato.</string>
<string name="srtm_download_single_help_message">Selecione o formato necessário. Você precisará baixar novamente o arquivo para alterar o formato.</string>
</resources> </resources>

View file

@ -193,7 +193,7 @@
<string name="poi_ford_stepping_stones">Ponte pedonal em pedras separadas</string> <string name="poi_ford_stepping_stones">Ponte pedonal em pedras separadas</string>
<string name="poi_mountain_pass">Passo de montanha</string> <string name="poi_mountain_pass">Passo de montanha</string>
<string name="poi_gate">Portão</string> <string name="poi_gate">Portão</string>
<string name="poi_city_wall">Muralha/cerca de cidade</string> <string name="poi_city_wall">Muralha de cidade</string>
<string name="poi_lift_gate">Cancela elevatória</string> <string name="poi_lift_gate">Cancela elevatória</string>
<string name="poi_toll_booth">Cabine de portagem</string> <string name="poi_toll_booth">Cabine de portagem</string>
<string name="poi_border_control">Controlo aduaneiro</string> <string name="poi_border_control">Controlo aduaneiro</string>
@ -637,13 +637,13 @@
<string name="poi_australian_football">Futebol australiano</string> <string name="poi_australian_football">Futebol australiano</string>
<string name="poi_base">Base jumping</string> <string name="poi_base">Base jumping</string>
<string name="poi_baseball">Beisebol</string> <string name="poi_baseball">Beisebol</string>
<string name="poi_basketball">Basquetebol</string> <string name="poi_basketball">Basquete</string>
<string name="poi_beachvolleyball">Voleibol de praia</string> <string name="poi_beachvolleyball">Voleibol de praia</string>
<string name="poi_bmx">BMX</string> <string name="poi_bmx">BMX</string>
<string name="poi_boules">Bocha</string> <string name="poi_boules">Bocha</string>
<string name="poi_bowls">Lawn bowls</string> <string name="poi_bowls">Lawn bowls</string>
<string name="poi_canadian_football">Futebol canadiano</string> <string name="poi_canadian_football">Futebol canadiano</string>
<string name="poi_canoe">Canoagem</string> <string name="poi_canoe">Canoa</string>
<string name="poi_chess">Xadrez</string> <string name="poi_chess">Xadrez</string>
<string name="poi_climbing">Escalada</string> <string name="poi_climbing">Escalada</string>
<string name="poi_cricket">Críquete</string> <string name="poi_cricket">Críquete</string>
@ -694,7 +694,7 @@
<string name="poi_boundary_stone">Marco de fronteira</string> <string name="poi_boundary_stone">Marco de fronteira</string>
<string name="poi_historic_cannon">Canhão histórico</string> <string name="poi_historic_cannon">Canhão histórico</string>
<string name="poi_castle">Castelo</string> <string name="poi_castle">Castelo</string>
<string name="poi_city_gate">Portão/porta/arco de cidade</string> <string name="poi_city_gate">Portão/arco de cidade</string>
<string name="poi_fort">Forte</string> <string name="poi_fort">Forte</string>
<string name="poi_fountain">Chafariz</string> <string name="poi_fountain">Chafariz</string>
<string name="poi_historic_ruins">Ruínas históricas</string> <string name="poi_historic_ruins">Ruínas históricas</string>
@ -707,7 +707,7 @@
<string name="poi_aquarium">Aquário</string> <string name="poi_aquarium">Aquário</string>
<string name="poi_theme_park">Parque de diversões</string> <string name="poi_theme_park">Parque de diversões</string>
<string name="poi_attraction">Atração turística</string> <string name="poi_attraction">Atração turística</string>
<string name="poi_tourism_yes">Elemento turístico</string> <string name="poi_tourism_yes">Objeto turístico</string>
<string name="poi_attraction_amusement_ride">Atracão de feira</string> <string name="poi_attraction_amusement_ride">Atracão de feira</string>
<string name="poi_attraction_animal">Animal (atração)</string> <string name="poi_attraction_animal">Animal (atração)</string>
<string name="poi_attraction_big_wheel">Roda gigante</string> <string name="poi_attraction_big_wheel">Roda gigante</string>
@ -2866,9 +2866,9 @@
<string name="poi_aquaculture_mussels">Aquicultura: mexilhões</string> <string name="poi_aquaculture_mussels">Aquicultura: mexilhões</string>
<string name="poi_mdf">Rede de distribuição principal (MDF)</string> <string name="poi_mdf">Rede de distribuição principal (MDF)</string>
<string name="poi_min_age">Idade mínima</string> <string name="poi_min_age">Idade mínima</string>
<string name="poi_organic_yes">Produtos orgânicos: sim</string> <string name="poi_organic_yes">Sim</string>
<string name="poi_organic_no">Produtos orgânicos: não</string> <string name="poi_organic_no">Não</string>
<string name="poi_organic_only">Produtos orgânicos: unicamente</string> <string name="poi_organic_only">Unicamente</string>
<string name="poi_traffic_mirror">Espelho de tráfego</string> <string name="poi_traffic_mirror">Espelho de tráfego</string>
<string name="poi_diplomatic_consulate">Consulado</string> <string name="poi_diplomatic_consulate">Consulado</string>
<string name="poi_diplomatic_consulate_general">Consulado geral</string> <string name="poi_diplomatic_consulate_general">Consulado geral</string>
@ -3746,7 +3746,7 @@
<string name="poi_community_gender_male">Sexo comunitário: masculino</string> <string name="poi_community_gender_male">Sexo comunitário: masculino</string>
<string name="poi_community_gender_mixed">Sexo comunitário: misto</string> <string name="poi_community_gender_mixed">Sexo comunitário: misto</string>
<string name="poi_grave">Sepultura</string> <string name="poi_grave">Sepultura</string>
<string name="poi_parking_space">Lugar de estacionamento (1 veículo)</string> <string name="poi_parking_space">Espaço de estacionamento</string>
<string name="poi_url">URL</string> <string name="poi_url">URL</string>
<string name="poi_volcano_type">Tipo</string> <string name="poi_volcano_type">Tipo</string>
<string name="poi_volcano_status">Estado</string> <string name="poi_volcano_status">Estado</string>

View file

@ -678,9 +678,9 @@
<string name="loading_builds">A carregar compilações OsmAnd…</string> <string name="loading_builds">A carregar compilações OsmAnd…</string>
<string name="select_build_to_install">Selecionar a compilação OsmAnd a instalar</string> <string name="select_build_to_install">Selecionar a compilação OsmAnd a instalar</string>
<string name="contribution_activity">Instalar versão</string> <string name="contribution_activity">Instalar versão</string>
<string name="navigate_point_format_D">GGG.GGGGG</string> <string name="navigate_point_format_D">DDD.DDDDD</string>
<string name="navigate_point_format_DM">GGG MM.MMM</string> <string name="navigate_point_format_DM">DDD MM.MMM</string>
<string name="navigate_point_format_DMS">GGG MM SS.S</string> <string name="navigate_point_format_DMS">DDD MM SS.S</string>
<string name="rendering_attr_noPolygons_description">Tornar transparentes todas as características do terreno no mapa.</string> <string name="rendering_attr_noPolygons_description">Tornar transparentes todas as características do terreno no mapa.</string>
<string name="rendering_attr_noPolygons_name">Polígonos</string> <string name="rendering_attr_noPolygons_name">Polígonos</string>
<string name="rendering_attr_appMode_name">Modo de visualização</string> <string name="rendering_attr_appMode_name">Modo de visualização</string>
@ -1021,7 +1021,7 @@
<string name="av_camera_focus_infinity">Focar infinito</string> <string name="av_camera_focus_infinity">Focar infinito</string>
<string name="av_camera_focus_macro">Focagem macro (close-up)</string> <string name="av_camera_focus_macro">Focagem macro (close-up)</string>
<string name="av_camera_focus_continuous">A câmara tenta focar continuadamente</string> <string name="av_camera_focus_continuous">A câmara tenta focar continuadamente</string>
<string name="av_photo_play_sound">Reproduzir som ao tirar fotografias</string> <string name="av_photo_play_sound">Reproduzir o som do obturador da câmara</string>
<string name="av_photo_play_sound_descr">Definir som ou silêncio ao fotografar.</string> <string name="av_photo_play_sound_descr">Definir som ou silêncio ao fotografar.</string>
<string name="driving_region_canada">Canadá</string> <string name="driving_region_canada">Canadá</string>
<string name="about_version">Versão:</string> <string name="about_version">Versão:</string>
@ -2013,7 +2013,7 @@
<string name="routing_attr_height_obstacles_name">Utilizar dados de elevação</string> <string name="routing_attr_height_obstacles_name">Utilizar dados de elevação</string>
<string name="rendering_attr_depthContours_description">Mostrar pontos e contornos de profundidade.</string> <string name="rendering_attr_depthContours_description">Mostrar pontos e contornos de profundidade.</string>
<string name="rendering_attr_depthContours_name">Contornos de profundidade náuticos</string> <string name="rendering_attr_depthContours_name">Contornos de profundidade náuticos</string>
<string name="show_transparency_seekbar">Mostrar barra deslizante de transparência</string> <string name="show_transparency_seekbar">Mostra a transparência da barra de navegação</string>
<string name="shared_string_widgets">Widgets</string> <string name="shared_string_widgets">Widgets</string>
<string name="rendering_attr_hideUnderground_name">Objetos subterrâneos</string> <string name="rendering_attr_hideUnderground_name">Objetos subterrâneos</string>
<string name="auto_split_recording_title">Dividir automaticamente as gravações após quebras</string> <string name="auto_split_recording_title">Dividir automaticamente as gravações após quebras</string>
@ -3440,7 +3440,7 @@
<string name="create_custom_categories_list_promo">Altere a ordenação da lista e oculte categorias. Pode importar ou exportar todas as alterações com perfis.</string> <string name="create_custom_categories_list_promo">Altere a ordenação da lista e oculte categorias. Pode importar ou exportar todas as alterações com perfis.</string>
<string name="rearrange_categories">Reorganizar categorias</string> <string name="rearrange_categories">Reorganizar categorias</string>
<string name="osm_authorization_success">Autorização bem sucedida</string> <string name="osm_authorization_success">Autorização bem sucedida</string>
<string name="multimedia_photo_play_sound">Som ao tirar fotografias</string> <string name="multimedia_photo_play_sound">Som do obturador da câmara</string>
<string name="multimedia_use_system_camera">Usar aplicação do sistema</string> <string name="multimedia_use_system_camera">Usar aplicação do sistema</string>
<string name="multimedia_rec_split_title">Dividir gravações</string> <string name="multimedia_rec_split_title">Dividir gravações</string>
<string name="reset_plugin_to_default">Repor configurações originais da extensão</string> <string name="reset_plugin_to_default">Repor configurações originais da extensão</string>
@ -3960,17 +3960,13 @@
<string name="routing_engine_vehicle_type_cycling_electric">Bicicleta elétrica</string> <string name="routing_engine_vehicle_type_cycling_electric">Bicicleta elétrica</string>
<string name="live_update_frequency_hour_variant">As atualizações ao mapa serão verificadas a todas as horas. Próxima %1$s em %2$s.</string> <string name="live_update_frequency_hour_variant">As atualizações ao mapa serão verificadas a todas as horas. Próxima %1$s em %2$s.</string>
<string name="live_update_delete_updates_msg">Tem a certeza que quer eliminar todas as %s atualizações OsmAnd Live\?</string> <string name="live_update_delete_updates_msg">Tem a certeza que quer eliminar todas as %s atualizações OsmAnd Live\?</string>
<string name="release_4_0_beta">• Adicionada opção para descarregar curvas de nível em pés. <string name="release_4_0_beta">• Atualizações OsmAnd Live movidas para \"Descarregamentos &gt; Atualizações\"
\n
\n• Planear rota: adicionadas abas para alternar entre pontos ou gráficos.
\n
\n• Atualizações OsmAnd Live movidas para \"Descarregamentos &gt; Atualizações\"
\n \n
\n• Os trilhos podem ser agora coloridos conforme a altitude, velocidade e declive. \n• Os trilhos podem ser agora coloridos conforme a altitude, velocidade e declive.
\n \n
\n• Adicionada opção para alterar a aparência da linha de rota de navegação. \n• Adicionada opção para alterar a aparência da linha de rota de navegação
\n \n
\n• Janela de diálogo \"Gravação do trilho\" atualizada. \n• Janela de diálogo \"Gravação do trilho\" atualizada
\n \n
\n</string> \n</string>
<string name="routing_attr_height_obstacles_description">O roteamento pode evitar subidas íngremes.</string> <string name="routing_attr_height_obstacles_description">O roteamento pode evitar subidas íngremes.</string>
@ -4093,8 +4089,4 @@
<string name="announce_when_exceeded">Anunciar quando ultrapassado</string> <string name="announce_when_exceeded">Anunciar quando ultrapassado</string>
<string name="user_points">Pontos do utilizador</string> <string name="user_points">Pontos do utilizador</string>
<string name="output">Saída</string> <string name="output">Saída</string>
<string name="shared_string_feet">pés</string>
<string name="srtm_download_list_help_message">O OsmAnd fornece dados de curvas de nível em metros e pés. Terá de descarregar novamente o ficheiro para alterar o formato.</string>
<string name="srtm_unit_format">Formato de unidades de curvas de nível</string>
<string name="srtm_download_single_help_message">Selecione o formato necessário. Terá de descarregar novamente o ficheiro para alterar o formato.</string>
</resources> </resources>

View file

@ -2872,7 +2872,7 @@
<string name="sit_on_the_stop">Посадка на остановке</string> <string name="sit_on_the_stop">Посадка на остановке</string>
<string name="use_osm_live_public_transport_description">Включить общественный транспорт с учётом автообновлений OsmAnd Live.</string> <string name="use_osm_live_public_transport_description">Включить общественный транспорт с учётом автообновлений OsmAnd Live.</string>
<string name="use_osm_live_public_transport">Общественный транспорт OsmAnd Live</string> <string name="use_osm_live_public_transport">Общественный транспорт OsmAnd Live</string>
<string name="transfers_size">пересадки: %1$d</string> <string name="transfers_size">%1$d пересадки</string>
<string name="rendering_attr_surface_unpaved_name">Грунтовая</string> <string name="rendering_attr_surface_unpaved_name">Грунтовая</string>
<string name="rendering_attr_surface_sand_name">Песок</string> <string name="rendering_attr_surface_sand_name">Песок</string>
<string name="rendering_attr_surface_grass_name">Трава</string> <string name="rendering_attr_surface_grass_name">Трава</string>
@ -3263,7 +3263,7 @@
<string name="selected_profile">Выбранный профиль</string> <string name="selected_profile">Выбранный профиль</string>
<string name="personal_category_name">Персональный</string> <string name="personal_category_name">Персональный</string>
<string name="shared_string_downloading_formatted">Скачивание %s</string> <string name="shared_string_downloading_formatted">Скачивание %s</string>
<string name="rendering_value_thick_name">Толстая</string> <string name="rendering_value_thick_name">Толсто</string>
<string name="default_speed_dialog_msg">Используется для оценки времени прибытия для неизвестного типа дорог и ограничения скорости для всех дорог (может изменить маршрут)</string> <string name="default_speed_dialog_msg">Используется для оценки времени прибытия для неизвестного типа дорог и ограничения скорости для всех дорог (может изменить маршрут)</string>
<string name="routing_attr_allow_intermediate_name">Разрешить промежуточные маршруты</string> <string name="routing_attr_allow_intermediate_name">Разрешить промежуточные маршруты</string>
<string name="routing_attr_allow_advanced_name">Разрешить расширенные маршруты</string> <string name="routing_attr_allow_advanced_name">Разрешить расширенные маршруты</string>
@ -3302,7 +3302,7 @@
<string name="rendering_attr_piste_difficulty_connection_name">Соединение</string> <string name="rendering_attr_piste_difficulty_connection_name">Соединение</string>
<string name="simulate_your_location_gpx_descr">Симулировать свою позицию используя записанный GPX трек.</string> <string name="simulate_your_location_gpx_descr">Симулировать свою позицию используя записанный GPX трек.</string>
<string name="route_start_point">Начало маршрута</string> <string name="route_start_point">Начало маршрута</string>
<string name="shared_string_revert">Сброс</string> <string name="shared_string_revert">Вернуться</string>
<string name="suggested_maps_descr">Эти карты необходимо использовать с плагином.</string> <string name="suggested_maps_descr">Эти карты необходимо использовать с плагином.</string>
<string name="added_profiles">Добавленные профили</string> <string name="added_profiles">Добавленные профили</string>
<string name="added_profiles_descr">Профили, добавленные плагином</string> <string name="added_profiles_descr">Профили, добавленные плагином</string>
@ -4056,11 +4056,7 @@
<string name="next_billing_date">Следующая дата оплаты: %1$s</string> <string name="next_billing_date">Следующая дата оплаты: %1$s</string>
<string name="osmand_live">OsmAnd Live</string> <string name="osmand_live">OsmAnd Live</string>
<string name="annual_subscription">Годовая подписка</string> <string name="annual_subscription">Годовая подписка</string>
<string name="release_4_0_beta">• Добавлена возможность скачать контурные линии в футах. <string name="release_4_0_beta">• Обновления OsmAnd Live перемещены в «Загрузка карт» → «Обновления».
\n
\n• Планирование маршрута: добавлены вкладки для переключения между точками и графиками.
\n
\n• Обновления OsmAnd Live перемещены в «Загрузка карт» → «Обновления».
\n \n
\n• Теперь треки можно раскрашивать по высоте, скорости или уклону. \n• Теперь треки можно раскрашивать по высоте, скорости или уклону.
\n \n
@ -4091,8 +4087,4 @@
<string name="output">Вывод</string> <string name="output">Вывод</string>
<string name="map_quick_action_pattern">%1$s → …</string> <string name="map_quick_action_pattern">%1$s → …</string>
<string name="exit_number">Номер съезда</string> <string name="exit_number">Номер съезда</string>
<string name="srtm_unit_format">Формат единиц на контурных линиях</string>
<string name="srtm_download_single_help_message">Выберите необходимый формат. Для изменения формата потребуется повторно загрузить файл.</string>
<string name="shared_string_feet">футы</string>
<string name="srtm_download_list_help_message">OsmAnd предоставляет данные изолиний в метрах и футах. Вам нужно будет повторно загрузить файл, чтобы изменить формат.</string>
</resources> </resources>

View file

@ -4045,11 +4045,7 @@
<string name="lost_data_warning">Všetky neuložené údaje budú stratené.</string> <string name="lost_data_warning">Všetky neuložené údaje budú stratené.</string>
<string name="show_start_dialog">Zobraziť úvodné okno</string> <string name="show_start_dialog">Zobraziť úvodné okno</string>
<string name="trip_recording_show_start_dialog_setting">Ak je vypnuté, záznam začne hneď po stlačení nástroja alebo položky v menu a preskočí okno nastavenia.</string> <string name="trip_recording_show_start_dialog_setting">Ak je vypnuté, záznam začne hneď po stlačení nástroja alebo položky v menu a preskočí okno nastavenia.</string>
<string name="release_4_0_beta">• Pridaná možnosť stiahnutia Vrstevníc v stopách <string name="release_4_0_beta">• Aktualizácie OsmAnd Live presunuté do \"Sťahovania &gt; Aktualizácie\"
\n
\n• Plánovať trasy: pridané prepínače medzi bodmi a grafmi
\n
\n• Aktualizácie OsmAnd Live presunuté do \"Sťahovania &gt; Aktualizácie\"
\n \n
\n • Stopy je teraz možné vyfarbiť podľa nadmorskej výšky, rýchlosti alebo sklonu svahu. \n • Stopy je teraz možné vyfarbiť podľa nadmorskej výšky, rýchlosti alebo sklonu svahu.
\n \n
@ -4085,8 +4081,4 @@
<string name="user_points">Body používateľa</string> <string name="user_points">Body používateľa</string>
<string name="output">Výstup</string> <string name="output">Výstup</string>
<string name="map_quick_action_pattern">%1$s → …</string> <string name="map_quick_action_pattern">%1$s → …</string>
<string name="shared_string_feet">stopy</string>
<string name="srtm_unit_format">Formát jednotiek vrstevníc</string>
<string name="srtm_download_list_help_message">OsmAnd poskytuje údaje vrstevníc v metroch a stopách. Budete musieť znovu stiahnuť súbor pre zmenu formátu.</string>
<string name="srtm_download_single_help_message">Prosím zvoľte požadovaný formát. Budete musieť znovu stiahnuť súbor pre zmenu formátu.</string>
</resources> </resources>

View file

@ -4072,11 +4072,7 @@
<string name="in_grace_period">Ek süre içinde</string> <string name="in_grace_period">Ek süre içinde</string>
<string name="on_hold">Beklemede</string> <string name="on_hold">Beklemede</string>
<string name="expired">Süresi doldu</string> <string name="expired">Süresi doldu</string>
<string name="release_4_0_beta">• Eş yükselti eğrilerini fit cinsinden indirme seçeneği eklendi <string name="release_4_0_beta">• OsmAnd Live güncellemeleri \"İndirmeler&gt; Güncellemeler\" bölümüne taşındı
\n
\n • Güzergah Planla görünümü: noktalar veya grafikler arasında geçiş yapmak için sekmeler eklendi
\n
\n • OsmAnd Live güncellemeleri \"İndirmeler &gt; Güncellemeler\" bölümüne taşındı
\n \n
\n • Yollar artık rakım, hız veya eğime göre renklendirilebilir \n • Yollar artık rakım, hız veya eğime göre renklendirilebilir
\n \n
@ -4091,8 +4087,4 @@
<string name="user_points">Kullanıcı puanları</string> <string name="user_points">Kullanıcı puanları</string>
<string name="output">Çıkış</string> <string name="output">Çıkış</string>
<string name="map_quick_action_pattern">%1$s → …</string> <string name="map_quick_action_pattern">%1$s → …</string>
<string name="shared_string_feet">fit</string>
<string name="srtm_unit_format">Eş yükselti eğrileri birimi biçimi</string>
<string name="srtm_download_list_help_message">OsmAnd, metre ve fit cinsinden eş yükselti eğrileri verileri sağlar. Biçimi değiştirmek için dosyayı yeniden indirmeniz gerekecek.</string>
<string name="srtm_download_single_help_message">Lütfen gerekli biçimi seçin. Biçimi değiştirmek için dosyayı yeniden indirmeniz gerekecek.</string>
</resources> </resources>

View file

@ -4053,11 +4053,7 @@
<string name="shared_string_route_line">Лінія маршруту</string> <string name="shared_string_route_line">Лінія маршруту</string>
<string name="route_line_use_map_style_appearance">Лінія маршруту застосовуватиме %1$s, вказаний у вибраному стилі мапи: %2$s.</string> <string name="route_line_use_map_style_appearance">Лінія маршруту застосовуватиме %1$s, вказаний у вибраному стилі мапи: %2$s.</string>
<string name="specify_color_for_map_mode">Вкажіть колір для режиму мапи: %1$s.</string> <string name="specify_color_for_map_mode">Вкажіть колір для режиму мапи: %1$s.</string>
<string name="release_4_0_beta">• Додана можливість завантаження контурних ліній у футах <string name="release_4_0_beta">• Оновлення OsmAnd Live переміщено до «Завантаження &gt;Оновлення»
\n
\n• Ландшафтне планування маршруту: додані вкладки для перемикання між точками або графіками
\n
\n• Оновлення OsmAnd Live переміщено до «Завантаження &gt;Оновлення»
\n \n
\n• Тепер треки можуть бути забарвлені за висотою, швидкістю або нахилом. \n• Тепер треки можуть бути забарвлені за висотою, швидкістю або нахилом.
\n \n
@ -4088,8 +4084,4 @@
<string name="announce_when_exceeded">Повідомляти про перевищення</string> <string name="announce_when_exceeded">Повідомляти про перевищення</string>
<string name="user_points">Користувацькі точки</string> <string name="user_points">Користувацькі точки</string>
<string name="output">Вивід</string> <string name="output">Вивід</string>
<string name="srtm_download_list_help_message">OsmAnd надає дані горизонталей в метрах і футах. Щоб змінити формат, потрібно повторно завантажити файл.</string>
<string name="srtm_unit_format">Формат одиниць вимірювання горизонталей</string>
<string name="shared_string_feet">фути</string>
<string name="srtm_download_single_help_message">Виберіть потрібний формат. Щоб змінити формат, потрібно повторно завантажувати файл.</string>
</resources> </resources>

View file

@ -4047,11 +4047,7 @@
<string name="shared_string_route_line">路線</string> <string name="shared_string_route_line">路線</string>
<string name="route_line_use_map_style_appearance">路線將會使用 %1$s 在選定的地圖樣式上指定的:%2$s。</string> <string name="route_line_use_map_style_appearance">路線將會使用 %1$s 在選定的地圖樣式上指定的:%2$s。</string>
<string name="specify_color_for_map_mode">指定地圖模式的顏色:%1$s。</string> <string name="specify_color_for_map_mode">指定地圖模式的顏色:%1$s。</string>
<string name="release_4_0_beta">• 新增以英呎為單位下載等高線 <string name="release_4_0_beta">• OsmAnd Live 更新移動至「下載 &gt; 更新」
\n
\n • 規劃路線樣式:新增切換點與圖形的分頁
\n
\n • OsmAnd Live 更新移動至「下載 &gt; 更新」
\n \n
\n • 軌跡現在可以使用海拔、速度或坡度來填色 \n • 軌跡現在可以使用海拔、速度或坡度來填色
\n \n
@ -4083,8 +4079,4 @@
<string name="user_points">使用者點</string> <string name="user_points">使用者點</string>
<string name="output">輸出</string> <string name="output">輸出</string>
<string name="map_quick_action_pattern">%1$s → …</string> <string name="map_quick_action_pattern">%1$s → …</string>
<string name="shared_string_feet">英呎</string>
<string name="srtm_unit_format">等高線單位格式</string>
<string name="srtm_download_list_help_message">OsmAnd 提供以公尺與英呎為單位的等高線資料。您將必須重新下載檔案以變更格式。</string>
<string name="srtm_download_single_help_message">請選取需要格式。您將必須重新下載檔案以變更格式。</string>
</resources> </resources>

View file

@ -12,9 +12,11 @@
--> -->
<string name="shared_string_max_height">Max. height</string> <string name="use_system_language">Use system language</string>
<string name="shared_string_min_height">Min. height</string> <string name="recorded_description">Recorded voice sounds better, but can pronounce only prerecorded phrases: turn instructions. Can\'t announce street names or POI names.</string>
<string name="route_line_use_gradient_coloring">Route line will be colorized depending on the elevation profile of the route.</string> <string name="tts_title">TTS</string>
<string name="tts_description">Text-to-speech (TTS) can pronounce all types of instructions: street names, turn instruction, POI names etc.</string>
<string name="language_description">Select preferred language and type of voice guidance.</string>
<string name="output">Output</string> <string name="output">Output</string>
<string name="user_points">User points</string> <string name="user_points">User points</string>
<string name="announce_when_exceeded">Announce when exceeded</string> <string name="announce_when_exceeded">Announce when exceeded</string>

View file

@ -15,23 +15,19 @@
android:key="voice_provider" android:key="voice_provider"
android:layout="@layout/preference_with_descr" android:layout="@layout/preference_with_descr"
android:persistent="false" android:persistent="false"
android:title="@string/shared_string_languages" android:title="@string/shared_string_language"
tools:icon="@drawable/ic_action_volume_up" /> tools:icon="@drawable/ic_action_volume_up" />
<Preference <Preference
android:key="language_divider"
android:layout="@layout/simple_divider_item" android:layout="@layout/simple_divider_item"
android:selectable="false" /> android:selectable="false" />
<PreferenceCategory <PreferenceCategory
android:key="language_and_output" android:key="announce_header"
android:layout="@layout/preference_category_with_descr" android:layout="@layout/preference_category_title"
android:title="@string/accessibility_announce" /> android:title="@string/accessibility_announce" />
<net.osmand.plus.settings.preferences.SwitchPreferenceEx
android:key="turn_screen_on_navigation_instructions"
android:layout="@layout/preference_with_descr"
android:title="@string/turn_screen_on_navigation_instructions" />
<SwitchPreferenceCompat <SwitchPreferenceCompat
android:key="speak_street_names" android:key="speak_street_names"
android:layout="@layout/preference_switch" android:layout="@layout/preference_switch"
@ -43,6 +39,7 @@
android:title="@string/exit_number" /> android:title="@string/exit_number" />
<Preference <Preference
android:key="exit_number_divider"
android:layout="@layout/divider_half_item" android:layout="@layout/divider_half_item"
android:selectable="false" /> android:selectable="false" />
@ -61,18 +58,27 @@
android:layout="@layout/preference_switch" android:layout="@layout/preference_switch"
android:title="@string/speak_cameras" /> android:title="@string/speak_cameras" />
<Preference
android:key="speed_cameras_uninstalled"
android:layout="@layout/preference_permission"
android:persistent="false"
android:summary="@string/read_more"
android:title="@string/speed_cameras_alert"
tools:icon="@drawable/ic_action_alert" />
<SwitchPreferenceCompat <SwitchPreferenceCompat
android:key="speak_tunnels" android:key="speak_tunnels"
android:layout="@layout/preference_switch" android:layout="@layout/preference_switch"
android:title="@string/show_tunnels" /> android:title="@string/show_tunnels" />
<Preference <Preference
android:key="announce_divider"
android:layout="@layout/divider_half_item" android:layout="@layout/divider_half_item"
android:selectable="false" /> android:selectable="false" />
<PreferenceCategory <PreferenceCategory
android:key="language_and_output" android:key="user_points_header"
android:layout="@layout/preference_category_with_descr" android:layout="@layout/preference_category_title"
android:title="@string/user_points" /> android:title="@string/user_points" />
<SwitchPreferenceCompat <SwitchPreferenceCompat
@ -91,12 +97,13 @@
android:title="@string/speak_poi" /> android:title="@string/speak_poi" />
<Preference <Preference
android:key="user_points_divider"
android:layout="@layout/divider_half_item" android:layout="@layout/divider_half_item"
android:selectable="false" /> android:selectable="false" />
<PreferenceCategory <PreferenceCategory
android:key="language_and_output" android:key="speed_limit_header"
android:layout="@layout/preference_category_with_descr" android:layout="@layout/preference_category_title"
android:title="@string/speak_speed_limit" /> android:title="@string/speak_speed_limit" />
<SwitchPreferenceCompat <SwitchPreferenceCompat
@ -110,16 +117,13 @@
android:title="@string/speed_limit_exceed" /> android:title="@string/speed_limit_exceed" />
<Preference <Preference
android:layout="@layout/simple_divider_item" android:key="speed_limit_divider"
android:selectable="false" />
<Preference
android:layout="@layout/simple_divider_item" android:layout="@layout/simple_divider_item"
android:selectable="false" /> android:selectable="false" />
<PreferenceCategory <PreferenceCategory
android:key="language_and_output" android:key="options_header"
android:layout="@layout/preference_category_with_descr" android:layout="@layout/preference_category_title"
android:title="@string/shared_string_options" /> android:title="@string/shared_string_options" />
<net.osmand.plus.settings.preferences.ListPreferenceEx <net.osmand.plus.settings.preferences.ListPreferenceEx
@ -133,12 +137,13 @@
android:title="@string/announcement_time_title" /> android:title="@string/announcement_time_title" />
<Preference <Preference
android:key="options_divider"
android:layout="@layout/simple_divider_item" android:layout="@layout/simple_divider_item"
android:selectable="false" /> android:selectable="false" />
<PreferenceCategory <PreferenceCategory
android:key="language_and_output" android:key="output_header"
android:layout="@layout/preference_category_with_descr" android:layout="@layout/preference_category_title"
android:title="@string/output" /> android:title="@string/output" />
</PreferenceScreen> </PreferenceScreen>

View file

@ -38,7 +38,6 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.concurrent.Executor;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream; import java.util.zip.GZIPOutputStream;
@ -48,14 +47,13 @@ public class AndroidNetworkUtils {
private static final Log LOG = PlatformUtil.getLog(AndroidNetworkUtils.class); private static final Log LOG = PlatformUtil.getLog(AndroidNetworkUtils.class);
public interface OnRequestResultListener { public interface OnRequestResultListener {
void onResult(@Nullable String result, @Nullable String error); void onResult(String result);
} }
public interface OnFilesUploadCallback { public interface OnFilesUploadCallback {
@Nullable @Nullable
Map<String, String> getAdditionalParams(@NonNull File file); Map<String, String> getAdditionalParams(@NonNull File file);
void onFileUploadProgress(@NonNull File file, int percent); void onFileUploadProgress(@NonNull File file, int percent);
void onFileUploadDone(@NonNull File file);
void onFilesUploadDone(@NonNull Map<File, String> errors); void onFilesUploadDone(@NonNull Map<File, String> errors);
} }
@ -65,26 +63,16 @@ public class AndroidNetworkUtils {
void onFileDownloadProgress(@NonNull File file, int percent); void onFileDownloadProgress(@NonNull File file, int percent);
@WorkerThread @WorkerThread
void onFileDownloadedAsync(@NonNull File file); void onFileDownloadedAsync(@NonNull File file);
void onFileDownloadDone(@NonNull File file);
void onFilesDownloadDone(@NonNull Map<File, String> errors); void onFilesDownloadDone(@NonNull Map<File, String> errors);
} }
public static class RequestResponse { public static class RequestResponse {
private final Request request; private Request request;
private final String response; private String response;
private final String error;
RequestResponse(@NonNull Request request, @Nullable String response) { RequestResponse(@NonNull Request request, @Nullable String response) {
this.request = request; this.request = request;
this.response = response; this.response = response;
this.error = null;
}
RequestResponse(@NonNull Request request, @Nullable String response, @Nullable String error) {
this.request = request;
this.response = response;
this.error = error;
} }
public Request getRequest() { public Request getRequest() {
@ -94,10 +82,6 @@ public class AndroidNetworkUtils {
public String getResponse() { public String getResponse() {
return response; return response;
} }
public String getError() {
return error;
}
} }
public interface OnSendRequestsListener { public interface OnSendRequestsListener {
@ -108,13 +92,6 @@ public class AndroidNetworkUtils {
public static void sendRequestsAsync(@Nullable final OsmandApplication ctx, public static void sendRequestsAsync(@Nullable final OsmandApplication ctx,
@NonNull final List<Request> requests, @NonNull final List<Request> requests,
@Nullable final OnSendRequestsListener listener) { @Nullable final OnSendRequestsListener listener) {
sendRequestsAsync(ctx, requests, listener, AsyncTask.THREAD_POOL_EXECUTOR);
}
public static void sendRequestsAsync(@Nullable final OsmandApplication ctx,
@NonNull final List<Request> requests,
@Nullable final OnSendRequestsListener listener,
final Executor executor) {
new AsyncTask<Void, RequestResponse, List<RequestResponse>>() { new AsyncTask<Void, RequestResponse, List<RequestResponse>>() {
@ -124,18 +101,11 @@ public class AndroidNetworkUtils {
for (Request request : requests) { for (Request request : requests) {
RequestResponse requestResponse; RequestResponse requestResponse;
try { try {
final String[] response = {null, null}; String response = sendRequest(ctx, request.getUrl(), request.getParameters(),
sendRequest(ctx, request.getUrl(), request.getParameters(), request.getUserOperation(), request.isToastAllowed(), request.isPost());
request.getUserOperation(), request.isToastAllowed(), request.isPost(), new OnRequestResultListener() { requestResponse = new RequestResponse(request, response);
@Override
public void onResult(@Nullable String result, @Nullable String error) {
response[0] = result;
response[1] = error;
}
});
requestResponse = new RequestResponse(request, response[0], response[1]);
} catch (Exception e) { } catch (Exception e) {
requestResponse = new RequestResponse(request, null, "Unexpected error"); requestResponse = new RequestResponse(request, null);
} }
responses.add(requestResponse); responses.add(requestResponse);
publishProgress(requestResponse); publishProgress(requestResponse);
@ -157,7 +127,7 @@ public class AndroidNetworkUtils {
} }
} }
}.executeOnExecutor(executor, (Void) null); }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);
} }
public static void sendRequestAsync(final OsmandApplication ctx, public static void sendRequestAsync(final OsmandApplication ctx,
@ -167,45 +137,26 @@ public class AndroidNetworkUtils {
final boolean toastAllowed, final boolean toastAllowed,
final boolean post, final boolean post,
final OnRequestResultListener listener) { final OnRequestResultListener listener) {
sendRequestAsync(ctx, url, parameters, userOperation, toastAllowed, post, listener,
AsyncTask.THREAD_POOL_EXECUTOR);
}
public static void sendRequestAsync(final OsmandApplication ctx, new AsyncTask<Void, Void, String>() {
final String url,
final Map<String, String> parameters,
final String userOperation,
final boolean toastAllowed,
final boolean post,
final OnRequestResultListener listener,
final Executor executor) {
new AsyncTask<Void, Void, String[]>() {
@Override @Override
protected String[] doInBackground(Void... params) { protected String doInBackground(Void... params) {
final String[] res = {null, null};
try { try {
sendRequest(ctx, url, parameters, userOperation, toastAllowed, post, new OnRequestResultListener() { return sendRequest(ctx, url, parameters, userOperation, toastAllowed, post);
@Override
public void onResult(@Nullable String result, @Nullable String error) {
res[0] = result;
res[1] = error;
}
});
} catch (Exception e) { } catch (Exception e) {
// ignore return null;
} }
return res;
} }
@Override @Override
protected void onPostExecute(String[] response) { protected void onPostExecute(String response) {
if (listener != null) { if (listener != null) {
listener.onResult(response[0], response[1]); listener.onResult(response);
} }
} }
}.executeOnExecutor(executor, (Void) null); }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);
} }
public static void downloadFileAsync(final String url, public static void downloadFileAsync(final String url,
@ -232,14 +183,6 @@ public class AndroidNetworkUtils {
final @NonNull List<File> files, final @NonNull List<File> files,
final @NonNull Map<String, String> parameters, final @NonNull Map<String, String> parameters,
final @Nullable OnFilesDownloadCallback callback) { final @Nullable OnFilesDownloadCallback callback) {
downloadFilesAsync(url, files, parameters, callback, AsyncTask.THREAD_POOL_EXECUTOR);
}
public static void downloadFilesAsync(final @NonNull String url,
final @NonNull List<File> files,
final @NonNull Map<String, String> parameters,
final @Nullable OnFilesDownloadCallback callback,
final Executor executor) {
new AsyncTask<Void, Object, Map<File, String>>() { new AsyncTask<Void, Object, Map<File, String>>() {
@ -285,7 +228,7 @@ public class AndroidNetworkUtils {
} catch (Exception e) { } catch (Exception e) {
errors.put(file, e.getMessage()); errors.put(file, e.getMessage());
} }
publishProgress(file, -1); publishProgress(file, Integer.MAX_VALUE);
} }
return errors; return errors;
} }
@ -293,13 +236,7 @@ public class AndroidNetworkUtils {
@Override @Override
protected void onProgressUpdate(Object... objects) { protected void onProgressUpdate(Object... objects) {
if (callback != null) { if (callback != null) {
File file = (File) objects[0]; callback.onFileDownloadProgress((File) objects[0], (Integer) objects[1]);
Integer progress = (Integer) objects[1];
if (progress >= 0) {
callback.onFileDownloadProgress(file, progress);
} else {
callback.onFileDownloadDone(file);
}
} }
} }
@ -310,23 +247,15 @@ public class AndroidNetworkUtils {
} }
} }
}.executeOnExecutor(executor, (Void) null); }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);
} }
public static String sendRequest(@Nullable OsmandApplication ctx, @NonNull String url, public static String sendRequest(@Nullable OsmandApplication ctx, @NonNull String url,
@Nullable Map<String, String> parameters, @Nullable Map<String, String> parameters,
@Nullable String userOperation, boolean toastAllowed, boolean post) { @Nullable String userOperation, boolean toastAllowed, boolean post) {
return sendRequest(ctx, url, parameters, userOperation, toastAllowed, post, null);
}
public static String sendRequest(@Nullable OsmandApplication ctx, @NonNull String url,
@Nullable Map<String, String> parameters,
@Nullable String userOperation, boolean toastAllowed, boolean post,
@Nullable OnRequestResultListener listener) {
String result = null;
String error = null;
HttpURLConnection connection = null; HttpURLConnection connection = null;
try { try {
String params = null; String params = null;
if (parameters != null && parameters.size() > 0) { if (parameters != null && parameters.size() > 0) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
@ -356,66 +285,68 @@ public class AndroidNetworkUtils {
output.write(params.getBytes("UTF-8")); output.write(params.getBytes("UTF-8"));
output.flush(); output.flush();
output.close(); output.close();
} else { } else {
connection.setRequestMethod("GET"); connection.setRequestMethod("GET");
connection.connect(); connection.connect();
} }
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) { if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
if (ctx != null) {
error = (!Algorithms.isEmpty(userOperation) ? userOperation + " " : "")
+ ctx.getString(R.string.failed_op) + ": " + connection.getResponseMessage();
} else {
error = (!Algorithms.isEmpty(userOperation) ? userOperation + " " : "")
+ "failed: " + connection.getResponseMessage();
}
if (toastAllowed && ctx != null) { if (toastAllowed && ctx != null) {
showToast(ctx, error); String msg = (!Algorithms.isEmpty(userOperation) ? userOperation + " " : "")
} + ctx.getString(R.string.failed_op) + ": "
InputStream errorStream = connection.getErrorStream(); + connection.getResponseMessage();
if (errorStream != null) { showToast(ctx, msg);
error = streamToString(errorStream);
} }
} else { } else {
result = streamToString(connection.getInputStream()); StringBuilder responseBody = new StringBuilder();
responseBody.setLength(0);
InputStream i = connection.getInputStream();
if (i != null) {
BufferedReader in = new BufferedReader(new InputStreamReader(i, "UTF-8"), 256);
String s;
boolean f = true;
while ((s = in.readLine()) != null) {
if (!f) {
responseBody.append("\n");
} else {
f = false;
} }
responseBody.append(s);
}
try {
in.close();
i.close();
} catch (Exception e) {
// ignore exception
}
}
return responseBody.toString();
}
} catch (NullPointerException e) { } catch (NullPointerException e) {
// that's tricky case why NPE is thrown to fix that problem httpClient could be used // that's tricky case why NPE is thrown to fix that problem httpClient could be used
if (ctx != null) {
error = ctx.getString(R.string.auth_failed);
} else {
error = "Authorization failed";
}
if (toastAllowed && ctx != null) { if (toastAllowed && ctx != null) {
showToast(ctx, error); String msg = ctx.getString(R.string.auth_failed);
showToast(ctx, msg);
} }
} catch (MalformedURLException e) { } catch (MalformedURLException e) {
if (ctx != null) {
error = MessageFormat.format(ctx.getResources().getString(R.string.shared_string_action_template)
+ ": " + ctx.getResources().getString(R.string.shared_string_unexpected_error), userOperation);
} else {
error = "Action " + userOperation + ": Unexpected error";
}
if (toastAllowed && ctx != null) { if (toastAllowed && ctx != null) {
showToast(ctx, error); showToast(ctx, MessageFormat.format(ctx.getResources().getString(R.string.shared_string_action_template)
+ ": " + ctx.getResources().getString(R.string.shared_string_unexpected_error), userOperation));
} }
} catch (IOException e) { } catch (IOException e) {
if (ctx != null) {
error = MessageFormat.format(ctx.getResources().getString(R.string.shared_string_action_template)
+ ": " + ctx.getResources().getString(R.string.shared_string_io_error), userOperation);
} else {
error = "Action " + userOperation + ": I/O error";
}
if (toastAllowed && ctx != null) { if (toastAllowed && ctx != null) {
showToast(ctx, error); showToast(ctx, MessageFormat.format(ctx.getResources().getString(R.string.shared_string_action_template)
+ ": " + ctx.getResources().getString(R.string.shared_string_io_error), userOperation));
} }
} finally { } finally {
if (connection != null) { if (connection != null) {
connection.disconnect(); connection.disconnect();
} }
} }
if (listener != null) {
listener.onResult(result, error);
}
return null; return null;
} }
@ -443,16 +374,12 @@ public class AndroidNetworkUtils {
public static String downloadFile(@NonNull String url, @NonNull File fileToSave, boolean gzip, @Nullable IProgress progress) { public static String downloadFile(@NonNull String url, @NonNull File fileToSave, boolean gzip, @Nullable IProgress progress) {
String error = null; String error = null;
try { try {
HttpURLConnection connection = NetworkUtils.getHttpURLConnection(url); URLConnection connection = NetworkUtils.getHttpURLConnection(url);
connection.setConnectTimeout(CONNECTION_TIMEOUT); connection.setConnectTimeout(CONNECTION_TIMEOUT);
connection.setReadTimeout(CONNECTION_TIMEOUT); connection.setReadTimeout(CONNECTION_TIMEOUT);
if (gzip) { if (gzip) {
connection.setRequestProperty("Accept-Encoding", "deflate, gzip"); connection.setRequestProperty("Accept-Encoding", "deflate, gzip");
} }
connection.connect();
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
return streamToString(connection.getErrorStream());
} else {
InputStream inputStream = gzip InputStream inputStream = gzip
? new GZIPInputStream(connection.getInputStream()) ? new GZIPInputStream(connection.getInputStream())
: new BufferedInputStream(connection.getInputStream(), 8 * 1024); : new BufferedInputStream(connection.getInputStream(), 8 * 1024);
@ -466,41 +393,16 @@ public class AndroidNetworkUtils {
Algorithms.closeStream(inputStream); Algorithms.closeStream(inputStream);
Algorithms.closeStream(stream); Algorithms.closeStream(stream);
} }
}
} catch (UnknownHostException e) { } catch (UnknownHostException e) {
error = e.getMessage(); error = e.getMessage();
LOG.error("UnknownHostException, cannot download file " + url + " " + error); LOG.error("UnknownHostException, cannot download file " + url + " " + error);
} catch (Exception e) { } catch (Exception e) {
error = e.getMessage(); error = e.getMessage();
LOG.warn("Cannot download file: " + url, e); LOG.warn("Cannot download file : " + url, e);
} }
return error; return error;
} }
private static String streamToString(InputStream inputStream) throws IOException {
StringBuilder result = new StringBuilder();
if (inputStream != null) {
BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"), 256);
String buffer;
boolean f = true;
while ((buffer = in.readLine()) != null) {
if (!f) {
result.append("\n");
} else {
f = false;
}
result.append(buffer);
}
try {
in.close();
inputStream.close();
} catch (Exception e) {
// ignore exception
}
}
return result.toString();
}
private static final String BOUNDARY = "CowMooCowMooCowCowCow"; private static final String BOUNDARY = "CowMooCowMooCowCowCow";
public static String uploadFile(@NonNull String urlText, @NonNull File file, boolean gzip, public static String uploadFile(@NonNull String urlText, @NonNull File file, boolean gzip,
@ -515,6 +417,7 @@ public class AndroidNetworkUtils {
@NonNull Map<String, String> additionalParams, @NonNull Map<String, String> additionalParams,
@Nullable Map<String, String> headers, @Nullable Map<String, String> headers,
@Nullable IProgress progress) { @Nullable IProgress progress) {
URL url;
try { try {
boolean firstPrm = !urlText.contains("?"); boolean firstPrm = !urlText.contains("?");
StringBuilder sb = new StringBuilder(urlText); StringBuilder sb = new StringBuilder(urlText);
@ -525,7 +428,7 @@ public class AndroidNetworkUtils {
urlText = sb.toString(); urlText = sb.toString();
LOG.info("Start uploading file to " + urlText + " " + fileName); LOG.info("Start uploading file to " + urlText + " " + fileName);
URL url = new URL(urlText); url = new URL(urlText);
HttpURLConnection conn = (HttpURLConnection) url.openConnection(); HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true); conn.setDoInput(true);
@ -566,10 +469,6 @@ public class AndroidNetworkUtils {
LOG.info("Finish uploading file " + fileName); LOG.info("Finish uploading file " + fileName);
LOG.info("Response code and message : " + conn.getResponseCode() + " " + conn.getResponseMessage()); LOG.info("Response code and message : " + conn.getResponseCode() + " " + conn.getResponseMessage());
if (conn.getResponseCode() != 200) { if (conn.getResponseCode() != 200) {
InputStream errorStream = conn.getErrorStream();
if (errorStream != null) {
return streamToString(errorStream);
}
return conn.getResponseMessage(); return conn.getResponseMessage();
} }
InputStream is = conn.getInputStream(); InputStream is = conn.getInputStream();
@ -604,16 +503,6 @@ public class AndroidNetworkUtils {
final @NonNull Map<String, String> parameters, final @NonNull Map<String, String> parameters,
final @Nullable Map<String, String> headers, final @Nullable Map<String, String> headers,
final OnFilesUploadCallback callback) { final OnFilesUploadCallback callback) {
uploadFilesAsync(url, files, gzip, parameters, headers, callback, AsyncTask.THREAD_POOL_EXECUTOR);
}
public static void uploadFilesAsync(final @NonNull String url,
final @NonNull List<File> files,
final boolean gzip,
final @NonNull Map<String, String> parameters,
final @Nullable Map<String, String> headers,
final OnFilesUploadCallback callback,
final Executor executor) {
new AsyncTask<Void, Object, Map<File, String>>() { new AsyncTask<Void, Object, Map<File, String>>() {
@ -649,7 +538,7 @@ public class AndroidNetworkUtils {
} catch (Exception e) { } catch (Exception e) {
errors.put(file, e.getMessage()); errors.put(file, e.getMessage());
} }
publishProgress(file, -1); publishProgress(file, Integer.MAX_VALUE);
} }
return errors; return errors;
} }
@ -657,13 +546,7 @@ public class AndroidNetworkUtils {
@Override @Override
protected void onProgressUpdate(Object... objects) { protected void onProgressUpdate(Object... objects) {
if (callback != null) { if (callback != null) {
File file = (File) objects[0]; callback.onFileUploadProgress((File) objects[0], (Integer) objects[1]);
Integer progress = (Integer) objects[1];
if (progress >= 0) {
callback.onFileUploadProgress(file, progress);
} else {
callback.onFileUploadDone(file);
}
} }
} }
@ -674,7 +557,7 @@ public class AndroidNetworkUtils {
} }
} }
}.executeOnExecutor(executor, (Void) null); }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);
} }
private static void showToast(OsmandApplication ctx, String message) { private static void showToast(OsmandApplication ctx, String message) {
@ -682,11 +565,11 @@ public class AndroidNetworkUtils {
} }
public static class Request { public static class Request {
private final String url; private String url;
private final Map<String, String> parameters; private Map<String, String> parameters;
private final String userOperation; private String userOperation;
private final boolean toastAllowed; private boolean toastAllowed;
private final boolean post; private boolean post;
public Request(String url, Map<String, String> parameters, String userOperation, boolean toastAllowed, boolean post) { public Request(String url, Map<String, String> parameters, String userOperation, boolean toastAllowed, boolean post) {
this.url = url; this.url = url;

View file

@ -40,6 +40,7 @@ import net.osmand.plus.helpers.DayNightHelper;
import net.osmand.plus.helpers.LockHelper; import net.osmand.plus.helpers.LockHelper;
import net.osmand.plus.helpers.WaypointHelper; import net.osmand.plus.helpers.WaypointHelper;
import net.osmand.plus.inapp.InAppPurchaseHelperImpl; import net.osmand.plus.inapp.InAppPurchaseHelperImpl;
import net.osmand.plus.itinerary.ItineraryHelper;
import net.osmand.plus.liveupdates.LiveUpdatesHelper; import net.osmand.plus.liveupdates.LiveUpdatesHelper;
import net.osmand.plus.mapmarkers.MapMarkersDbHelper; import net.osmand.plus.mapmarkers.MapMarkersDbHelper;
import net.osmand.plus.mapmarkers.MapMarkersHelper; import net.osmand.plus.mapmarkers.MapMarkersHelper;
@ -472,6 +473,7 @@ public class AppInitializer implements IProgress {
app.osmOAuthHelper = startupInit(new OsmOAuthHelper(app), OsmOAuthHelper.class); app.osmOAuthHelper = startupInit(new OsmOAuthHelper(app), OsmOAuthHelper.class);
app.oprAuthHelper = startupInit(new OprAuthHelper(app), OprAuthHelper.class); app.oprAuthHelper = startupInit(new OprAuthHelper(app), OprAuthHelper.class);
app.onlineRoutingHelper = startupInit(new OnlineRoutingHelper(app), OnlineRoutingHelper.class); app.onlineRoutingHelper = startupInit(new OnlineRoutingHelper(app), OnlineRoutingHelper.class);
app.itineraryHelper = startupInit(new ItineraryHelper(app), ItineraryHelper.class);
app.backupHelper = startupInit(new BackupHelper(app), BackupHelper.class); app.backupHelper = startupInit(new BackupHelper(app), BackupHelper.class);
initOpeningHoursParser(); initOpeningHoursParser();
@ -685,7 +687,7 @@ public class AppInitializer implements IProgress {
// restore backuped favorites to normal file // restore backuped favorites to normal file
restoreBackupForFavoritesFiles(); restoreBackupForFavoritesFiles();
notifyEvent(InitEvents.RESTORE_BACKUPS); notifyEvent(InitEvents.RESTORE_BACKUPS);
app.mapMarkersHelper.syncAllGroupsAsync(); app.itineraryHelper.syncAllGroupsAsync();
app.searchUICore.initSearchUICore(); app.searchUICore.initSearchUICore();
checkLiveUpdatesAlerts(); checkLiveUpdatesAlerts();

View file

@ -445,9 +445,6 @@ public class ContextMenuAdapter {
ImageView imageView = (ImageView) convertView.findViewById(R.id.secondary_icon); ImageView imageView = (ImageView) convertView.findViewById(R.id.secondary_icon);
imageView.setImageDrawable(drawable); imageView.setImageDrawable(drawable);
imageView.setVisibility(View.VISIBLE); imageView.setVisibility(View.VISIBLE);
if (secondaryDrawable == R.drawable.ic_action_additional_option) {
UiUtilities.rotateImageByLayoutDirection(imageView);
}
} else { } else {
ImageView imageView = (ImageView) convertView.findViewById(R.id.secondary_icon); ImageView imageView = (ImageView) convertView.findViewById(R.id.secondary_icon);
if (imageView != null) { if (imageView != null) {

View file

@ -225,7 +225,7 @@ public class CustomRegion extends WorldRegion {
&& app.getSettings().isInternetConnectionAvailable()) { && app.getSettings().isInternetConnectionAvailable()) {
OnRequestResultListener resultListener = new OnRequestResultListener() { OnRequestResultListener resultListener = new OnRequestResultListener() {
@Override @Override
public void onResult(@Nullable String result, @Nullable String error) { public void onResult(String result) {
if (!Algorithms.isEmpty(result)) { if (!Algorithms.isEmpty(result)) {
if ("json".equalsIgnoreCase(dynamicDownloadItems.format)) { if ("json".equalsIgnoreCase(dynamicDownloadItems.format)) {
dynamicItemsJson = mapJsonItems(result); dynamicItemsJson = mapJsonItems(result);

View file

@ -17,7 +17,7 @@ import net.osmand.data.FavouritePoint;
import net.osmand.data.LatLon; import net.osmand.data.LatLon;
import net.osmand.plus.GeocodingLookupService.AddressLookupRequest; import net.osmand.plus.GeocodingLookupService.AddressLookupRequest;
import net.osmand.plus.mapmarkers.MapMarkersHelper; import net.osmand.plus.mapmarkers.MapMarkersHelper;
import net.osmand.plus.mapmarkers.MapMarkersGroup; import net.osmand.plus.itinerary.ItineraryGroup;
import net.osmand.plus.api.SQLiteAPI.SQLiteConnection; import net.osmand.plus.api.SQLiteAPI.SQLiteConnection;
import net.osmand.plus.api.SQLiteAPI.SQLiteCursor; import net.osmand.plus.api.SQLiteAPI.SQLiteCursor;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
@ -280,16 +280,15 @@ public class FavouritesDbHelper {
} }
private void runSyncWithMarkers(FavoriteGroup favGroup) { private void runSyncWithMarkers(FavoriteGroup favGroup) {
MapMarkersHelper helper = context.getMapMarkersHelper(); ItineraryGroup group = context.getItineraryHelper().getMarkersGroup(favGroup);
MapMarkersGroup group = helper.getMarkersGroup(favGroup);
if (group != null) { if (group != null) {
helper.runSynchronization(group); context.getItineraryHelper().runSynchronization(group);
} }
} }
private boolean removeFromMarkers(FavoriteGroup favGroup) { private boolean removeFromMarkers(FavoriteGroup favGroup) {
MapMarkersHelper helper = context.getMapMarkersHelper(); MapMarkersHelper helper = context.getMapMarkersHelper();
MapMarkersGroup group = helper.getMarkersGroup(favGroup); ItineraryGroup group = context.getItineraryHelper().getMarkersGroup(favGroup);
if (group != null) { if (group != null) {
helper.removeMarkersGroup(group); helper.removeMarkersGroup(group);
return true; return true;
@ -298,8 +297,7 @@ public class FavouritesDbHelper {
} }
private void addToMarkers(FavoriteGroup favGroup) { private void addToMarkers(FavoriteGroup favGroup) {
MapMarkersHelper helper = context.getMapMarkersHelper(); context.getItineraryHelper().addOrEnableGroup(favGroup);
helper.addOrEnableGroup(favGroup);
} }
private File getInternalFile() { private File getInternalFile() {

View file

@ -30,8 +30,7 @@ import net.osmand.plus.helpers.GpxUiHelper.GPXDataSetType;
import net.osmand.plus.helpers.GpxUiHelper.GPXInfo; import net.osmand.plus.helpers.GpxUiHelper.GPXInfo;
import net.osmand.plus.helpers.SearchHistoryHelper; import net.osmand.plus.helpers.SearchHistoryHelper;
import net.osmand.plus.helpers.enums.MetricsConstants; import net.osmand.plus.helpers.enums.MetricsConstants;
import net.osmand.plus.mapmarkers.MapMarkersGroup; import net.osmand.plus.itinerary.ItineraryGroup;
import net.osmand.plus.mapmarkers.MapMarkersHelper;
import net.osmand.plus.routing.GPXRouteParams.GPXRouteParamsBuilder; import net.osmand.plus.routing.GPXRouteParams.GPXRouteParamsBuilder;
import net.osmand.plus.track.GpxSplitType; import net.osmand.plus.track.GpxSplitType;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
@ -798,7 +797,7 @@ public class GpxSelectionHelper {
boolean addToHistory) { boolean addToHistory) {
GpxDataItem dataItem = app.getGpxDbHelper().getItem(new File(gpx.path)); GpxDataItem dataItem = app.getGpxDbHelper().getItem(new File(gpx.path));
if (canAddToMarkers && show && dataItem != null && dataItem.isShowAsMarkers()) { if (canAddToMarkers && show && dataItem != null && dataItem.isShowAsMarkers()) {
app.getMapMarkersHelper().addOrEnableGroup(gpx); app.getItineraryHelper().addOrEnableGroup(gpx);
} }
return selectGpxFile(gpx, dataItem, show, notShowNavigationDialog, syncGroup, selectedByUser, addToHistory); return selectGpxFile(gpx, dataItem, show, notShowNavigationDialog, syncGroup, selectedByUser, addToHistory);
} }
@ -825,10 +824,9 @@ public class GpxSelectionHelper {
} }
private void syncGpxWithMarkers(GPXFile gpxFile) { private void syncGpxWithMarkers(GPXFile gpxFile) {
MapMarkersHelper mapMarkersHelper = app.getMapMarkersHelper(); ItineraryGroup group = app.getItineraryHelper().getMarkersGroup(gpxFile);
MapMarkersGroup group = mapMarkersHelper.getMarkersGroup(gpxFile);
if (group != null) { if (group != null) {
mapMarkersHelper.runSynchronization(group); app.getItineraryHelper().runSynchronization(group);
} }
} }

View file

@ -67,6 +67,7 @@ import net.osmand.plus.helpers.WaypointHelper;
import net.osmand.plus.helpers.enums.DrivingRegion; import net.osmand.plus.helpers.enums.DrivingRegion;
import net.osmand.plus.helpers.enums.MetricsConstants; import net.osmand.plus.helpers.enums.MetricsConstants;
import net.osmand.plus.inapp.InAppPurchaseHelper; import net.osmand.plus.inapp.InAppPurchaseHelper;
import net.osmand.plus.itinerary.ItineraryHelper;
import net.osmand.plus.mapmarkers.MapMarkersDbHelper; import net.osmand.plus.mapmarkers.MapMarkersDbHelper;
import net.osmand.plus.mapmarkers.MapMarkersHelper; import net.osmand.plus.mapmarkers.MapMarkersHelper;
import net.osmand.plus.measurementtool.MeasurementEditingContext; import net.osmand.plus.measurementtool.MeasurementEditingContext;
@ -168,6 +169,7 @@ public class OsmandApplication extends MultiDexApplication {
OprAuthHelper oprAuthHelper; OprAuthHelper oprAuthHelper;
MeasurementEditingContext measurementEditingContext; MeasurementEditingContext measurementEditingContext;
OnlineRoutingHelper onlineRoutingHelper; OnlineRoutingHelper onlineRoutingHelper;
ItineraryHelper itineraryHelper;
BackupHelper backupHelper; BackupHelper backupHelper;
private Map<String, Builder> customRoutingConfigs = new ConcurrentHashMap<>(); private Map<String, Builder> customRoutingConfigs = new ConcurrentHashMap<>();
@ -470,6 +472,10 @@ public class OsmandApplication extends MultiDexApplication {
return onlineRoutingHelper; return onlineRoutingHelper;
} }
public ItineraryHelper getItineraryHelper() {
return itineraryHelper;
}
public BackupHelper getBackupHelper() { public BackupHelper getBackupHelper() {
return backupHelper; return backupHelper;
} }

View file

@ -28,7 +28,7 @@ import net.osmand.AndroidUtils;
import net.osmand.plus.FavouritesDbHelper; import net.osmand.plus.FavouritesDbHelper;
import net.osmand.plus.FavouritesDbHelper.FavoriteGroup; import net.osmand.plus.FavouritesDbHelper.FavoriteGroup;
import net.osmand.plus.mapmarkers.MapMarkersHelper; import net.osmand.plus.mapmarkers.MapMarkersHelper;
import net.osmand.plus.mapmarkers.MapMarkersGroup; import net.osmand.plus.itinerary.ItineraryGroup;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.UiUtilities; import net.osmand.plus.UiUtilities;
@ -179,7 +179,7 @@ public class EditFavoriteGroupDialogFragment extends MenuBottomSheetDialogFragme
final MapMarkersHelper markersHelper = app.getMapMarkersHelper(); final MapMarkersHelper markersHelper = app.getMapMarkersHelper();
final FavoriteGroup favGroup = this.group; final FavoriteGroup favGroup = this.group;
final MapMarkersGroup markersGr = markersHelper.getMarkersGroup(this.group); final ItineraryGroup markersGr = app.getItineraryHelper().getMarkersGroup(this.group);
final boolean synced = markersGr != null; final boolean synced = markersGr != null;
BaseBottomSheetItem markersGroupItem = new SimpleBottomSheetItem.Builder() BaseBottomSheetItem markersGroupItem = new SimpleBottomSheetItem.Builder()
@ -192,7 +192,7 @@ public class EditFavoriteGroupDialogFragment extends MenuBottomSheetDialogFragme
if (synced) { if (synced) {
markersHelper.removeMarkersGroup(markersGr); markersHelper.removeMarkersGroup(markersGr);
} else { } else {
markersHelper.addOrEnableGroup(favGroup); app.getItineraryHelper().addOrEnableGroup(favGroup);
} }
dismiss(); dismiss();
MapActivity.launchMapActivityMoveToTop(getActivity()); MapActivity.launchMapActivityMoveToTop(getActivity());

View file

@ -526,7 +526,7 @@ public class FavoritesTreeFragment extends OsmandExpandableListFragment implemen
for (Map.Entry<String, Set<FavouritePoint>> entry : favoritesSelected.entrySet()) { for (Map.Entry<String, Set<FavouritePoint>> entry : favoritesSelected.entrySet()) {
FavoriteGroup group = helper.getGroup(entry.getKey()); FavoriteGroup group = helper.getGroup(entry.getKey());
if (group != null && entry.getValue().size() == group.getPoints().size()) { if (group != null && entry.getValue().size() == group.getPoints().size()) {
markersHelper.addOrEnableGroup(group); getMyApplication().getItineraryHelper().addOrEnableGroup(group);
} else { } else {
for (FavouritePoint fp : entry.getValue()) { for (FavouritePoint fp : entry.getValue()) {
points.add(new LatLon(fp.getLatitude(), fp.getLongitude())); points.add(new LatLon(fp.getLatitude(), fp.getLongitude()));

View file

@ -37,10 +37,6 @@ import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class BackupHelper { public class BackupHelper {
@ -49,9 +45,6 @@ public class BackupHelper {
private final FavouritesDbHelper favouritesHelper; private final FavouritesDbHelper favouritesHelper;
private final GpxDbHelper gpxHelper; private final GpxDbHelper gpxHelper;
private static final ThreadPoolExecutor EXECUTOR = new ThreadPoolExecutor(1, 1, 0L,
TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
private static final String SERVER_URL = "https://osmand.net"; private static final String SERVER_URL = "https://osmand.net";
private static final String USER_REGISTER_URL = SERVER_URL + "/userdata/user-register"; private static final String USER_REGISTER_URL = SERVER_URL + "/userdata/user-register";
@ -66,6 +59,10 @@ public class BackupHelper {
public final static int STATUS_EMPTY_RESPONSE_ERROR = 2; public final static int STATUS_EMPTY_RESPONSE_ERROR = 2;
public final static int STATUS_SERVER_ERROR = 3; public final static int STATUS_SERVER_ERROR = 3;
public interface OnResultListener {
void onResult(int status, @Nullable String message, @Nullable JSONObject json);
}
public interface OnRegisterUserListener { public interface OnRegisterUserListener {
void onRegisterUser(int status, @Nullable String message); void onRegisterUser(int status, @Nullable String message);
} }
@ -80,6 +77,7 @@ public class BackupHelper {
public interface OnCollectLocalFilesListener { public interface OnCollectLocalFilesListener {
void onFileCollected(@NonNull GpxFileInfo fileInfo); void onFileCollected(@NonNull GpxFileInfo fileInfo);
void onFilesCollected(@NonNull List<GpxFileInfo> fileInfos); void onFilesCollected(@NonNull List<GpxFileInfo> fileInfos);
} }
@ -89,21 +87,20 @@ public class BackupHelper {
public interface OnUploadFilesListener { public interface OnUploadFilesListener {
void onFileUploadProgress(@NonNull File file, int progress); void onFileUploadProgress(@NonNull File file, int progress);
void onFileUploadDone(@NonNull File file);
void onFilesUploadDone(@NonNull Map<File, String> errors); void onFilesUploadDone(@NonNull Map<File, String> errors);
} }
public interface OnDeleteFilesListener { public interface OnDeleteFilesListener {
void onFileDeleteProgress(@NonNull UserFile file); void onFileDeleteProgress(@NonNull UserFile file);
void onFilesDeleteDone(@NonNull Map<UserFile, String> errors); void onFilesDeleteDone(@NonNull Map<UserFile, String> errors);
} }
public interface OnDownloadFileListener { public interface OnDownloadFileListener {
void onFileDownloadProgress(@NonNull UserFile userFile, int progress); void onFileDownloadProgress(@NonNull UserFile userFile, int progress);
@WorkerThread @WorkerThread
void onFileDownloadedAsync(@NonNull File file); void onFileDownloadedAsync(@NonNull File file);
void onFileDownloaded(@NonNull File file);
void onFilesDownloadDone(@NonNull Map<File, String> errors); void onFilesDownloadDone(@NonNull Map<File, String> errors);
} }
@ -134,6 +131,10 @@ public class BackupHelper {
return token.matches("[0-9]+"); return token.matches("[0-9]+");
} }
public boolean hasOsmLiveUpdates() {
return InAppPurchaseHelper.isSubscribedToLiveUpdates(app);
}
@Nullable @Nullable
public String getOrderId() { public String getOrderId() {
InAppPurchaseHelper purchaseHelper = app.getInAppPurchaseHelper(); InAppPurchaseHelper purchaseHelper = app.getInAppPurchaseHelper();
@ -166,27 +167,22 @@ public class BackupHelper {
public void registerUser(@NonNull String email, @Nullable final OnRegisterUserListener listener) { public void registerUser(@NonNull String email, @Nullable final OnRegisterUserListener listener) {
Map<String, String> params = new HashMap<>(); Map<String, String> params = new HashMap<>();
params.put("email", email); params.put("email", email);
String orderId = getOrderId(); params.put("orderid", getOrderId());
if (!Algorithms.isEmpty(orderId)) {
params.put("orderid", orderId);
}
params.put("deviceid", app.getUserAndroidId()); params.put("deviceid", app.getUserAndroidId());
AndroidNetworkUtils.sendRequestAsync(app, USER_REGISTER_URL, params, "Register user", false, true, new OnRequestResultListener() { AndroidNetworkUtils.sendRequestAsync(app, USER_REGISTER_URL, params, "Register user", true, true, new OnRequestResultListener() {
@Override @Override
public void onResult(@Nullable String resultJson, @Nullable String error) { public void onResult(String resultJson) {
int status; int status;
String message; String message;
if (!Algorithms.isEmpty(error)) { if (!Algorithms.isEmpty(resultJson)) {
message = "User registration error: " + parseServerError(error);
status = STATUS_SERVER_ERROR;
} else if (!Algorithms.isEmpty(resultJson)) {
try { try {
JSONObject result = new JSONObject(resultJson); JSONObject result = new JSONObject(resultJson);
if (result.has("status") && "ok".equals(result.getString("status"))) { String statusStr = result.getString("status");
if (statusStr.equals("ok")) {
message = "You have been registered successfully. Please check for email with activation code."; message = "You have been registered successfully. Please check for email with activation code.";
status = STATUS_SUCCESS; status = STATUS_SUCCESS;
} else { } else {
message = "User registration error: unknown"; message = "User registration error: " + statusStr;
status = STATUS_SERVER_ERROR; status = STATUS_SERVER_ERROR;
} }
} catch (JSONException e) { } catch (JSONException e) {
@ -201,7 +197,7 @@ public class BackupHelper {
listener.onRegisterUser(status, message); listener.onRegisterUser(status, message);
} }
} }
}, EXECUTOR); });
} }
public void registerDevice(String token, @Nullable final OnRegisterDeviceListener listener) { public void registerDevice(String token, @Nullable final OnRegisterDeviceListener listener) {
@ -216,15 +212,12 @@ public class BackupHelper {
params.put("deviceid", androidId); params.put("deviceid", androidId);
} }
params.put("token", token); params.put("token", token);
AndroidNetworkUtils.sendRequestAsync(app, DEVICE_REGISTER_URL, params, "Register device", false, true, new OnRequestResultListener() { AndroidNetworkUtils.sendRequestAsync(app, DEVICE_REGISTER_URL, params, "Register device", true, true, new OnRequestResultListener() {
@Override @Override
public void onResult(@Nullable String resultJson, @Nullable String error) { public void onResult(String resultJson) {
int status; int status;
String message; String message;
if (!Algorithms.isEmpty(error)) { if (!Algorithms.isEmpty(resultJson)) {
message = "Device registration error: " + parseServerError(error);
status = STATUS_SERVER_ERROR;
} else if (!Algorithms.isEmpty(resultJson)) {
try { try {
JSONObject result = new JSONObject(resultJson); JSONObject result = new JSONObject(resultJson);
settings.BACKUP_DEVICE_ID.set(result.getString("id")); settings.BACKUP_DEVICE_ID.set(result.getString("id"));
@ -232,9 +225,8 @@ public class BackupHelper {
settings.BACKUP_NATIVE_DEVICE_ID.set(result.getString("deviceid")); settings.BACKUP_NATIVE_DEVICE_ID.set(result.getString("deviceid"));
settings.BACKUP_ACCESS_TOKEN.set(result.getString("accesstoken")); settings.BACKUP_ACCESS_TOKEN.set(result.getString("accesstoken"));
settings.BACKUP_ACCESS_TOKEN_UPDATE_TIME.set(result.getString("udpatetime")); settings.BACKUP_ACCESS_TOKEN_UPDATE_TIME.set(result.getString("udpatetime"));
message = "Device have been registered successfully";
status = STATUS_SUCCESS; status = STATUS_SUCCESS;
message = "Device have been registered successfully";
} catch (JSONException e) { } catch (JSONException e) {
message = "Device registration error: json parsing"; message = "Device registration error: json parsing";
status = STATUS_PARSE_JSON_ERROR; status = STATUS_PARSE_JSON_ERROR;
@ -247,7 +239,7 @@ public class BackupHelper {
listener.onRegisterDevice(status, message); listener.onRegisterDevice(status, message);
} }
} }
}, EXECUTOR); });
} }
public void uploadFiles(@NonNull List<GpxFileInfo> gpxFiles, @Nullable final OnUploadFilesListener listener) throws UserNotRegisteredException { public void uploadFiles(@NonNull List<GpxFileInfo> gpxFiles, @Nullable final OnUploadFilesListener listener) throws UserNotRegisteredException {
@ -274,6 +266,14 @@ public class BackupHelper {
additionaParams.put("name", gpxFileInfo.getFileName(true)); additionaParams.put("name", gpxFileInfo.getFileName(true));
additionaParams.put("type", Algorithms.getFileExtension(file)); additionaParams.put("type", Algorithms.getFileExtension(file));
gpxFileInfo.uploadTime = System.currentTimeMillis(); gpxFileInfo.uploadTime = System.currentTimeMillis();
if (file.equals(favoritesFile)) {
favouritesHelper.setLastUploadedTime(gpxFileInfo.uploadTime);
} else {
GpxDataItem gpxItem = gpxHelper.getItem(file);
if (gpxItem != null) {
gpxHelper.updateLastUploadedTime(gpxItem, gpxFileInfo.uploadTime);
}
}
additionaParams.put("clienttime", String.valueOf(gpxFileInfo.uploadTime)); additionaParams.put("clienttime", String.valueOf(gpxFileInfo.uploadTime));
} }
return additionaParams; return additionaParams;
@ -286,34 +286,16 @@ public class BackupHelper {
} }
} }
@Override
public void onFileUploadDone(@NonNull File file) {
if (listener != null) {
GpxFileInfo gpxFileInfo = gpxInfos.get(file);
if (gpxFileInfo != null) {
if (file.equals(favoritesFile)) {
favouritesHelper.setLastUploadedTime(gpxFileInfo.uploadTime);
} else {
GpxDataItem gpxItem = gpxHelper.getItem(file);
if (gpxItem != null) {
gpxHelper.updateLastUploadedTime(gpxItem, gpxFileInfo.uploadTime);
}
}
}
listener.onFileUploadDone(file);
}
}
@Override @Override
public void onFilesUploadDone(@NonNull Map<File, String> errors) { public void onFilesUploadDone(@NonNull Map<File, String> errors) {
if (errors.isEmpty()) { if (errors.isEmpty()) {
settings.BACKUP_LAST_UPLOADED_TIME.set(System.currentTimeMillis() + 1); settings.BACKUP_LAST_UPLOADED_TIME.set(System.currentTimeMillis() + 1);
} }
if (listener != null) { if (listener != null) {
listener.onFilesUploadDone(resolveServerErrors(errors)); listener.onFilesUploadDone(errors);
} }
} }
}, EXECUTOR); });
} }
public void deleteFiles(@NonNull List<UserFile> userFiles, @Nullable final OnDeleteFilesListener listener) throws UserNotRegisteredException { public void deleteFiles(@NonNull List<UserFile> userFiles, @Nullable final OnDeleteFilesListener listener) throws UserNotRegisteredException {
@ -351,36 +333,24 @@ public class BackupHelper {
for (RequestResponse response : results) { for (RequestResponse response : results) {
UserFile userFile = filesMap.get(response.getRequest()); UserFile userFile = filesMap.get(response.getRequest());
if (userFile != null) { if (userFile != null) {
boolean success;
String message = null;
String errorStr = response.getError();
if (!Algorithms.isEmpty(errorStr)) {
message = parseServerError(errorStr);
success = false;
} else {
String responseStr = response.getResponse(); String responseStr = response.getResponse();
boolean success;
try { try {
JSONObject result = new JSONObject(responseStr); JSONObject json = new JSONObject(responseStr);
if (result.has("status") && "ok".equals(result.getString("status"))) { String status = json.getString("status");
success = true; success = status.equalsIgnoreCase("ok");
} else {
message = "Unknown error";
success = false;
}
} catch (JSONException e) { } catch (JSONException e) {
message = "Json parsing error";
success = false; success = false;
} }
}
if (!success) { if (!success) {
errors.put(userFile, message); errors.put(userFile, responseStr);
} }
} }
} }
listener.onFilesDeleteDone(errors); listener.onFilesDeleteDone(errors);
} }
} }
}, EXECUTOR); });
} }
public void downloadFileList(@Nullable final OnDownloadFileListListener listener) throws UserNotRegisteredException { public void downloadFileList(@Nullable final OnDownloadFileListListener listener) throws UserNotRegisteredException {
@ -389,16 +359,13 @@ public class BackupHelper {
Map<String, String> params = new HashMap<>(); Map<String, String> params = new HashMap<>();
params.put("deviceid", getDeviceId()); params.put("deviceid", getDeviceId());
params.put("accessToken", getAccessToken()); params.put("accessToken", getAccessToken());
AndroidNetworkUtils.sendRequestAsync(app, LIST_FILES_URL, params, "Download file list", false, false, new OnRequestResultListener() { AndroidNetworkUtils.sendRequestAsync(app, LIST_FILES_URL, params, "Download file list", true, false, new OnRequestResultListener() {
@Override @Override
public void onResult(@Nullable String resultJson, @Nullable String error) { public void onResult(String resultJson) {
int status; int status;
String message; String message;
List<UserFile> userFiles = new ArrayList<>(); List<UserFile> userFiles = new ArrayList<>();
if (!Algorithms.isEmpty(error)) { if (!Algorithms.isEmpty(resultJson)) {
status = STATUS_SERVER_ERROR;
message = "Download file list error: " + parseServerError(error);
} else if (!Algorithms.isEmpty(resultJson)) {
try { try {
JSONObject result = new JSONObject(resultJson); JSONObject result = new JSONObject(resultJson);
String totalZipSize = result.getString("totalZipSize"); String totalZipSize = result.getString("totalZipSize");
@ -425,7 +392,7 @@ public class BackupHelper {
listener.onDownloadFileList(status, message, userFiles); listener.onDownloadFileList(status, message, userFiles);
} }
} }
}, EXECUTOR); });
} }
public void downloadFiles(@NonNull final Map<File, UserFile> filesMap, @Nullable final OnDownloadFileListener listener) throws UserNotRegisteredException { public void downloadFiles(@NonNull final Map<File, UserFile> filesMap, @Nullable final OnDownloadFileListener listener) throws UserNotRegisteredException {
@ -453,13 +420,6 @@ public class BackupHelper {
} }
} }
@Override
public void onFileDownloadDone(@NonNull File file) {
if (listener != null) {
listener.onFileDownloaded(file);
}
}
@Override @Override
public void onFileDownloadedAsync(@NonNull File file) { public void onFileDownloadedAsync(@NonNull File file) {
if (listener != null) { if (listener != null) {
@ -470,10 +430,10 @@ public class BackupHelper {
@Override @Override
public void onFilesDownloadDone(@NonNull Map<File, String> errors) { public void onFilesDownloadDone(@NonNull Map<File, String> errors) {
if (listener != null) { if (listener != null) {
listener.onFilesDownloadDone(resolveServerErrors(errors)); listener.onFilesDownloadDone(errors);
} }
} }
}, EXECUTOR); });
} }
@SuppressLint("StaticFieldLeak") @SuppressLint("StaticFieldLeak")
@ -555,37 +515,7 @@ public class BackupHelper {
} }
} }
}; };
task.executeOnExecutor(EXECUTOR); task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
private Map<File, String> resolveServerErrors(@NonNull Map<File, String> errors) {
Map<File, String> resolvedErrors = new HashMap<>();
for (Entry<File, String> fileError : errors.entrySet()) {
File file = fileError.getKey();
String errorStr = fileError.getValue();
try {
JSONObject errorJson = new JSONObject(errorStr);
JSONObject error = errorJson.getJSONObject("error");
errorStr = "Error " + error.getInt("errorCode") + " (" + error.getString("message") + ")";
} catch (JSONException e) {
// ignore
}
resolvedErrors.put(file, errorStr);
}
return resolvedErrors;
}
private String parseServerError(@NonNull String error) {
try {
JSONObject resultError = new JSONObject(error);
if (resultError.has("error")) {
JSONObject errorObj = resultError.getJSONObject("error");
return errorObj.getInt("errorCode") + " (" + errorObj.getString("message") + ")";
}
} catch (JSONException e) {
// ignore
}
return error;
} }
@SuppressLint("StaticFieldLeak") @SuppressLint("StaticFieldLeak")
@ -646,6 +576,6 @@ public class BackupHelper {
} }
} }
}; };
task.executeOnExecutor(EXECUTOR); task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} }
} }

View file

@ -11,6 +11,7 @@ import net.osmand.AndroidUtils;
import net.osmand.GPXUtilities; import net.osmand.GPXUtilities;
import net.osmand.GPXUtilities.GPXFile; import net.osmand.GPXUtilities.GPXFile;
import net.osmand.plus.GPXDatabase.GpxDataItem; import net.osmand.plus.GPXDatabase.GpxDataItem;
import net.osmand.plus.GpxDbHelper;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.ProgressImplementation; import net.osmand.plus.ProgressImplementation;
import net.osmand.plus.backup.BackupHelper.BackupInfo; import net.osmand.plus.backup.BackupHelper.BackupInfo;
@ -112,7 +113,7 @@ public class BackupTask {
tasks.push(backupTasks[i]); tasks.push(backupTasks[i]);
} }
this.runningTasks = tasks; this.runningTasks = tasks;
onBackupTasksInit(); onTasksInit();
} }
private void initRestoreTasks() { private void initRestoreTasks() {
@ -122,7 +123,7 @@ public class BackupTask {
tasks.push(restoreTasks[i]); tasks.push(restoreTasks[i]);
} }
this.runningTasks = tasks; this.runningTasks = tasks;
onRestoreTasksInit(); onTasksInit();
} }
private void initData() { private void initData() {
@ -179,11 +180,6 @@ public class BackupTask {
} }
} }
@Override
public void onFileUploadDone(@NonNull File file) {
onTaskProgressDone();
}
@Override @Override
public void onFilesUploadDone(@NonNull Map<File, String> errors) { public void onFilesUploadDone(@NonNull Map<File, String> errors) {
uploadErrors = errors; uploadErrors = errors;
@ -228,11 +224,6 @@ public class BackupTask {
} }
} }
@Override
public void onFileDownloaded(@NonNull File file) {
onTaskProgressDone();
}
@Override @Override
public void onFileDownloadedAsync(@NonNull File file) { public void onFileDownloadedAsync(@NonNull File file) {
UserFile userFile = filesMap.get(file); UserFile userFile = filesMap.get(file);
@ -284,22 +275,14 @@ public class BackupTask {
} }
} }
private void onBackupTasksInit() { private void onTasksInit() {
Context ctx = contextRef.get(); Context ctx = contextRef.get();
if (ctx instanceof Activity && AndroidUtils.isActivityNotDestroyed((Activity) ctx)) { if (ctx instanceof Activity && AndroidUtils.isActivityNotDestroyed((Activity) ctx) && progress != null) {
progress = ProgressImplementation.createProgressDialog(ctx, progress = ProgressImplementation.createProgressDialog(ctx,
"Backup data", "Initializing...", ProgressDialog.STYLE_HORIZONTAL); "Backup data", "Initializing...", ProgressDialog.STYLE_HORIZONTAL);
} }
} }
private void onRestoreTasksInit() {
Context ctx = contextRef.get();
if (ctx instanceof Activity && AndroidUtils.isActivityNotDestroyed((Activity) ctx)) {
progress = ProgressImplementation.createProgressDialog(ctx,
"Restore data", "Initializing...", ProgressDialog.STYLE_HORIZONTAL);
}
}
private void onTaskProgressUpdate(Object... objects) { private void onTaskProgressUpdate(Object... objects) {
Context ctx = contextRef.get(); Context ctx = contextRef.get();
if (ctx instanceof Activity && AndroidUtils.isActivityNotDestroyed((Activity) ctx) && progress != null) { if (ctx instanceof Activity && AndroidUtils.isActivityNotDestroyed((Activity) ctx) && progress != null) {
@ -309,7 +292,7 @@ public class BackupTask {
progress.startTask((String) objects[0], -1); progress.startTask((String) objects[0], -1);
} else if (objects[0] instanceof Integer) { } else if (objects[0] instanceof Integer) {
int progressValue = (Integer) objects[0]; int progressValue = (Integer) objects[0];
if (progressValue >= 0) { if (progressValue < Integer.MAX_VALUE) {
progress.progress(progressValue); progress.progress(progressValue);
} else { } else {
progress.finishTask(); progress.finishTask();
@ -322,13 +305,6 @@ public class BackupTask {
} }
} }
private void onTaskProgressDone() {
Context ctx = contextRef.get();
if (ctx instanceof Activity && AndroidUtils.isActivityNotDestroyed((Activity) ctx) && progress != null) {
progress.finishTask();
}
}
private void onError(@NonNull String message) { private void onError(@NonNull String message) {
this.error = message; this.error = message;
runningTasks.clear(); runningTasks.clear();

View file

@ -89,6 +89,11 @@ public class TestBackupActivity extends OsmandActionBarActivity {
} }
}); });
if (!backupHelper.hasOsmLiveUpdates()) {
findViewById(R.id.main_view).setVisibility(View.GONE);
return;
}
buttonRegister = findViewById(R.id.btn_register); buttonRegister = findViewById(R.id.btn_register);
UiUtilities.setupDialogButton(nightMode, buttonRegister, DialogButtonType.PRIMARY, "Register"); UiUtilities.setupDialogButton(nightMode, buttonRegister, DialogButtonType.PRIMARY, "Register");
buttonVerify = findViewById(R.id.btn_verify); buttonVerify = findViewById(R.id.btn_verify);
@ -137,7 +142,6 @@ public class TestBackupActivity extends OsmandActionBarActivity {
a.buttonVerify.setVisibility(View.VISIBLE); a.buttonVerify.setVisibility(View.VISIBLE);
a.buttonVerify.setEnabled(status == BackupHelper.STATUS_SUCCESS); a.buttonVerify.setEnabled(status == BackupHelper.STATUS_SUCCESS);
a.tokenEditText.requestFocus(); a.tokenEditText.requestFocus();
a.infoView.setText(message);
} }
} }
}); });
@ -163,11 +167,10 @@ public class TestBackupActivity extends OsmandActionBarActivity {
a.progressBar.setVisibility(View.GONE); a.progressBar.setVisibility(View.GONE);
a.buttonVerify.setEnabled(status != BackupHelper.STATUS_SUCCESS); a.buttonVerify.setEnabled(status != BackupHelper.STATUS_SUCCESS);
if (status == BackupHelper.STATUS_SUCCESS) { if (status == BackupHelper.STATUS_SUCCESS) {
a.tokenEdit.setVisibility(View.GONE); tokenEdit.setVisibility(View.GONE);
a.buttonVerify.setVisibility(View.GONE); buttonVerify.setVisibility(View.GONE);
a.prepareBackup();
} }
a.infoView.setText(message); a.prepareBackup();
} }
} }
}); });
@ -188,41 +191,6 @@ public class TestBackupActivity extends OsmandActionBarActivity {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
if (backupInfo != null) { if (backupInfo != null) {
buttonBackup.setEnabled(false);
BackupTask task = new BackupTask(backupInfo, TestBackupActivity.this, new OnBackupListener() {
@Override
public void onBackupDone(@Nullable Map<File, String> uploadErrors, @Nullable Map<File, String> downloadErrors,
@Nullable Map<UserFile, String> deleteErrors, @Nullable String error) {
TestBackupActivity a = activityRef.get();
if (AndroidUtils.isActivityNotDestroyed(a)) {
String description;
if (error != null) {
description = error;
} else if (uploadErrors == null && deleteErrors == null) {
description = "No data";
} else {
description = getBackupErrorsDescription(uploadErrors, downloadErrors, deleteErrors, error);
}
a.infoView.setText(description);
a.infoView.requestFocus();
a.buttonBackup.setEnabled(true);
if (Algorithms.isEmpty(description)) {
a.prepareBackup();
} else {
a.backupInfo = null;
}
}
}
});
task.runBackup();
}
}
});
buttonRestore.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (backupInfo != null) {
buttonRestore.setEnabled(false);
BackupTask task = new BackupTask(backupInfo, TestBackupActivity.this, new OnBackupListener() { BackupTask task = new BackupTask(backupInfo, TestBackupActivity.this, new OnBackupListener() {
@Override @Override
public void onBackupDone(@Nullable Map<File, String> uploadErrors, @Nullable Map<File, String> downloadErrors, public void onBackupDone(@Nullable Map<File, String> uploadErrors, @Nullable Map<File, String> downloadErrors,
@ -239,13 +207,36 @@ public class TestBackupActivity extends OsmandActionBarActivity {
} }
a.infoView.setText(description); a.infoView.setText(description);
a.infoView.requestFocus(); a.infoView.requestFocus();
a.buttonRestore.setEnabled(true);
if (Algorithms.isEmpty(description)) {
a.prepareBackup(); a.prepareBackup();
} else {
a.backupInfo = null;
} }
} }
});
task.runBackup();
}
}
});
buttonRestore.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (backupInfo != null) {
BackupTask task = new BackupTask(backupInfo, TestBackupActivity.this, new OnBackupListener() {
@Override
public void onBackupDone(@Nullable Map<File, String> uploadErrors, @Nullable Map<File, String> downloadErrors,
@Nullable Map<UserFile, String> deleteErrors, @Nullable String error) {
TestBackupActivity a = activityRef.get();
if (AndroidUtils.isActivityNotDestroyed(a)) {
String description;
if (error != null) {
description = error;
} else if (uploadErrors == null && downloadErrors == null) {
description = "No data";
} else {
description = getBackupErrorsDescription(uploadErrors, downloadErrors, deleteErrors, error);
}
a.infoView.setText(description);
a.infoView.requestFocus();
a.prepareBackup();
}
} }
}); });
task.runRestore(); task.runRestore();
@ -259,21 +250,21 @@ public class TestBackupActivity extends OsmandActionBarActivity {
private String getBackupErrorsDescription(@Nullable Map<File, String> uploadErrors, @Nullable Map<File, String> downloadErrors, @Nullable Map<UserFile, String> deleteErrors, @Nullable String error) { private String getBackupErrorsDescription(@Nullable Map<File, String> uploadErrors, @Nullable Map<File, String> downloadErrors, @Nullable Map<UserFile, String> deleteErrors, @Nullable String error) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
if (!Algorithms.isEmpty(uploadErrors)) { if (!Algorithms.isEmpty(uploadErrors)) {
sb.append("--- Upload errors ---").append("\n\n"); sb.append("--- Upload errors ---").append("\n");
for (Entry<File, String> uploadEntry : uploadErrors.entrySet()) { for (Entry<File, String> uploadEntry : uploadErrors.entrySet()) {
sb.append(uploadEntry.getKey().getName()).append(": ").append(uploadEntry.getValue()).append("\n\n"); sb.append(uploadEntry.getKey().getName()).append(": ").append(uploadEntry.getValue()).append("\n");
} }
} }
if (!Algorithms.isEmpty(downloadErrors)) { if (!Algorithms.isEmpty(downloadErrors)) {
sb.append("--- Download errors ---").append("\n\n"); sb.append("--- Download errors ---").append("\n");
for (Entry<File, String> downloadEntry : downloadErrors.entrySet()) { for (Entry<File, String> downloadEntry : downloadErrors.entrySet()) {
sb.append(downloadEntry.getKey().getName()).append(": ").append(downloadEntry.getValue()).append("\n\n"); sb.append(downloadEntry.getKey().getName()).append(": ").append(downloadEntry.getValue()).append("\n");
} }
} }
if (!Algorithms.isEmpty(deleteErrors)) { if (!Algorithms.isEmpty(deleteErrors)) {
sb.append("--- Delete errors ---").append("\n\n"); sb.append("--- Delete errors ---").append("\n");
for (Entry<UserFile, String> deleteEntry : deleteErrors.entrySet()) { for (Entry<UserFile, String> deleteEntry : deleteErrors.entrySet()) {
sb.append(deleteEntry.getKey().getName()).append(": ").append(deleteEntry.getValue()).append("\n\n"); sb.append(deleteEntry.getKey().getName()).append(": ").append(deleteEntry.getValue()).append("\n");
} }
} }
return sb.length() == 0 ? "OK" : sb.toString(); return sb.length() == 0 ? "OK" : sb.toString();
@ -282,32 +273,32 @@ public class TestBackupActivity extends OsmandActionBarActivity {
private String getBackupDescription(@NonNull BackupInfo backupInfo) { private String getBackupDescription(@NonNull BackupInfo backupInfo) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
if (!Algorithms.isEmpty(backupInfo.filesToUpload)) { if (!Algorithms.isEmpty(backupInfo.filesToUpload)) {
sb.append("\n").append("--- Upload ---").append("\n\n"); sb.append("\n").append("--- Upload ---").append("\n");
for (GpxFileInfo info : backupInfo.filesToUpload) { for (GpxFileInfo info : backupInfo.filesToUpload) {
sb.append(info.getFileName(true)) sb.append(info.getFileName(true))
.append(" L: ").append(DF.format(new Date(info.getFileDate()))) .append(" L: ").append(DF.format(new Date(info.getFileDate())))
.append(" U: ").append(DF.format(new Date(info.uploadTime))) .append(" U: ").append(DF.format(new Date(info.uploadTime)))
.append("\n\n"); .append("\n");
} }
} }
if (!Algorithms.isEmpty(backupInfo.filesToDownload)) { if (!Algorithms.isEmpty(backupInfo.filesToDownload)) {
sb.append("\n").append("--- Download ---").append("\n\n"); sb.append("\n").append("--- Download ---").append("\n");
for (UserFile userFile : backupInfo.filesToDownload) { for (UserFile userFile : backupInfo.filesToDownload) {
sb.append(userFile.getName()) sb.append(userFile.getName())
.append(" R: ").append(DF.format(new Date(userFile.getClienttimems()))) .append(" R: ").append(DF.format(new Date(userFile.getClienttimems())))
.append("\n\n"); .append("\n");
} }
} }
if (!Algorithms.isEmpty(backupInfo.filesToDelete)) { if (!Algorithms.isEmpty(backupInfo.filesToDelete)) {
sb.append("\n").append("--- Delete ---").append("\n\n"); sb.append("\n").append("--- Delete ---").append("\n");
for (UserFile userFile : backupInfo.filesToDelete) { for (UserFile userFile : backupInfo.filesToDelete) {
sb.append(userFile.getName()) sb.append(userFile.getName())
.append(" R: ").append(DF.format(new Date(userFile.getClienttimems()))) .append(" R: ").append(DF.format(new Date(userFile.getClienttimems())))
.append("\n\n"); .append("\n");
} }
} }
if (!Algorithms.isEmpty(backupInfo.filesToMerge)) { if (!Algorithms.isEmpty(backupInfo.filesToMerge)) {
sb.append("\n").append("--- Conflicts ---").append("\n\n"); sb.append("\n").append("--- Conflicts ---").append("\n");
for (Pair<GpxFileInfo, UserFile> localRemote : backupInfo.filesToMerge) { for (Pair<GpxFileInfo, UserFile> localRemote : backupInfo.filesToMerge) {
GpxFileInfo local = localRemote.first; GpxFileInfo local = localRemote.first;
UserFile remote = localRemote.second; UserFile remote = localRemote.second;
@ -315,7 +306,7 @@ public class TestBackupActivity extends OsmandActionBarActivity {
.append(" L: ").append(DF.format(new Date(local.getFileDate()))) .append(" L: ").append(DF.format(new Date(local.getFileDate())))
.append(" U: ").append(DF.format(new Date(local.uploadTime))) .append(" U: ").append(DF.format(new Date(local.uploadTime)))
.append(" R: ").append(DF.format(new Date(remote.getClienttimems()))) .append(" R: ").append(DF.format(new Date(remote.getClienttimems())))
.append("\n\n"); .append("\n");
} }
} }
return sb.toString(); return sb.toString();
@ -323,7 +314,6 @@ public class TestBackupActivity extends OsmandActionBarActivity {
private void prepareBackup() { private void prepareBackup() {
final WeakReference<TestBackupActivity> activityRef = new WeakReference<>(this); final WeakReference<TestBackupActivity> activityRef = new WeakReference<>(this);
buttonRefresh.setEnabled(false);
PrepareBackupTask prepareBackupTask = new PrepareBackupTask(this, new OnPrepareBackupListener() { PrepareBackupTask prepareBackupTask = new PrepareBackupTask(this, new OnPrepareBackupListener() {
@Override @Override
public void onBackupPrepared(@Nullable BackupInfo backupInfo, @Nullable String error) { public void onBackupPrepared(@Nullable BackupInfo backupInfo, @Nullable String error) {
@ -344,7 +334,6 @@ public class TestBackupActivity extends OsmandActionBarActivity {
} }
a.infoView.setText(description); a.infoView.setText(description);
a.infoView.requestFocus(); a.infoView.requestFocus();
a.buttonRefresh.setEnabled(true);
} }
} }
}); });

View file

@ -662,6 +662,14 @@ public class DownloadResources extends DownloadResourceGroup {
return res; return res;
} }
public List<DownloadItem> getDownloadItemsForGroup(String groupId) {
DownloadResourceGroup group = getSubGroupById(groupId);
if (group != null) {
return group.getIndividualDownloadItems();
}
return Collections.emptyList();
}
public static List<IndexItem> findIndexItemsAt(OsmandApplication app, public static List<IndexItem> findIndexItemsAt(OsmandApplication app,
List<String> names, List<String> names,
DownloadActivityType type, DownloadActivityType type,

View file

@ -2125,12 +2125,9 @@ public class GpxUiHelper {
public static GPXFile makeGpxFromRoute(RouteCalculationResult route, OsmandApplication app) { public static GPXFile makeGpxFromRoute(RouteCalculationResult route, OsmandApplication app) {
return makeGpxFromLocations(route.getRouteLocations(), app);
}
public static GPXFile makeGpxFromLocations(List<Location> locations, OsmandApplication app) {
double lastHeight = HEIGHT_UNDEFINED; double lastHeight = HEIGHT_UNDEFINED;
GPXFile gpx = new GPXUtilities.GPXFile(Version.getFullVersion(app)); GPXFile gpx = new GPXUtilities.GPXFile(Version.getFullVersion(app));
List<Location> locations = route.getRouteLocations();
if (locations != null) { if (locations != null) {
GPXUtilities.Track track = new GPXUtilities.Track(); GPXUtilities.Track track = new GPXUtilities.Track();
GPXUtilities.TrkSegment seg = new GPXUtilities.TrkSegment(); GPXUtilities.TrkSegment seg = new GPXUtilities.TrkSegment();
@ -2150,8 +2147,6 @@ public class GpxUiHelper {
} }
} }
lastHeight = h; lastHeight = h;
} else {
lastHeight = HEIGHT_UNDEFINED;
} }
seg.points.add(point); seg.points.add(point);
} }

View file

@ -18,8 +18,8 @@ import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.activities.PluginsFragment; import net.osmand.plus.activities.PluginsFragment;
import net.osmand.plus.dashboard.DashboardOnMap.DashboardType; import net.osmand.plus.dashboard.DashboardOnMap.DashboardType;
import net.osmand.plus.itinerary.ItineraryGroup;
import net.osmand.plus.mapmarkers.MapMarkersDialogFragment; import net.osmand.plus.mapmarkers.MapMarkersDialogFragment;
import net.osmand.plus.mapmarkers.MapMarkersGroup;
import net.osmand.plus.mapsource.EditMapSourceDialogFragment; import net.osmand.plus.mapsource.EditMapSourceDialogFragment;
import net.osmand.plus.openplacereviews.OPRConstants; import net.osmand.plus.openplacereviews.OPRConstants;
import net.osmand.plus.openplacereviews.OprAuthHelper.OprAuthorizationListener; import net.osmand.plus.openplacereviews.OprAuthHelper.OprAuthorizationListener;
@ -219,7 +219,7 @@ public class IntentHelper {
if (intent.hasExtra(MapMarkersDialogFragment.OPEN_MAP_MARKERS_GROUPS)) { if (intent.hasExtra(MapMarkersDialogFragment.OPEN_MAP_MARKERS_GROUPS)) {
Bundle openMapMarkersGroupsExtra = intent.getBundleExtra(MapMarkersDialogFragment.OPEN_MAP_MARKERS_GROUPS); Bundle openMapMarkersGroupsExtra = intent.getBundleExtra(MapMarkersDialogFragment.OPEN_MAP_MARKERS_GROUPS);
if (openMapMarkersGroupsExtra != null) { if (openMapMarkersGroupsExtra != null) {
MapMarkersDialogFragment.showInstance(mapActivity, openMapMarkersGroupsExtra.getString(MapMarkersGroup.MARKERS_SYNC_GROUP_ID)); MapMarkersDialogFragment.showInstance(mapActivity, openMapMarkersGroupsExtra.getString(ItineraryGroup.MARKERS_SYNC_GROUP_ID));
} }
mapActivity.setIntent(null); mapActivity.setIntent(null);
} }

View file

@ -8,9 +8,6 @@ import android.os.AsyncTask;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import net.osmand.AndroidNetworkUtils; import net.osmand.AndroidNetworkUtils;
import net.osmand.AndroidNetworkUtils.OnRequestResultListener; import net.osmand.AndroidNetworkUtils.OnRequestResultListener;
import net.osmand.AndroidNetworkUtils.OnSendRequestsListener; import net.osmand.AndroidNetworkUtils.OnSendRequestsListener;
@ -44,6 +41,9 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
public abstract class InAppPurchaseHelper { public abstract class InAppPurchaseHelper {
// Debug tag, for logging // Debug tag, for logging
protected static final org.apache.commons.logging.Log LOG = PlatformUtil.getLog(InAppPurchaseHelper.class); protected static final org.apache.commons.logging.Log LOG = PlatformUtil.getLog(InAppPurchaseHelper.class);
@ -466,7 +466,7 @@ public abstract class InAppPurchaseHelper {
protected void onSkuDetailsResponseDone(List<PurchaseInfo> purchaseInfoList) { protected void onSkuDetailsResponseDone(List<PurchaseInfo> purchaseInfoList) {
final AndroidNetworkUtils.OnRequestResultListener listener = new AndroidNetworkUtils.OnRequestResultListener() { final AndroidNetworkUtils.OnRequestResultListener listener = new AndroidNetworkUtils.OnRequestResultListener() {
@Override @Override
public void onResult(@Nullable String result, @Nullable String error) { public void onResult(String result) {
notifyDismissProgress(InAppPurchaseTaskType.REQUEST_INVENTORY); notifyDismissProgress(InAppPurchaseTaskType.REQUEST_INVENTORY);
notifyGetItems(); notifyGetItems();
stop(true); stop(true);
@ -477,7 +477,7 @@ public abstract class InAppPurchaseHelper {
if (purchaseInfoList.size() > 0) { if (purchaseInfoList.size() > 0) {
sendTokens(purchaseInfoList, listener); sendTokens(purchaseInfoList, listener);
} else { } else {
listener.onResult("OK", null); listener.onResult("OK");
} }
} }
@ -503,7 +503,7 @@ public abstract class InAppPurchaseHelper {
liveUpdatesPurchase.setState(ctx, SubscriptionState.UNDEFINED); liveUpdatesPurchase.setState(ctx, SubscriptionState.UNDEFINED);
sendTokens(Collections.singletonList(info), new OnRequestResultListener() { sendTokens(Collections.singletonList(info), new OnRequestResultListener() {
@Override @Override
public void onResult(@Nullable String result, @Nullable String error) { public void onResult(String result) {
boolean active = ctx.getSettings().LIVE_UPDATES_PURCHASED.get(); boolean active = ctx.getSettings().LIVE_UPDATES_PURCHASED.get();
ctx.getSettings().LIVE_UPDATES_PURCHASED.set(true); ctx.getSettings().LIVE_UPDATES_PURCHASED.set(true);
ctx.getSettings().getCustomRenderBooleanProperty("depthContours").set(true); ctx.getSettings().getCustomRenderBooleanProperty("depthContours").set(true);
@ -642,7 +642,7 @@ public abstract class InAppPurchaseHelper {
} }
} }
if (listener != null) { if (listener != null) {
listener.onResult("OK", null); listener.onResult("OK");
} }
} }
@ -695,7 +695,7 @@ public abstract class InAppPurchaseHelper {
} catch (Exception e) { } catch (Exception e) {
logError("SendToken Error", e); logError("SendToken Error", e);
if (listener != null) { if (listener != null) {
listener.onResult("Error", null); listener.onResult("Error");
} }
} }
} }

View file

@ -1,8 +1,12 @@
package net.osmand.plus.mapmarkers; package net.osmand.plus.itinerary;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import net.osmand.plus.mapmarkers.CategoriesSubHeader;
import net.osmand.plus.mapmarkers.GroupHeader;
import net.osmand.plus.mapmarkers.MapMarker;
import net.osmand.plus.mapmarkers.ShowHideHistoryButton;
import net.osmand.plus.wikivoyage.data.TravelArticle; import net.osmand.plus.wikivoyage.data.TravelArticle;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
@ -10,7 +14,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
public class MapMarkersGroup { public class ItineraryGroup {
public static final int ANY_TYPE = -1; public static final int ANY_TYPE = -1;
public static final int FAVORITES_TYPE = 0; public static final int FAVORITES_TYPE = 0;
@ -31,13 +35,14 @@ public class MapMarkersGroup {
private TravelArticle wikivoyageArticle; private TravelArticle wikivoyageArticle;
// TODO should be removed from this class: // TODO should be removed from this class:
private GroupHeader header; private GroupHeader header;
private CategoriesSubHeader categoriesSubHeader;
private ShowHideHistoryButton showHideHistoryButton; private ShowHideHistoryButton showHideHistoryButton;
public MapMarkersGroup() { public ItineraryGroup() {
} }
public MapMarkersGroup(@NonNull String id, @NonNull String name, int type) { public ItineraryGroup(@NonNull String id, @NonNull String name, int type) {
this.id = id; this.id = id;
this.name = name; this.name = name;
this.type = type; this.type = type;
@ -75,6 +80,10 @@ public class MapMarkersGroup {
this.header = header; this.header = header;
} }
public void setCategoriesSubHeader(CategoriesSubHeader categoriesSubHeader) {
this.categoriesSubHeader = categoriesSubHeader;
}
public void setShowHideHistoryButton(ShowHideHistoryButton showHideHistoryButton) { public void setShowHideHistoryButton(ShowHideHistoryButton showHideHistoryButton) {
this.showHideHistoryButton = showHideHistoryButton; this.showHideHistoryButton = showHideHistoryButton;
} }
@ -139,6 +148,10 @@ public class MapMarkersGroup {
return header; return header;
} }
public CategoriesSubHeader getCategoriesSubHeader() {
return categoriesSubHeader;
}
public ShowHideHistoryButton getShowHideHistoryButton() { public ShowHideHistoryButton getShowHideHistoryButton() {
return showHideHistoryButton; return showHideHistoryButton;
} }

View file

@ -0,0 +1,436 @@
package net.osmand.plus.itinerary;
import android.os.AsyncTask;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import net.osmand.GPXUtilities.GPXFile;
import net.osmand.GPXUtilities.WptPt;
import net.osmand.IndexConstants;
import net.osmand.PlatformUtil;
import net.osmand.data.FavouritePoint;
import net.osmand.data.LatLon;
import net.osmand.plus.FavouritesDbHelper.FavoriteGroup;
import net.osmand.plus.GPXDatabase;
import net.osmand.plus.GpxSelectionHelper;
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.mapmarkers.MapMarker;
import net.osmand.plus.mapmarkers.MapMarkersDbHelper;
import net.osmand.plus.mapmarkers.MapMarkersHelper;
import net.osmand.plus.mapmarkers.MapMarkersHelper.OnGroupSyncedListener;
import net.osmand.plus.wikivoyage.data.TravelArticle;
import net.osmand.plus.wikivoyage.data.TravelHelper;
import net.osmand.util.Algorithms;
import org.apache.commons.logging.Log;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import static net.osmand.plus.mapmarkers.MapMarkersHelper.BY_DATE_ADDED_DESC;
public class ItineraryHelper {
private static final Log LOG = PlatformUtil.getLog(ItineraryHelper.class);
private OsmandApplication app;
private MapMarkersHelper markersHelper;
private MapMarkersDbHelper markersDbHelper;
private ExecutorService executorService = Executors.newSingleThreadExecutor();
private List<ItineraryGroup> itineraryGroups = new ArrayList<>();
private Set<OnGroupSyncedListener> syncListeners = new HashSet<>();
public ItineraryHelper(@NonNull OsmandApplication app) {
this.app = app;
markersHelper = app.getMapMarkersHelper();
markersDbHelper = app.getMapMarkersDbHelper();
loadGroups();
}
public List<ItineraryGroup> getItineraryGroups() {
return itineraryGroups;
}
public void syncAllGroupsAsync() {
for (ItineraryGroup group : itineraryGroups) {
if (group.getId() != null && group.getName() != null) {
runSynchronization(group);
}
}
}
public void updateGroupWptCategories(@NonNull ItineraryGroup group, Set<String> wptCategories) {
String id = group.getId();
if (id != null) {
group.setWptCategories(wptCategories);
if (wptCategories != null) {
markersDbHelper.updateGroupCategories(id, group.getWptCategoriesString());
}
}
}
public void enableGroup(@NonNull ItineraryGroup gr) {
// check if group doesn't exist internally
if (!itineraryGroups.contains(gr)) {
addGroupInternally(gr);
}
if (gr.isDisabled()) {
updateGroupDisabled(gr, false);
}
runSynchronization(gr);
}
public void updateGroups() {
for (ItineraryGroup group : itineraryGroups) {
markersHelper.updateGroup(group);
}
}
public void updateGroupDisabled(@NonNull ItineraryGroup group, boolean disabled) {
String id = group.getId();
if (id != null) {
markersDbHelper.updateGroupDisabled(id, disabled);
group.setDisabled(disabled);
}
}
public List<MapMarker> getMapMarkersFromDefaultGroups(boolean history) {
List<MapMarker> mapMarkers = new ArrayList<>();
for (ItineraryGroup group : itineraryGroups) {
if (group.getType() == ItineraryGroup.ANY_TYPE) {
for (MapMarker marker : group.getMarkers()) {
if (history && marker.history || !history && !marker.history) {
mapMarkers.add(marker);
}
}
}
}
return mapMarkers;
}
private void loadGroups() {
Map<String, ItineraryGroup> groupsMap = markersDbHelper.getAllGroupsMap();
List<MapMarker> allMarkers = new ArrayList<>(markersHelper.getMapMarkers());
allMarkers.addAll(markersHelper.getMapMarkersHistory());
Iterator<Entry<String, ItineraryGroup>> iterator = groupsMap.entrySet().iterator();
while (iterator.hasNext()) {
ItineraryGroup group = iterator.next().getValue();
if (group.getType() == ItineraryGroup.GPX_TYPE && !new File(group.getId()).exists()) {
markersDbHelper.removeMarkersGroup(group.getId());
iterator.remove();
}
}
ItineraryGroup noGroup = null;
for (MapMarker marker : allMarkers) {
ItineraryGroup group = groupsMap.get(marker.groupKey);
if (group == null) {
if (noGroup == null) {
noGroup = new ItineraryGroup();
noGroup.setCreationDate(Long.MAX_VALUE);
}
noGroup.getMarkers().add(marker);
} else {
if (marker.creationDate < group.getCreationDate()) {
group.setCreationDate(marker.creationDate);
}
group.getMarkers().add(marker);
}
}
itineraryGroups = new ArrayList<>(groupsMap.values());
if (noGroup != null) {
markersHelper.sortMarkers(noGroup.getMarkers(), false, BY_DATE_ADDED_DESC);
addToGroupsList(noGroup);
}
sortGroups();
for (ItineraryGroup group : itineraryGroups) {
markersHelper.updateGroup(group);
}
}
public void addGroupInternally(ItineraryGroup gr) {
markersDbHelper.addGroup(gr);
markersHelper.addHistoryMarkersToGroup(gr);
addToGroupsList(gr);
}
public void updateGpxShowAsMarkers(File file) {
GPXDatabase.GpxDataItem dataItem = app.getGpxDbHelper().getItem(file);
if (dataItem != null) {
app.getGpxDbHelper().updateShowAsMarkers(dataItem, true);
dataItem.setShowAsMarkers(true);
}
}
public void addToGroupsList(ItineraryGroup group) {
List<ItineraryGroup> copyList = new ArrayList<>(itineraryGroups);
copyList.add(group);
itineraryGroups = copyList;
}
public void removeFromGroupsList(ItineraryGroup group) {
List<ItineraryGroup> copyList = new ArrayList<>(itineraryGroups);
copyList.remove(group);
itineraryGroups = copyList;
}
public void addSyncListener(OnGroupSyncedListener listener) {
syncListeners.add(listener);
}
public void removeSyncListener(OnGroupSyncedListener listener) {
syncListeners.remove(listener);
}
public void runSynchronization(final @NonNull ItineraryGroup group) {
app.runInUIThread(new Runnable() {
@Override
public void run() {
new SyncGroupTask(group).executeOnExecutor(executorService);
}
});
}
public ItineraryGroup getMarkersGroup(GPXFile gpx) {
if (gpx == null || gpx.path == null) {
return null;
}
return getMapMarkerGroupById(getMarkerGroupId(new File(gpx.path)), ItineraryGroup.GPX_TYPE);
}
public ItineraryGroup getMarkersGroup(FavoriteGroup favGroup) {
return getMapMarkerGroupById(getMarkerGroupId(favGroup), ItineraryGroup.FAVORITES_TYPE);
}
public ItineraryGroup addOrEnableGpxGroup(@NonNull File file) {
updateGpxShowAsMarkers(file);
ItineraryGroup gr = getMapMarkerGroupById(getMarkerGroupId(file), ItineraryGroup.GPX_TYPE);
if (gr == null) {
gr = createGPXMarkerGroup(file);
addGroupInternally(gr);
}
enableGroup(gr);
return gr;
}
public ItineraryGroup addOrEnableGroup(@NonNull GPXFile file) {
updateGpxShowAsMarkers(new File(file.path));
ItineraryGroup gr = getMarkersGroup(file);
if (gr == null) {
gr = createGPXMarkerGroup(new File(file.path));
addGroupInternally(gr);
}
enableGroup(gr);
return gr;
}
public ItineraryGroup addOrEnableGroup(@NonNull FavoriteGroup group) {
ItineraryGroup gr = getMarkersGroup(group);
if (gr == null) {
gr = createFavMarkerGroup(group);
addGroupInternally(gr);
}
enableGroup(gr);
return gr;
}
private ItineraryGroup createGPXMarkerGroup(File fl) {
return new ItineraryGroup(getMarkerGroupId(fl),
Algorithms.getFileNameWithoutExtension(fl.getName()),
ItineraryGroup.GPX_TYPE);
}
private ItineraryGroup createFavMarkerGroup(FavoriteGroup favGroup) {
return new ItineraryGroup(favGroup.getName(), favGroup.getName(), ItineraryGroup.FAVORITES_TYPE);
}
private String getMarkerGroupId(File gpx) {
return gpx.getAbsolutePath();
}
private String getMarkerGroupId(FavoriteGroup group) {
return group.getName();
}
public void removeMarkerFromGroup(MapMarker marker) {
if (marker != null) {
ItineraryGroup itineraryGroup = getMapMarkerGroupById(marker.groupKey, marker.getType());
if (itineraryGroup != null) {
itineraryGroup.getMarkers().remove(marker);
markersHelper.updateGroup(itineraryGroup);
}
}
}
public void sortGroups() {
if (itineraryGroups.size() > 0) {
Collections.sort(itineraryGroups, new Comparator<ItineraryGroup>() {
@Override
public int compare(ItineraryGroup group1, ItineraryGroup group2) {
long t1 = group1.getCreationDate();
long t2 = group2.getCreationDate();
return (t1 > t2) ? -1 : ((t1 == t2) ? 0 : 1);
}
});
}
}
@Nullable
public ItineraryGroup getMapMarkerGroupById(String id, int type) {
for (ItineraryGroup group : itineraryGroups) {
if ((id == null && group.getId() == null)
|| (group.getId() != null && group.getId().equals(id))) {
if (type == ItineraryGroup.ANY_TYPE || type == group.getType()) {
return group;
}
}
}
return null;
}
@NonNull
public List<ItineraryGroup> getGroupsForDisplayedGpx() {
List<ItineraryGroup> res = new ArrayList<>();
List<SelectedGpxFile> selectedGpxFiles = app.getSelectedGpxHelper().getSelectedGPXFiles();
for (SelectedGpxFile selected : selectedGpxFiles) {
ItineraryGroup search = getMarkersGroup(selected.getGpxFile());
if (search == null && selected.getGpxFile() != null && selected.getGpxFile().path != null) {
ItineraryGroup group = createGPXMarkerGroup(new File(selected.getGpxFile().path));
group.setDisabled(true);
markersHelper.createHeadersInGroup(group);
res.add(group);
}
}
return res;
}
@NonNull
public List<ItineraryGroup> getGroupsForSavedArticlesTravelBook() {
List<ItineraryGroup> res = new ArrayList<>();
TravelHelper travelHelper = app.getTravelHelper();
if (travelHelper.isAnyTravelBookPresent()) {
List<TravelArticle> savedArticles = travelHelper.getBookmarksHelper().getSavedArticles();
for (TravelArticle art : savedArticles) {
String gpxName = travelHelper.getGPXName(art);
File path = app.getAppPath(IndexConstants.GPX_TRAVEL_DIR + gpxName);
ItineraryGroup search = getMapMarkerGroupById(getMarkerGroupId(path), ItineraryGroup.GPX_TYPE);
if (search == null) {
ItineraryGroup group = createGPXMarkerGroup(path);
group.setDisabled(true);
markersHelper.createHeadersInGroup(group);
res.add(group);
}
}
}
return res;
}
private class SyncGroupTask extends AsyncTask<Void, Void, Void> {
private ItineraryGroup group;
SyncGroupTask(ItineraryGroup group) {
this.group = group;
}
@Override
protected void onPreExecute() {
if (!syncListeners.isEmpty()) {
app.runInUIThread(new Runnable() {
@Override
public void run() {
for (OnGroupSyncedListener listener : syncListeners) {
listener.onSyncStarted();
}
}
});
}
}
@Override
protected Void doInBackground(Void... voids) {
runGroupSynchronization();
return null;
}
// TODO extract method from Asynctask to Helper directly
private void runGroupSynchronization() {
List<MapMarker> groupMarkers = new ArrayList<>(group.getMarkers());
if (group.getType() == ItineraryGroup.FAVORITES_TYPE) {
FavoriteGroup favGroup = app.getFavorites().getGroup(group.getName());
if (favGroup == null) {
return;
}
group.setVisible(favGroup.isVisible());
if (!group.isVisible() || group.isDisabled()) {
markersHelper.removeGroupActiveMarkers(group, true);
return;
}
List<FavouritePoint> points = new ArrayList<>(favGroup.getPoints());
for (FavouritePoint fp : points) {
markersHelper.addNewMarkerIfNeeded(group, groupMarkers, new LatLon(fp.getLatitude(), fp.getLongitude()), fp.getName(), fp, null);
}
} else if (group.getType() == ItineraryGroup.GPX_TYPE) {
GpxSelectionHelper gpxHelper = app.getSelectedGpxHelper();
File file = new File(group.getId());
if (!file.exists()) {
return;
}
String gpxPath = group.getId();
SelectedGpxFile selectedGpxFile = gpxHelper.getSelectedFileByPath(gpxPath);
GPXFile gpx = selectedGpxFile == null ? null : selectedGpxFile.getGpxFile();
group.setVisible(gpx != null || group.isVisibleUntilRestart());
if (gpx == null || group.isDisabled()) {
markersHelper.removeGroupActiveMarkers(group, true);
return;
}
boolean addAll = group.getWptCategories() == null || group.getWptCategories().isEmpty();
List<WptPt> gpxPoints = new ArrayList<>(gpx.getPoints());
for (WptPt pt : gpxPoints) {
if (addAll || group.getWptCategories().contains(pt.category)
|| (pt.category == null && group.getWptCategories().contains(""))) {
markersHelper.addNewMarkerIfNeeded(group, groupMarkers, new LatLon(pt.lat, pt.lon), pt.name, null, pt);
}
}
}
markersHelper.removeOldMarkersIfPresent(groupMarkers);
}
@Override
protected void onPostExecute(Void aVoid) {
if (!syncListeners.isEmpty()) {
app.runInUIThread(new Runnable() {
@Override
public void run() {
for (OnGroupSyncedListener listener : syncListeners) {
listener.onSyncDone();
}
}
});
}
}
}
}

View file

@ -275,14 +275,16 @@ public class LiveUpdatesFragment extends BaseOsmAndDialogFragment implements OnL
TextViewEx toolbarTitle = (TextViewEx) toolbar.findViewById(R.id.toolbar_title); TextViewEx toolbarTitle = (TextViewEx) toolbar.findViewById(R.id.toolbar_title);
toolbarTitle.setText(R.string.osm_live); toolbarTitle.setText(R.string.osm_live);
ImageView closeButton = (ImageView) toolbar.findViewById(R.id.close_button); View closeButton = toolbar.findViewById(R.id.close_button);
UiUtilities.rotateImageByLayoutDirection(closeButton);
closeButton.setOnClickListener(new View.OnClickListener() { closeButton.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
dismiss(); dismiss();
} }
}); });
if (closeButton instanceof ImageView) {
UiUtilities.rotateImageByLayoutDirection((ImageView) closeButton);
}
FrameLayout iconHelpContainer = toolbar.findViewById(R.id.action_button); FrameLayout iconHelpContainer = toolbar.findViewById(R.id.action_button);
int iconColorResId = nightMode ? R.color.active_buttons_and_links_text_dark : R.color.active_buttons_and_links_text_light; int iconColorResId = nightMode ? R.color.active_buttons_and_links_text_dark : R.color.active_buttons_and_links_text_light;
@ -441,8 +443,6 @@ public class LiveUpdatesFragment extends BaseOsmAndDialogFragment implements OnL
boolean isLastChild, View convertView, ViewGroup parent) { boolean isLastChild, View convertView, ViewGroup parent) {
LayoutInflater inflater = UiUtilities.getInflater(app, nightMode); LayoutInflater inflater = UiUtilities.getInflater(app, nightMode);
convertView = inflater.inflate(R.layout.list_item_triple_row_icon_and_menu, parent, false); convertView = inflater.inflate(R.layout.list_item_triple_row_icon_and_menu, parent, false);
ImageView secondaryIcon = (ImageView) convertView.findViewById(R.id.secondary_icon);
UiUtilities.rotateImageByLayoutDirection(secondaryIcon);
LiveMapsViewHolder viewHolder = new LiveMapsViewHolder(convertView); LiveMapsViewHolder viewHolder = new LiveMapsViewHolder(convertView);
convertView.setTag(viewHolder); convertView.setTag(viewHolder);
viewHolder.bindLocalIndexInfo(getChild(groupPosition, childPosition).getFileName()); viewHolder.bindLocalIndexInfo(getChild(groupPosition, childPosition).getFileName());

View file

@ -6,7 +6,6 @@ import android.content.Context;
import android.os.AsyncTask; import android.os.AsyncTask;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import net.osmand.AndroidNetworkUtils; import net.osmand.AndroidNetworkUtils;
import net.osmand.AndroidNetworkUtils.OnRequestResultListener; import net.osmand.AndroidNetworkUtils.OnRequestResultListener;
@ -195,7 +194,7 @@ public class PerformLiveUpdateAsyncTask
AndroidNetworkUtils.sendRequestAsync( AndroidNetworkUtils.sendRequestAsync(
app, LiveUpdatesFragment.URL, null, "Requesting map updates info...", false, false, new OnRequestResultListener() { app, LiveUpdatesFragment.URL, null, "Requesting map updates info...", false, false, new OnRequestResultListener() {
@Override @Override
public void onResult(@Nullable String result, @Nullable String error) { public void onResult(String result) {
if (!Algorithms.isEmpty(result)) { if (!Algorithms.isEmpty(result)) {
SimpleDateFormat source = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US); SimpleDateFormat source = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US);
source.setTimeZone(TimeZone.getTimeZone("UTC")); source.setTimeZone(TimeZone.getTimeZone("UTC"));

View file

@ -208,7 +208,7 @@ public class SubscriptionFragment extends BaseOsmAndDialogFragment implements In
"https://osmand.net/subscription/update", "https://osmand.net/subscription/update",
parameters, "Sending data...", true, true, new AndroidNetworkUtils.OnRequestResultListener() { parameters, "Sending data...", true, true, new AndroidNetworkUtils.OnRequestResultListener() {
@Override @Override
public void onResult(@Nullable String result, @Nullable String error) { public void onResult(String result) {
dismissProgress(null); dismissProgress(null);
OsmandApplication app = getMyApplication(); OsmandApplication app = getMyApplication();
if (result != null) { if (result != null) {

View file

@ -189,24 +189,7 @@ public class TransportStopController extends MenuController {
} }
} }
private static void sortTransportStopsExits(@NonNull LatLon latLon, @NonNull List<TransportStop> transportStops) { private static void sortTransportStops(@NonNull LatLon latLon, List<TransportStop> transportStops) {
for (TransportStop transportStop : transportStops) {
for (TransportStopExit exit : transportStop.getExits()) {
int distance = (int) MapUtils.getDistance(latLon, exit.getLocation());
if (transportStop.distance > distance) {
transportStop.distance = distance;
}
}
}
Collections.sort(transportStops, new Comparator<TransportStop>() {
@Override
public int compare(TransportStop s1, TransportStop s2) {
return Algorithms.compare(s1.distance, s2.distance);
}
});
}
private static void sortTransportStops(@NonNull LatLon latLon, @NonNull List<TransportStop> transportStops) {
for (TransportStop transportStop : transportStops) { for (TransportStop transportStop : transportStops) {
transportStop.distance = (int) MapUtils.getDistance(latLon, transportStop.getLocation()); transportStop.distance = (int) MapUtils.getDistance(latLon, transportStop.getLocation());
} }
@ -244,8 +227,6 @@ public class TransportStopController extends MenuController {
if (isSubwayEntrance) { if (isSubwayEntrance) {
stopAggregated = processTransportStopsForAmenity(transportStops, amenity); stopAggregated = processTransportStopsForAmenity(transportStops, amenity);
sortTransportStopsExits(loc, stopAggregated.getLocalTransportStops());
sortTransportStopsExits(loc, stopAggregated.getNearbyTransportStops());
} else { } else {
stopAggregated = new TransportStopAggregated(); stopAggregated = new TransportStopAggregated();
stopAggregated.setAmenity(amenity); stopAggregated.setAmenity(amenity);

View file

@ -17,8 +17,6 @@ import net.osmand.GPXUtilities.WptPt;
import net.osmand.data.LatLon; import net.osmand.data.LatLon;
import net.osmand.data.WptLocationPoint; import net.osmand.data.WptLocationPoint;
import net.osmand.plus.GpxSelectionHelper; import net.osmand.plus.GpxSelectionHelper;
import net.osmand.plus.mapmarkers.MapMarkersHelper;
import net.osmand.plus.mapmarkers.MapMarkersGroup;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
@ -26,6 +24,7 @@ import net.osmand.plus.activities.SavingTrackHelper;
import net.osmand.plus.base.PointImageDrawable; import net.osmand.plus.base.PointImageDrawable;
import net.osmand.plus.mapcontextmenu.MapContextMenu; import net.osmand.plus.mapcontextmenu.MapContextMenu;
import net.osmand.plus.mapcontextmenu.editors.WptPtEditor.OnDismissListener; import net.osmand.plus.mapcontextmenu.editors.WptPtEditor.OnDismissListener;
import net.osmand.plus.itinerary.ItineraryGroup;
import net.osmand.plus.track.SaveGpxAsyncTask; import net.osmand.plus.track.SaveGpxAsyncTask;
import net.osmand.plus.track.SaveGpxAsyncTask.SaveGpxListener; import net.osmand.plus.track.SaveGpxAsyncTask.SaveGpxListener;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
@ -220,10 +219,9 @@ public class WptPtEditorFragment extends PointEditorFragment {
private void syncGpx(GPXFile gpxFile) { private void syncGpx(GPXFile gpxFile) {
OsmandApplication app = getMyApplication(); OsmandApplication app = getMyApplication();
if (app != null) { if (app != null) {
MapMarkersHelper helper = app.getMapMarkersHelper(); ItineraryGroup group = app.getItineraryHelper().getMarkersGroup(gpxFile);
MapMarkersGroup group = helper.getMarkersGroup(gpxFile);
if (group != null) { if (group != null) {
helper.runSynchronization(group); app.getItineraryHelper().runSynchronization(group);
} }
} }
} }

View file

@ -20,8 +20,6 @@ import net.osmand.data.FavouritePoint.BackgroundType;
import net.osmand.data.LatLon; import net.osmand.data.LatLon;
import net.osmand.data.WptLocationPoint; import net.osmand.data.WptLocationPoint;
import net.osmand.plus.GpxSelectionHelper; import net.osmand.plus.GpxSelectionHelper;
import net.osmand.plus.mapmarkers.MapMarkersHelper;
import net.osmand.plus.mapmarkers.MapMarkersGroup;
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile; import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
@ -29,6 +27,7 @@ import net.osmand.plus.UiUtilities;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.activities.SavingTrackHelper; import net.osmand.plus.activities.SavingTrackHelper;
import net.osmand.plus.base.PointImageDrawable; import net.osmand.plus.base.PointImageDrawable;
import net.osmand.plus.itinerary.ItineraryGroup;
import net.osmand.plus.mapcontextmenu.MapContextMenu; import net.osmand.plus.mapcontextmenu.MapContextMenu;
import net.osmand.plus.mapcontextmenu.editors.WptPtEditor.OnDismissListener; import net.osmand.plus.mapcontextmenu.editors.WptPtEditor.OnDismissListener;
import net.osmand.plus.track.SaveGpxAsyncTask; import net.osmand.plus.track.SaveGpxAsyncTask;
@ -238,10 +237,9 @@ public class WptPtEditorFragmentNew extends PointEditorFragmentNew {
private void syncGpx(GPXFile gpxFile) { private void syncGpx(GPXFile gpxFile) {
OsmandApplication app = getMyApplication(); OsmandApplication app = getMyApplication();
if (app != null) { if (app != null) {
MapMarkersHelper helper = app.getMapMarkersHelper(); ItineraryGroup group = app.getItineraryHelper().getMarkersGroup(gpxFile);
MapMarkersGroup group = helper.getMarkersGroup(gpxFile);
if (group != null) { if (group != null) {
helper.runSynchronization(group); app.getItineraryHelper().runSynchronization(group);
} }
} }
} }

View file

@ -56,7 +56,7 @@ public class AddFavouritesGroupBottomSheetDialogFragment extends AddGroupBottomS
if (!group.isVisible()) { if (!group.isVisible()) {
favouritesDbHelper.editFavouriteGroup(group, group.getName(), group.getColor(), true); favouritesDbHelper.editFavouriteGroup(group, group.getName(), group.getColor(), true);
} }
getMyApplication().getMapMarkersHelper().addOrEnableGroup(group); getMyApplication().getItineraryHelper().addOrEnableGroup(group);
dismiss(); dismiss();
} }
} }

View file

@ -108,7 +108,7 @@ public class AddTracksGroupBottomSheetDialogFragment extends AddGroupBottomSheet
GPXFile res = GPXUtilities.loadGPXFile(gpx); GPXFile res = GPXUtilities.loadGPXFile(gpx);
selectionHelper.selectGpxFile(res, true, false, false, false, false); selectionHelper.selectGpxFile(res, true, false, false, false, false);
} }
app.getMapMarkersHelper().addOrEnableGpxGroup(gpx); app.getItineraryHelper().addOrEnableGpxGroup(gpx);
} }
} }
dismiss(); dismiss();

View file

@ -2,3 +2,25 @@ package net.osmand.plus.mapmarkers;
import androidx.annotation.DrawableRes; import androidx.annotation.DrawableRes;
import net.osmand.plus.itinerary.ItineraryGroup;
public class CategoriesSubHeader {
@DrawableRes
private int iconRes;
private ItineraryGroup group;
public CategoriesSubHeader(int iconRes, ItineraryGroup group) {
this.iconRes = iconRes;
this.group = group;
}
@DrawableRes
public int getIconRes() {
return iconRes;
}
public ItineraryGroup getGroup() {
return group;
}
}

View file

@ -71,6 +71,8 @@ import net.osmand.plus.Version;
import net.osmand.plus.activities.SavingTrackHelper; import net.osmand.plus.activities.SavingTrackHelper;
import net.osmand.plus.activities.TrackActivity; import net.osmand.plus.activities.TrackActivity;
import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.helpers.AndroidUiHelper;
import net.osmand.plus.itinerary.ItineraryGroup;
import net.osmand.plus.itinerary.ItineraryHelper;
import net.osmand.plus.mapmarkers.CoordinateInputBottomSheetDialogFragment.CoordinateInputFormatChangeListener; import net.osmand.plus.mapmarkers.CoordinateInputBottomSheetDialogFragment.CoordinateInputFormatChangeListener;
import net.osmand.plus.mapmarkers.CoordinateInputFormats.DDM; import net.osmand.plus.mapmarkers.CoordinateInputFormats.DDM;
import net.osmand.plus.mapmarkers.CoordinateInputFormats.DMS; import net.osmand.plus.mapmarkers.CoordinateInputFormats.DMS;
@ -168,8 +170,8 @@ public class CoordinateInputDialogFragment extends DialogFragment implements Osm
} }
private void syncGpx(GPXFile gpxFile) { private void syncGpx(GPXFile gpxFile) {
MapMarkersHelper helper = getMyApplication().getMapMarkersHelper(); ItineraryHelper helper = getMyApplication().getItineraryHelper();
MapMarkersGroup group = helper.getMarkersGroup(gpxFile); ItineraryGroup group = helper.getMarkersGroup(gpxFile);
if (group != null) { if (group != null) {
helper.runSynchronization(group); helper.runSynchronization(group);
} }
@ -1089,7 +1091,7 @@ public class CoordinateInputDialogFragment extends DialogFragment implements Osm
public void saveGpx(final String fileName) { public void saveGpx(final String fileName) {
new SaveGpxAsyncTask(app, getGpx(),fileName, false).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); new SaveGpxAsyncTask(app, getGpx(),fileName, false).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
hasUnsavedChanges = false; hasUnsavedChanges = false;
app.getMapMarkersHelper().addOrEnableGroup(getGpx()); app.getItineraryHelper().addOrEnableGroup(getGpx());
if (listener != null) { if (listener != null) {
listener.onPointsSaved(); listener.onPointsSaved();
} }

View file

@ -2,13 +2,15 @@ package net.osmand.plus.mapmarkers;
import androidx.annotation.DrawableRes; import androidx.annotation.DrawableRes;
import net.osmand.plus.itinerary.ItineraryGroup;
public class GroupHeader { public class GroupHeader {
@DrawableRes @DrawableRes
private int iconRes; private int iconRes;
private MapMarkersGroup group; private ItineraryGroup group;
public GroupHeader(int iconRes, MapMarkersGroup group) { public GroupHeader(int iconRes, ItineraryGroup group) {
this.iconRes = iconRes; this.iconRes = iconRes;
this.group = group; this.group = group;
} }
@ -18,7 +20,7 @@ public class GroupHeader {
return iconRes; return iconRes;
} }
public MapMarkersGroup getGroup() { public ItineraryGroup getGroup() {
return group; return group;
} }
} }

View file

@ -11,6 +11,7 @@ import net.osmand.data.LatLon;
import net.osmand.data.LocationPoint; import net.osmand.data.LocationPoint;
import net.osmand.data.PointDescription; import net.osmand.data.PointDescription;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.itinerary.ItineraryGroup;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
import static net.osmand.data.PointDescription.POINT_TYPE_MAP_MARKER; import static net.osmand.data.PointDescription.POINT_TYPE_MAP_MARKER;
@ -46,8 +47,8 @@ public class MapMarker implements LocationPoint {
public int getType() { public int getType() {
return favouritePoint == null ? return favouritePoint == null ?
(wptPt == null ? MapMarkersGroup.ANY_TYPE : MapMarkersGroup.GPX_TYPE) : (wptPt == null ? ItineraryGroup.ANY_TYPE : ItineraryGroup.GPX_TYPE) :
MapMarkersGroup.FAVORITES_TYPE; ItineraryGroup.FAVORITES_TYPE;
} }
public PointDescription getPointDescription(Context ctx) { public PointDescription getPointDescription(Context ctx) {

View file

@ -8,6 +8,7 @@ import net.osmand.plus.OsmandApplication;
import net.osmand.plus.api.SQLiteAPI.SQLiteConnection; import net.osmand.plus.api.SQLiteAPI.SQLiteConnection;
import net.osmand.plus.api.SQLiteAPI.SQLiteCursor; import net.osmand.plus.api.SQLiteAPI.SQLiteCursor;
import net.osmand.plus.helpers.SearchHistoryHelper; import net.osmand.plus.helpers.SearchHistoryHelper;
import net.osmand.plus.itinerary.ItineraryGroup;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
import java.util.ArrayList; import java.util.ArrayList;
@ -161,7 +162,7 @@ public class MapMarkersDbHelper {
} }
} }
public void addGroup(MapMarkersGroup group) { public void addGroup(ItineraryGroup group) {
SQLiteConnection db = openConnection(false); SQLiteConnection db = openConnection(false);
if (db != null) { if (db != null) {
try { try {
@ -173,15 +174,15 @@ public class MapMarkersDbHelper {
} }
} }
public Map<String, MapMarkersGroup> getAllGroupsMap() { public Map<String, ItineraryGroup> getAllGroupsMap() {
Map<String, MapMarkersGroup> res = new LinkedHashMap<>(); Map<String, ItineraryGroup> res = new LinkedHashMap<>();
SQLiteConnection db = openConnection(true); SQLiteConnection db = openConnection(true);
if (db != null) { if (db != null) {
try { try {
SQLiteCursor query = db.rawQuery(GROUPS_TABLE_SELECT, null); SQLiteCursor query = db.rawQuery(GROUPS_TABLE_SELECT, null);
if (query != null && query.moveToFirst()) { if (query != null && query.moveToFirst()) {
do { do {
MapMarkersGroup group = readGroup(query); ItineraryGroup group = readGroup(query);
res.put(group.getId(), group); res.put(group.getId(), group);
} while (query.moveToNext()); } while (query.moveToNext());
} }
@ -195,14 +196,14 @@ public class MapMarkersDbHelper {
return res; return res;
} }
private MapMarkersGroup readGroup(SQLiteCursor query) { private ItineraryGroup readGroup(SQLiteCursor query) {
String id = query.getString(0); String id = query.getString(0);
String name = query.getString(1); String name = query.getString(1);
int type = query.getInt(2); int type = query.getInt(2);
boolean disabled = query.getInt(3) == 1; boolean disabled = query.getInt(3) == 1;
String categories = query.getString(4); String categories = query.getString(4);
MapMarkersGroup res = new MapMarkersGroup(id, name, type); ItineraryGroup res = new ItineraryGroup(id, name, type);
res.setDisabled(disabled); res.setDisabled(disabled);
res.setWptCategories(categories == null ? null : Algorithms.decodeStringSet(categories)); res.setWptCategories(categories == null ? null : Algorithms.decodeStringSet(categories));

View file

@ -218,13 +218,13 @@ public class MapMarkersDialogFragment extends DialogFragment implements OnGroupS
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
getMyApplication().getMapMarkersHelper().addSyncListener(this); getMyApplication().getItineraryHelper().addSyncListener(this);
} }
@Override @Override
public void onPause() { public void onPause() {
super.onPause(); super.onPause();
getMyApplication().getMapMarkersHelper().removeSyncListener(this); getMyApplication().getItineraryHelper().removeSyncListener(this);
} }
@Override @Override

View file

@ -1,7 +1,5 @@
package net.osmand.plus.mapmarkers; package net.osmand.plus.mapmarkers;
import android.os.AsyncTask;
import androidx.annotation.IntDef; import androidx.annotation.IntDef;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
@ -16,17 +14,12 @@ import net.osmand.PlatformUtil;
import net.osmand.data.FavouritePoint; import net.osmand.data.FavouritePoint;
import net.osmand.data.LatLon; import net.osmand.data.LatLon;
import net.osmand.data.PointDescription; import net.osmand.data.PointDescription;
import net.osmand.plus.FavouritesDbHelper.FavoriteGroup;
import net.osmand.plus.GPXDatabase;
import net.osmand.plus.GeocodingLookupService; import net.osmand.plus.GeocodingLookupService;
import net.osmand.plus.GeocodingLookupService.AddressLookupRequest; import net.osmand.plus.GeocodingLookupService.AddressLookupRequest;
import net.osmand.plus.GpxSelectionHelper;
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.Version; import net.osmand.plus.Version;
import net.osmand.plus.wikivoyage.data.TravelArticle; import net.osmand.plus.itinerary.ItineraryGroup;
import net.osmand.plus.wikivoyage.data.TravelHelper;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
import net.osmand.util.MapUtils; import net.osmand.util.MapUtils;
@ -41,15 +34,10 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.Date; import java.util.Date;
import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone; import java.util.TimeZone;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import static net.osmand.GPXUtilities.GPX_TIME_FORMAT; import static net.osmand.GPXUtilities.GPX_TIME_FORMAT;
import static net.osmand.data.PointDescription.POINT_TYPE_MAP_MARKER; import static net.osmand.data.PointDescription.POINT_TYPE_MAP_MARKER;
@ -75,17 +63,13 @@ public class MapMarkersHelper {
public @interface MapMarkersSortByDef { public @interface MapMarkersSortByDef {
} }
private OsmandApplication ctx; private OsmandApplication app;
private MapMarkersDbHelper markersDbHelper; private MapMarkersDbHelper markersDbHelper;
private ExecutorService executorService = Executors.newSingleThreadExecutor();
private List<MapMarker> mapMarkers = new ArrayList<>(); private List<MapMarker> mapMarkers = new ArrayList<>();
private List<MapMarker> mapMarkersHistory = new ArrayList<>(); private List<MapMarker> mapMarkersHistory = new ArrayList<>();
private List<MapMarkersGroup> mapMarkersGroups = new ArrayList<>();
private List<MapMarkerChangedListener> listeners = new ArrayList<>(); private List<MapMarkerChangedListener> listeners = new ArrayList<>();
private Set<OnGroupSyncedListener> syncListeners = new HashSet<>();
private MarkersPlanRouteContext planRouteContext; private MarkersPlanRouteContext planRouteContext;
@ -97,29 +81,24 @@ public class MapMarkersHelper {
return mapMarkersHistory; return mapMarkersHistory;
} }
public List<MapMarkersGroup> getMapMarkersGroups() {
return mapMarkersGroups;
}
public boolean isStartFromMyLocation() { public boolean isStartFromMyLocation() {
return ctx.getSettings().ROUTE_MAP_MARKERS_START_MY_LOC.get(); return app.getSettings().ROUTE_MAP_MARKERS_START_MY_LOC.get();
} }
public void setStartFromMyLocation(boolean startFromMyLocation) { public void setStartFromMyLocation(boolean startFromMyLocation) {
ctx.getSettings().ROUTE_MAP_MARKERS_START_MY_LOC.set(startFromMyLocation); app.getSettings().ROUTE_MAP_MARKERS_START_MY_LOC.set(startFromMyLocation);
} }
public MarkersPlanRouteContext getPlanRouteContext() { public MarkersPlanRouteContext getPlanRouteContext() {
return planRouteContext; return planRouteContext;
} }
public MapMarkersHelper(OsmandApplication ctx) { public MapMarkersHelper(OsmandApplication app) {
this.ctx = ctx; this.app = app;
markersDbHelper = ctx.getMapMarkersDbHelper(); markersDbHelper = app.getMapMarkersDbHelper();
planRouteContext = new MarkersPlanRouteContext(ctx); planRouteContext = new MarkersPlanRouteContext(app);
markersDbHelper.removeDisabledGroups(); markersDbHelper.removeDisabledGroups();
loadMarkers(); loadMarkers();
loadGroups();
} }
private void loadMarkers() { private void loadMarkers() {
@ -133,63 +112,11 @@ public class MapMarkersHelper {
sortMarkers(markersHistory, true, BY_DATE_ADDED_DESC); sortMarkers(markersHistory, true, BY_DATE_ADDED_DESC);
addToMapMarkersHistoryList(markersHistory); addToMapMarkersHistoryList(markersHistory);
if (!ctx.isApplicationInitializing()) { if (!app.isApplicationInitializing()) {
lookupAddressAll(); lookupAddressAll();
} }
} }
private void loadGroups() {
Map<String, MapMarkersGroup> groupsMap = markersDbHelper.getAllGroupsMap();
List<MapMarker> allMarkers = new ArrayList<>(mapMarkers);
allMarkers.addAll(mapMarkersHistory);
Iterator<Map.Entry<String, MapMarkersGroup>> iterator = groupsMap.entrySet().iterator();
while (iterator.hasNext()) {
MapMarkersGroup group = iterator.next().getValue();
if (group.getType() == MapMarkersGroup.GPX_TYPE && !new File(group.getId()).exists()) {
markersDbHelper.removeMarkersGroup(group.getId());
iterator.remove();
}
}
MapMarkersGroup noGroup = null;
for (MapMarker marker : allMarkers) {
MapMarkersGroup group = groupsMap.get(marker.groupKey);
if (group == null) {
if (noGroup == null) {
noGroup = new MapMarkersGroup();
noGroup.setCreationDate(Long.MAX_VALUE);
}
noGroup.getMarkers().add(marker);
} else {
if (marker.creationDate < group.getCreationDate()) {
group.setCreationDate(marker.creationDate);
}
group.getMarkers().add(marker);
}
}
mapMarkersGroups = new ArrayList<>(groupsMap.values());
if (noGroup != null) {
sortMarkers(noGroup.getMarkers(), false, BY_DATE_ADDED_DESC);
addToGroupsList(noGroup);
}
sortGroups();
for (MapMarkersGroup group : mapMarkersGroups) {
updateGroup(group);
}
}
public void syncAllGroupsAsync() {
for (MapMarkersGroup gr : mapMarkersGroups) {
if (gr.getId() != null && gr.getName() != null) {
runSynchronization(gr);
}
}
}
public void lookupAddressAll() { public void lookupAddressAll() {
for (MapMarker mapMarker : mapMarkers) { for (MapMarker mapMarker : mapMarkers) {
@ -201,7 +128,7 @@ public class MapMarkersHelper {
} }
private void lookupAddress(final MapMarker mapMarker) { private void lookupAddress(final MapMarker mapMarker) {
if (mapMarker != null && mapMarker.getOriginalPointDescription().isSearchingAddress(ctx)) { if (mapMarker != null && mapMarker.getOriginalPointDescription().isSearchingAddress(app)) {
cancelPointAddressRequests(mapMarker.point); cancelPointAddressRequests(mapMarker.point);
AddressLookupRequest lookupRequest = new AddressLookupRequest(mapMarker.point, AddressLookupRequest lookupRequest = new AddressLookupRequest(mapMarker.point,
new GeocodingLookupService.OnAddressLookupResult() { new GeocodingLookupService.OnAddressLookupResult() {
@ -209,7 +136,7 @@ public class MapMarkersHelper {
public void geocodingDone(String address) { public void geocodingDone(String address) {
PointDescription pointDescription = mapMarker.getOriginalPointDescription(); PointDescription pointDescription = mapMarker.getOriginalPointDescription();
if (Algorithms.isEmpty(address)) { if (Algorithms.isEmpty(address)) {
pointDescription.setName(PointDescription.getAddressNotFoundStr(ctx)); pointDescription.setName(PointDescription.getAddressNotFoundStr(app));
} else { } else {
pointDescription.setName(address); pointDescription.setName(address);
} }
@ -217,7 +144,7 @@ public class MapMarkersHelper {
refreshMarker(mapMarker); refreshMarker(mapMarker);
} }
}, null); }, null);
ctx.getGeocodingLookupService().lookupAddress(lookupRequest); app.getGeocodingLookupService().lookupAddress(lookupRequest);
} }
} }
@ -234,7 +161,7 @@ public class MapMarkersHelper {
private void cancelPointAddressRequests(LatLon latLon) { private void cancelPointAddressRequests(LatLon latLon) {
if (latLon != null) { if (latLon != null) {
ctx.getGeocodingLookupService().cancel(latLon); app.getGeocodingLookupService().cancel(latLon);
} }
} }
@ -263,7 +190,7 @@ public class MapMarkersHelper {
reorderActiveMarkersIfNeeded(); reorderActiveMarkersIfNeeded();
} }
private void sortMarkers(List<MapMarker> markers, final boolean visited, final @MapMarkersSortByDef int sortByMode) { public void sortMarkers(List<MapMarker> markers, final boolean visited, final @MapMarkersSortByDef int sortByMode) {
sortMarkers(markers, visited, sortByMode, null); sortMarkers(markers, visited, sortByMode, null);
} }
@ -295,92 +222,15 @@ public class MapMarkersHelper {
return sortByMode == BY_DISTANCE_DESC ? 1 : -1; return sortByMode == BY_DISTANCE_DESC ? 1 : -1;
} }
} else { } else {
String n1 = mapMarker1.getName(ctx); String n1 = mapMarker1.getName(app);
String n2 = mapMarker2.getName(ctx); String n2 = mapMarker2.getName(app);
return n1.compareToIgnoreCase(n2); return n1.compareToIgnoreCase(n2);
} }
} }
}); });
} }
public void runSynchronization(final @NonNull MapMarkersGroup group) { public void addHistoryMarkersToGroup(@NonNull ItineraryGroup group) {
ctx.runInUIThread(new Runnable() {
@Override
public void run() {
new SyncGroupTask(group).executeOnExecutor(executorService);
}
});
}
public MapMarkersGroup getMarkersGroup(GPXFile gpx) {
if (gpx == null || gpx.path == null) {
return null;
}
return getMapMarkerGroupById(getMarkerGroupId(new File(gpx.path)), MapMarkersGroup.GPX_TYPE);
}
public MapMarkersGroup getMarkersGroup(FavoriteGroup favGroup) {
return getMapMarkerGroupById(getMarkerGroupId(favGroup), MapMarkersGroup.FAVORITES_TYPE);
}
public MapMarkersGroup addOrEnableGpxGroup(@NonNull File file) {
updateGpxShowAsMarkers(file);
MapMarkersGroup gr = getMapMarkerGroupById(getMarkerGroupId(file), MapMarkersGroup.GPX_TYPE);
if (gr == null) {
gr = createGPXMarkerGroup(file);
addGroupInternally(gr);
}
enableGroup(gr);
return gr;
}
public MapMarkersGroup addOrEnableGroup(@NonNull GPXFile file) {
updateGpxShowAsMarkers(new File(file.path));
MapMarkersGroup gr = getMarkersGroup(file);
if (gr == null) {
gr = createGPXMarkerGroup(new File(file.path));
addGroupInternally(gr);
}
enableGroup(gr);
return gr;
}
public MapMarkersGroup addOrEnableGroup(@NonNull FavoriteGroup group) {
MapMarkersGroup gr = getMarkersGroup(group);
if (gr == null) {
gr = createFavMarkerGroup(group);
addGroupInternally(gr);
}
enableGroup(gr);
return gr;
}
public void enableGroup(@NonNull MapMarkersGroup gr) {
// check if group doesn't exist internally
if (!mapMarkersGroups.contains(gr)) {
addGroupInternally(gr);
}
if (gr.isDisabled()) {
updateGroupDisabled(gr, false);
}
runSynchronization(gr);
}
private void addGroupInternally(MapMarkersGroup gr) {
markersDbHelper.addGroup(gr);
addHistoryMarkersToGroup(gr);
addToGroupsList(gr);
}
private void updateGpxShowAsMarkers(File file) {
GPXDatabase.GpxDataItem dataItem = ctx.getGpxDbHelper().getItem(file);
if (dataItem != null) {
ctx.getGpxDbHelper().updateShowAsMarkers(dataItem, true);
dataItem.setShowAsMarkers(true);
}
}
private void addHistoryMarkersToGroup(@NonNull MapMarkersGroup group) {
List<MapMarker> historyMarkers = new ArrayList<>(mapMarkersHistory); List<MapMarker> historyMarkers = new ArrayList<>(mapMarkersHistory);
for (MapMarker m : historyMarkers) { for (MapMarker m : historyMarkers) {
if (m.groupKey != null && group.getId() != null && m.groupKey.equals(group.getId())) { if (m.groupKey != null && group.getId() != null && m.groupKey.equals(group.getId())) {
@ -389,33 +239,15 @@ public class MapMarkersHelper {
} }
} }
public void removeMarkersGroup(MapMarkersGroup group) { public void removeMarkersGroup(ItineraryGroup group) {
if (group != null) { if (group != null) {
markersDbHelper.removeMarkersGroup(group.getId()); markersDbHelper.removeMarkersGroup(group.getId());
removeGroupActiveMarkers(group, false); removeGroupActiveMarkers(group, false);
removeFromGroupsList(group); app.getItineraryHelper().removeFromGroupsList(group);
} }
} }
public void updateGroupDisabled(@NonNull MapMarkersGroup group, boolean disabled) { public void removeGroupActiveMarkers(ItineraryGroup group, boolean updateGroup) {
String id = group.getId();
if (id != null) {
markersDbHelper.updateGroupDisabled(id, disabled);
group.setDisabled(disabled);
}
}
public void updateGroupWptCategories(@NonNull MapMarkersGroup group, Set<String> wptCategories) {
String id = group.getId();
if (id != null) {
group.setWptCategories(wptCategories);
if (wptCategories != null) {
markersDbHelper.updateGroupCategories(id, group.getWptCategoriesString());
}
}
}
private void removeGroupActiveMarkers(MapMarkersGroup group, boolean updateGroup) {
if (group != null) { if (group != null) {
markersDbHelper.removeActiveMarkersFromGroup(group.getId()); markersDbHelper.removeActiveMarkersFromGroup(group.getId());
removeFromMapMarkersList(group.getActiveMarkers()); removeFromMapMarkersList(group.getActiveMarkers());
@ -428,27 +260,21 @@ public class MapMarkersHelper {
} }
} }
public void updateGroups() { public void updateGroup(ItineraryGroup itineraryGroup) {
for (MapMarkersGroup group : mapMarkersGroups) { if (itineraryGroup.getId() == null || itineraryGroup.getName() == null) {
updateGroup(group);
}
}
public void updateGroup(MapMarkersGroup mapMarkersGroup) {
if (mapMarkersGroup.getId() == null || mapMarkersGroup.getName() == null) {
return; return;
} }
createHeadersInGroup(mapMarkersGroup); createHeadersInGroup(itineraryGroup);
int historyMarkersCount = mapMarkersGroup.getHistoryMarkers().size(); int historyMarkersCount = itineraryGroup.getHistoryMarkers().size();
ShowHideHistoryButton showHideHistoryButton = mapMarkersGroup.getShowHideHistoryButton(); ShowHideHistoryButton showHideHistoryButton = itineraryGroup.getShowHideHistoryButton();
if (showHideHistoryButton != null) { if (showHideHistoryButton != null) {
if (historyMarkersCount == 0) { if (historyMarkersCount == 0) {
mapMarkersGroup.setShowHideHistoryButton(null); itineraryGroup.setShowHideHistoryButton(null);
} }
} else if (historyMarkersCount > 0) { } else if (historyMarkersCount > 0) {
showHideHistoryButton = new ShowHideHistoryButton(); showHideHistoryButton = new ShowHideHistoryButton();
showHideHistoryButton.showHistory = false; showHideHistoryButton.showHistory = false;
mapMarkersGroup.setShowHideHistoryButton(showHideHistoryButton); itineraryGroup.setShowHideHistoryButton(showHideHistoryButton);
} }
} }
@ -460,124 +286,38 @@ public class MapMarkersHelper {
private void addMarkerToGroup(MapMarker marker) { private void addMarkerToGroup(MapMarker marker) {
if (marker != null) { if (marker != null) {
MapMarkersGroup mapMarkersGroup = getMapMarkerGroupById(marker.groupKey, marker.getType()); ItineraryGroup itineraryGroup = app.getItineraryHelper().getMapMarkerGroupById(marker.groupKey, marker.getType());
if (mapMarkersGroup != null) { if (itineraryGroup != null) {
mapMarkersGroup.getMarkers().add(marker); itineraryGroup.getMarkers().add(marker);
updateGroup(mapMarkersGroup); updateGroup(itineraryGroup);
if (mapMarkersGroup.getName() == null) { if (itineraryGroup.getName() == null) {
sortMarkers(mapMarkersGroup.getMarkers(), false, BY_DATE_ADDED_DESC); sortMarkers(itineraryGroup.getMarkers(), false, BY_DATE_ADDED_DESC);
} }
} else { } else {
mapMarkersGroup = new MapMarkersGroup(marker.groupKey, marker.groupName, MapMarkersGroup.ANY_TYPE); itineraryGroup = new ItineraryGroup(marker.groupKey, marker.groupName, ItineraryGroup.ANY_TYPE);
mapMarkersGroup.setCreationDate(Long.MAX_VALUE); itineraryGroup.setCreationDate(Long.MAX_VALUE);
mapMarkersGroup.getMarkers().add(marker); itineraryGroup.getMarkers().add(marker);
addToGroupsList(mapMarkersGroup); app.getItineraryHelper().addToGroupsList(itineraryGroup);
sortGroups(); app.getItineraryHelper().sortGroups();
updateGroup(mapMarkersGroup); updateGroup(itineraryGroup);
} }
} }
} }
private void createHeadersInGroup(@NonNull MapMarkersGroup group) { public void createHeadersInGroup(@NonNull ItineraryGroup group) {
int type = group.getType(); int type = group.getType();
int headerIconId = 0; int headerIconId = 0;
int subHeaderIconId = 0;
if (type != -1) { if (type != -1) {
headerIconId = type == MapMarkersGroup.FAVORITES_TYPE headerIconId = type == ItineraryGroup.FAVORITES_TYPE
? R.drawable.ic_action_favorite : R.drawable.ic_action_polygom_dark; ? R.drawable.ic_action_favorite : R.drawable.ic_action_polygom_dark;
subHeaderIconId = R.drawable.ic_action_filter;
} }
GroupHeader header = new GroupHeader(headerIconId, group); GroupHeader header = new GroupHeader(headerIconId, group);
CategoriesSubHeader categoriesSubHeader = new CategoriesSubHeader(subHeaderIconId, group);
group.setHeader(header); group.setHeader(header);
} group.setCategoriesSubHeader(categoriesSubHeader);
private void removeMarkerFromGroup(MapMarker marker) {
if (marker != null) {
MapMarkersGroup mapMarkersGroup = getMapMarkerGroupById(marker.groupKey, marker.getType());
if (mapMarkersGroup != null) {
mapMarkersGroup.getMarkers().remove(marker);
updateGroup(mapMarkersGroup);
}
}
}
private void sortGroups() {
if (mapMarkersGroups.size() > 0) {
Collections.sort(mapMarkersGroups, new Comparator<MapMarkersGroup>() {
@Override
public int compare(MapMarkersGroup group1, MapMarkersGroup group2) {
long t1 = group1.getCreationDate();
long t2 = group2.getCreationDate();
return (t1 > t2) ? -1 : ((t1 == t2) ? 0 : 1);
}
});
}
}
@Nullable
public MapMarkersGroup getMapMarkerGroupById(String id, int type) {
for (MapMarkersGroup group : mapMarkersGroups) {
if ((id == null && group.getId() == null)
|| (group.getId() != null && group.getId().equals(id))) {
if (type == MapMarkersGroup.ANY_TYPE || type == group.getType()) {
return group;
}
}
}
return null;
}
private MapMarkersGroup createGPXMarkerGroup(File fl) {
return new MapMarkersGroup(getMarkerGroupId(fl),
Algorithms.getFileNameWithoutExtension(fl.getName()),
MapMarkersGroup.GPX_TYPE);
}
private MapMarkersGroup createFavMarkerGroup(FavoriteGroup favGroup) {
return new MapMarkersGroup(favGroup.getName(), favGroup.getName(), MapMarkersGroup.FAVORITES_TYPE);
}
private String getMarkerGroupId(File gpx) {
return gpx.getAbsolutePath();
}
private String getMarkerGroupId(FavoriteGroup group) {
return group.getName();
}
@NonNull
public List<MapMarkersGroup> getGroupsForDisplayedGpx() {
List<MapMarkersGroup> res = new ArrayList<>();
List<SelectedGpxFile> selectedGpxFiles = ctx.getSelectedGpxHelper().getSelectedGPXFiles();
for (SelectedGpxFile selected : selectedGpxFiles) {
MapMarkersGroup search = getMarkersGroup(selected.getGpxFile());
if (search == null && selected.getGpxFile() != null && selected.getGpxFile().path != null) {
MapMarkersGroup group = createGPXMarkerGroup(new File(selected.getGpxFile().path));
group.setDisabled(true);
createHeadersInGroup(group);
res.add(group);
}
}
return res;
}
@NonNull
public List<MapMarkersGroup> getGroupsForSavedArticlesTravelBook() {
List<MapMarkersGroup> res = new ArrayList<>();
TravelHelper travelHelper = ctx.getTravelHelper();
if (travelHelper.isAnyTravelBookPresent()) {
List<TravelArticle> savedArticles = travelHelper.getBookmarksHelper().getSavedArticles();
for (TravelArticle art : savedArticles) {
String gpxName = travelHelper.getGPXName(art);
File path = ctx.getAppPath(IndexConstants.GPX_TRAVEL_DIR + gpxName);
MapMarkersGroup search = getMapMarkerGroupById(getMarkerGroupId(path), MapMarkersGroup.GPX_TYPE);
if (search == null) {
MapMarkersGroup group = createGPXMarkerGroup(path);
group.setDisabled(true);
createHeadersInGroup(group);
res.add(group);
}
}
}
return res;
} }
@Nullable @Nullable
@ -612,7 +352,7 @@ public class MapMarkersHelper {
private List<MapMarker> getMarkers() { private List<MapMarker> getMarkers() {
List<MapMarker> res = new ArrayList<>(mapMarkers); List<MapMarker> res = new ArrayList<>(mapMarkers);
if (ctx.getSettings().KEEP_PASSED_MARKERS_ON_MAP.get()) { if (app.getSettings().KEEP_PASSED_MARKERS_ON_MAP.get()) {
res.addAll(mapMarkersHistory); res.addAll(mapMarkersHistory);
} }
return res; return res;
@ -631,7 +371,7 @@ public class MapMarkersHelper {
return null; return null;
} }
private void addNewMarkerIfNeeded(@NonNull MapMarkersGroup group, public void addNewMarkerIfNeeded(@NonNull ItineraryGroup group,
@NonNull List<MapMarker> groupMarkers, @NonNull List<MapMarker> groupMarkers,
@NonNull LatLon latLon, @NonNull LatLon latLon,
@NonNull String name, @NonNull String name,
@ -666,7 +406,7 @@ public class MapMarkersHelper {
} }
} }
private void removeOldMarkersIfPresent(List<MapMarker> markers) { public void removeOldMarkersIfPresent(List<MapMarker> markers) {
if (!markers.isEmpty()) { if (!markers.isEmpty()) {
boolean needRefresh = false; boolean needRefresh = false;
for (MapMarker marker : markers) { for (MapMarker marker : markers) {
@ -733,7 +473,7 @@ public class MapMarkersHelper {
addToMapMarkersList(markers); addToMapMarkersList(markers);
reorderActiveMarkersIfNeeded(); reorderActiveMarkersIfNeeded();
sortMarkers(mapMarkersHistory, true, BY_DATE_ADDED_DESC); sortMarkers(mapMarkersHistory, true, BY_DATE_ADDED_DESC);
updateGroups(); app.getItineraryHelper().updateGroups();
refresh(); refresh();
} }
} }
@ -750,7 +490,7 @@ public class MapMarkersHelper {
} else { } else {
removeFromMapMarkersList(marker); removeFromMapMarkersList(marker);
} }
removeMarkerFromGroup(marker); app.getItineraryHelper().removeMarkerFromGroup(marker);
if (refresh) { if (refresh) {
refresh(); refresh();
} }
@ -847,7 +587,7 @@ public class MapMarkersHelper {
addToMapMarkersHistoryList(mapMarkers); addToMapMarkersHistoryList(mapMarkers);
mapMarkers = new ArrayList<>(); mapMarkers = new ArrayList<>();
sortMarkers(mapMarkersHistory, true, BY_DATE_ADDED_DESC); sortMarkers(mapMarkersHistory, true, BY_DATE_ADDED_DESC);
updateGroups(); app.getItineraryHelper().updateGroups();
refresh(); refresh();
} }
@ -868,18 +608,18 @@ public class MapMarkersHelper {
public void addMapMarkers(@NonNull List<LatLon> points, public void addMapMarkers(@NonNull List<LatLon> points,
@NonNull List<PointDescription> historyNames, @NonNull List<PointDescription> historyNames,
@Nullable MapMarkersGroup group) { @Nullable ItineraryGroup group) {
addMarkers(points, historyNames, group, null, null, null); addMarkers(points, historyNames, group, null, null, null);
} }
private void addMarkers(@NonNull List<LatLon> points, private void addMarkers(@NonNull List<LatLon> points,
@NonNull List<PointDescription> historyNames, @NonNull List<PointDescription> historyNames,
@Nullable MapMarkersGroup group, @Nullable ItineraryGroup group,
@Nullable List<FavouritePoint> favouritePoints, @Nullable List<FavouritePoint> favouritePoints,
@Nullable List<WptPt> wptPts, @Nullable List<WptPt> wptPts,
@Nullable List<String> mapObjNames) { @Nullable List<String> mapObjNames) {
if (points.size() > 0) { if (points.size() > 0) {
ctx.getSettings().SHOW_MAP_MARKERS.set(true); app.getSettings().SHOW_MAP_MARKERS.set(true);
int colorIndex = -1; int colorIndex = -1;
List<MapMarker> addedMarkers = new ArrayList<>(); List<MapMarker> addedMarkers = new ArrayList<>();
for (int i = 0; i < points.size(); i++) { for (int i = 0; i < points.size(); i++) {
@ -895,7 +635,7 @@ public class MapMarkersHelper {
pointDescription = historyName; pointDescription = historyName;
} }
if (pointDescription.isLocation() && Algorithms.isEmpty(pointDescription.getName())) { if (pointDescription.isLocation() && Algorithms.isEmpty(pointDescription.getName())) {
pointDescription.setName(PointDescription.getSearchAddressStr(ctx)); pointDescription.setName(PointDescription.getSearchAddressStr(app));
} }
if (colorIndex == -1) { if (colorIndex == -1) {
if (mapMarkers.size() > 0) { if (mapMarkers.size() > 0) {
@ -909,7 +649,7 @@ public class MapMarkersHelper {
MapMarker marker = new MapMarker(point, pointDescription, colorIndex, false, 0); MapMarker marker = new MapMarker(point, pointDescription, colorIndex, false, 0);
if (group != null) { if (group != null) {
marker.id = group.getId() + marker.getName(ctx) + MapUtils.createShortLinkString(marker.point.getLatitude(), marker.point.getLongitude(), 15); marker.id = group.getId() + marker.getName(app) + MapUtils.createShortLinkString(marker.point.getLatitude(), marker.point.getLongitude(), 15);
if (markersDbHelper.getMarker(marker.id) != null) { if (markersDbHelper.getMarker(marker.id) != null) {
continue; continue;
} }
@ -965,14 +705,6 @@ public class MapMarkersHelper {
} }
} }
public void addSyncListener(OnGroupSyncedListener listener) {
syncListeners.add(listener);
}
public void removeSyncListener(OnGroupSyncedListener listener) {
syncListeners.remove(listener);
}
public void addListener(MapMarkerChangedListener l) { public void addListener(MapMarkerChangedListener l) {
if (!listeners.contains(l)) { if (!listeners.contains(l)) {
listeners.add(l); listeners.add(l);
@ -984,7 +716,7 @@ public class MapMarkersHelper {
} }
private void refreshMarker(final MapMarker marker) { private void refreshMarker(final MapMarker marker) {
ctx.runInUIThread(new Runnable() { app.runInUIThread(new Runnable() {
@Override @Override
public void run() { public void run() {
for (MapMarkerChangedListener l : listeners) { for (MapMarkerChangedListener l : listeners) {
@ -995,7 +727,7 @@ public class MapMarkersHelper {
} }
private void refresh() { private void refresh() {
ctx.runInUIThread(new Runnable() { app.runInUIThread(new Runnable() {
@Override @Override
public void run() { public void run() {
for (MapMarkerChangedListener l : listeners) { for (MapMarkerChangedListener l : listeners) {
@ -1005,28 +737,14 @@ public class MapMarkersHelper {
}); });
} }
public List<MapMarker> getMapMarkersFromDefaultGroups(boolean history) {
List<MapMarker> mapMarkers = new ArrayList<>();
for (MapMarkersGroup group : mapMarkersGroups) {
if (group.getType() == MapMarkersGroup.ANY_TYPE) {
for (MapMarker marker : group.getMarkers()) {
if (history && marker.history || !history && !marker.history) {
mapMarkers.add(marker);
}
}
}
}
return mapMarkers;
}
public String saveMarkersToFile(String fileName) { public String saveMarkersToFile(String fileName) {
GPXFile gpxFile = generateGpx(); GPXFile gpxFile = generateGpx();
String dirName = IndexConstants.GPX_INDEX_DIR + IndexConstants.MAP_MARKERS_INDEX_DIR; String dirName = IndexConstants.GPX_INDEX_DIR + IndexConstants.MAP_MARKERS_INDEX_DIR;
File dir = ctx.getAppPath(dirName); File dir = app.getAppPath(dirName);
if (!dir.exists()) { if (!dir.exists()) {
dir.mkdirs(); dir.mkdirs();
} }
String uniqueFileName = FileUtils.createUniqueFileName(ctx, fileName, dirName, IndexConstants.GPX_FILE_EXT); String uniqueFileName = FileUtils.createUniqueFileName(app, fileName, dirName, IndexConstants.GPX_FILE_EXT);
File fout = new File(dir, uniqueFileName + IndexConstants.GPX_FILE_EXT); File fout = new File(dir, uniqueFileName + IndexConstants.GPX_FILE_EXT);
GPXUtilities.writeGpxFile(fout, gpxFile); GPXUtilities.writeGpxFile(fout, gpxFile);
@ -1041,13 +759,13 @@ public class MapMarkersHelper {
SimpleDateFormat format = new SimpleDateFormat(GPX_TIME_FORMAT, Locale.US); SimpleDateFormat format = new SimpleDateFormat(GPX_TIME_FORMAT, Locale.US);
format.setTimeZone(TimeZone.getTimeZone("UTC")); format.setTimeZone(TimeZone.getTimeZone("UTC"));
GPXFile gpxFile = new GPXFile(Version.getFullVersion(ctx)); GPXFile gpxFile = new GPXFile(Version.getFullVersion(app));
for (MapMarker marker : markers) { for (MapMarker marker : markers) {
WptPt wpt = new WptPt(); WptPt wpt = new WptPt();
wpt.lat = marker.getLatitude(); wpt.lat = marker.getLatitude();
wpt.lon = marker.getLongitude(); wpt.lon = marker.getLongitude();
wpt.name = marker.getOnlyName(); wpt.name = marker.getOnlyName();
wpt.setColor(ContextCompat.getColor(ctx, MapMarker.getColorId(marker.colorIndex))); wpt.setColor(ContextCompat.getColor(app, MapMarker.getColorId(marker.colorIndex)));
if (completeBackup) { if (completeBackup) {
if (marker.creationDate != 0) { if (marker.creationDate != 0) {
wpt.getExtensionsToWrite().put(CREATION_DATE, format.format(new Date(marker.creationDate))); wpt.getExtensionsToWrite().put(CREATION_DATE, format.format(new Date(marker.creationDate)));
@ -1068,7 +786,7 @@ public class MapMarkersHelper {
List<MapMarker> mapMarkers = new ArrayList<>(); List<MapMarker> mapMarkers = new ArrayList<>();
for (WptPt point : gpxFile.getPoints()) { for (WptPt point : gpxFile.getPoints()) {
LatLon latLon = new LatLon(point.lat, point.lon); LatLon latLon = new LatLon(point.lat, point.lon);
int colorIndex = MapMarker.getColorIndex(ctx, point.getColor()); int colorIndex = MapMarker.getColorIndex(app, point.getColor());
PointDescription name = new PointDescription(PointDescription.POINT_TYPE_LOCATION, point.name); PointDescription name = new PointDescription(PointDescription.POINT_TYPE_LOCATION, point.name);
MapMarker marker = new MapMarker(latLon, name, colorIndex, false, 0); MapMarker marker = new MapMarker(latLon, name, colorIndex, false, 0);
@ -1159,22 +877,6 @@ public class MapMarkersHelper {
mapMarkersHistory = copyList; mapMarkersHistory = copyList;
} }
// accessors to markers groups:
private void addToGroupsList(MapMarkersGroup group) {
List<MapMarkersGroup> copyList = new ArrayList<>(mapMarkersGroups);
copyList.add(group);
mapMarkersGroups = copyList;
}
private void removeFromGroupsList(MapMarkersGroup group) {
List<MapMarkersGroup> copyList = new ArrayList<>(mapMarkersGroups);
copyList.remove(group);
mapMarkersGroups = copyList;
}
// ---------------------------------------------------------------------------------------------
// classes and interfaces: // classes and interfaces:
public interface MapMarkerChangedListener { public interface MapMarkerChangedListener {
@ -1189,93 +891,4 @@ public class MapMarkersHelper {
void onSyncDone(); void onSyncDone();
} }
private class SyncGroupTask extends AsyncTask<Void, Void, Void> {
private MapMarkersGroup group;
SyncGroupTask(MapMarkersGroup group) {
this.group = group;
}
@Override
protected void onPreExecute() {
if (!syncListeners.isEmpty()) {
ctx.runInUIThread(new Runnable() {
@Override
public void run() {
for (OnGroupSyncedListener listener : syncListeners) {
listener.onSyncStarted();
}
}
});
}
}
@Override
protected Void doInBackground(Void... voids) {
runGroupSynchronization();
return null;
}
// TODO extract method from Asynctask to Helper directly
private void runGroupSynchronization() {
List<MapMarker> groupMarkers = new ArrayList<>(group.getMarkers());
if (group.getType() == MapMarkersGroup.FAVORITES_TYPE) {
FavoriteGroup favGroup = ctx.getFavorites().getGroup(group.getName());
if (favGroup == null) {
return;
}
group.setVisible(favGroup.isVisible());
if (!group.isVisible() || group.isDisabled()) {
removeGroupActiveMarkers(group, true);
return;
}
List<FavouritePoint> points = new ArrayList<>(favGroup.getPoints());
for (FavouritePoint fp : points) {
addNewMarkerIfNeeded(group, groupMarkers, new LatLon(fp.getLatitude(), fp.getLongitude()), fp.getName(), fp, null);
}
} else if (group.getType() == MapMarkersGroup.GPX_TYPE) {
GpxSelectionHelper gpxHelper = ctx.getSelectedGpxHelper();
File file = new File(group.getId());
if (!file.exists()) {
return;
}
String gpxPath = group.getId();
SelectedGpxFile selectedGpxFile = gpxHelper.getSelectedFileByPath(gpxPath);
GPXFile gpx = selectedGpxFile == null ? null : selectedGpxFile.getGpxFile();
group.setVisible(gpx != null || group.isVisibleUntilRestart());
if (gpx == null || group.isDisabled()) {
removeGroupActiveMarkers(group, true);
return;
}
boolean addAll = group.getWptCategories() == null || group.getWptCategories().isEmpty();
List<WptPt> gpxPoints = new ArrayList<>(gpx.getPoints());
for (WptPt pt : gpxPoints) {
if (addAll || group.getWptCategories().contains(pt.category)
|| (pt.category == null && group.getWptCategories().contains(""))) {
addNewMarkerIfNeeded(group, groupMarkers, new LatLon(pt.lat, pt.lon), pt.name, null, pt);
}
}
}
removeOldMarkersIfPresent(groupMarkers);
}
@Override
protected void onPostExecute(Void aVoid) {
if (!syncListeners.isEmpty()) {
ctx.runInUIThread(new Runnable() {
@Override
public void run() {
for (OnGroupSyncedListener listener : syncListeners) {
listener.onSyncDone();
}
}
});
}
}
}
} }

View file

@ -20,6 +20,8 @@ import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithCompoundButton;
import net.osmand.plus.base.bottomsheetmenu.simpleitems.DividerItem; import net.osmand.plus.base.bottomsheetmenu.simpleitems.DividerItem;
import net.osmand.plus.base.bottomsheetmenu.simpleitems.ShortDescriptionItem; import net.osmand.plus.base.bottomsheetmenu.simpleitems.ShortDescriptionItem;
import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem; import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem;
import net.osmand.plus.itinerary.ItineraryGroup;
import net.osmand.plus.itinerary.ItineraryHelper;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
@ -136,18 +138,18 @@ public class SelectWptCategoriesBottomSheetDialogFragment extends MenuBottomShee
private void updateAddOrEnableGroupWptCategories() { private void updateAddOrEnableGroupWptCategories() {
OsmandApplication app = getMyApplication(); OsmandApplication app = getMyApplication();
GpxSelectionHelper gpxSelectionHelper = app.getSelectedGpxHelper(); GpxSelectionHelper gpxSelectionHelper = app.getSelectedGpxHelper();
MapMarkersHelper mapMarkersHelper = app.getMapMarkersHelper(); ItineraryHelper helper = app.getItineraryHelper();
SelectedGpxFile selectedGpxFile = gpxSelectionHelper.getSelectedFileByPath(gpxFile.path); SelectedGpxFile selectedGpxFile = gpxSelectionHelper.getSelectedFileByPath(gpxFile.path);
if (selectedGpxFile == null) { if (selectedGpxFile == null) {
gpxSelectionHelper.selectGpxFile(gpxFile, true, false, false, false, false); gpxSelectionHelper.selectGpxFile(gpxFile, true, false, false, false, false);
} }
MapMarkersGroup group = mapMarkersHelper.getMarkersGroup(gpxFile); ItineraryGroup group = helper.getMarkersGroup(gpxFile);
if (group == null) { if (group == null) {
group = mapMarkersHelper.addOrEnableGroup(gpxFile); group = helper.addOrEnableGroup(gpxFile);
} }
mapMarkersHelper.updateGroupWptCategories(group, selectedCategories); helper.updateGroupWptCategories(group, selectedCategories);
mapMarkersHelper.runSynchronization(group); helper.runSynchronization(group);
} }
private boolean isAllChecked() { private boolean isAllChecked() {

View file

@ -14,7 +14,7 @@ import com.google.android.material.snackbar.Snackbar;
import net.osmand.data.LatLon; import net.osmand.data.LatLon;
import net.osmand.plus.mapmarkers.MapMarker; import net.osmand.plus.mapmarkers.MapMarker;
import net.osmand.plus.mapmarkers.MapMarkersGroup; import net.osmand.plus.itinerary.ItineraryGroup;
import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmAndFormatter;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.UiUtilities; import net.osmand.plus.UiUtilities;
@ -214,8 +214,8 @@ public class MapMarkersActiveAdapter extends RecyclerView.Adapter<MapMarkerItemV
final int pos = holder.getAdapterPosition(); final int pos = holder.getAdapterPosition();
final MapMarker marker = getItem(pos); final MapMarker marker = getItem(pos);
mapActivity.getMyApplication().getMapMarkersHelper().moveMapMarkerToHistory(marker); mapActivity.getMyApplication().getMapMarkersHelper().moveMapMarkerToHistory(marker);
MapMarkersGroup group = mapActivity.getMyApplication().getMapMarkersHelper().getMapMarkerGroupById(marker.groupKey, ItineraryGroup group = mapActivity.getMyApplication().getItineraryHelper().getMapMarkerGroupById(marker.groupKey,
MapMarkersGroup.ANY_TYPE); ItineraryGroup.ANY_TYPE);
if (group != null) { if (group != null) {
mapActivity.getMyApplication().getMapMarkersHelper().updateGroup(group); mapActivity.getMyApplication().getMapMarkersHelper().updateGroup(group);
} }

View file

@ -7,10 +7,8 @@ import android.view.ViewGroup;
import android.widget.CompoundButton; import android.widget.CompoundButton;
import android.widget.ImageView; import android.widget.ImageView;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.appcompat.content.res.AppCompatResources; import androidx.appcompat.content.res.AppCompatResources;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
@ -23,10 +21,12 @@ import net.osmand.IndexConstants;
import net.osmand.data.LatLon; import net.osmand.data.LatLon;
import net.osmand.plus.GpxSelectionHelper; import net.osmand.plus.GpxSelectionHelper;
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile; import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
import net.osmand.plus.itinerary.ItineraryHelper;
import net.osmand.plus.mapmarkers.CategoriesSubHeader;
import net.osmand.plus.mapmarkers.MapMarkersHelper; import net.osmand.plus.mapmarkers.MapMarkersHelper;
import net.osmand.plus.mapmarkers.GroupHeader; import net.osmand.plus.mapmarkers.GroupHeader;
import net.osmand.plus.mapmarkers.MapMarker; import net.osmand.plus.mapmarkers.MapMarker;
import net.osmand.plus.mapmarkers.MapMarkersGroup; import net.osmand.plus.itinerary.ItineraryGroup;
import net.osmand.plus.mapmarkers.ShowHideHistoryButton; import net.osmand.plus.mapmarkers.ShowHideHistoryButton;
import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmAndFormatter;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
@ -38,7 +38,6 @@ import net.osmand.plus.mapmarkers.SelectWptCategoriesBottomSheetDialogFragment;
import net.osmand.plus.wikivoyage.article.WikivoyageArticleDialogFragment; import net.osmand.plus.wikivoyage.article.WikivoyageArticleDialogFragment;
import net.osmand.plus.wikivoyage.data.TravelArticle; import net.osmand.plus.wikivoyage.data.TravelArticle;
import net.osmand.plus.wikivoyage.data.TravelHelper; import net.osmand.plus.wikivoyage.data.TravelHelper;
import net.osmand.util.Algorithms;
import java.io.File; import java.io.File;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
@ -57,6 +56,10 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter<RecyclerView.V
private static final int SHOW_HIDE_HISTORY_TYPE = 3; private static final int SHOW_HIDE_HISTORY_TYPE = 3;
private static final int CATEGORIES_TYPE = 4; private static final int CATEGORIES_TYPE = 4;
private static final int TODAY_HEADER = 56;
private static final int YESTERDAY_HEADER = 57;
private static final int LAST_SEVEN_DAYS_HEADER = 58;
private static final int THIS_YEAR_HEADER = 59;
private MapActivity mapActivity; private MapActivity mapActivity;
private OsmandApplication app; private OsmandApplication app;
@ -101,90 +104,55 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter<RecyclerView.V
private void createDisplayGroups() { private void createDisplayGroups() {
items = new ArrayList<>(); items = new ArrayList<>();
MapMarkersHelper helper = app.getMapMarkersHelper(); ItineraryHelper helper = app.getItineraryHelper();
helper.updateGroups(); helper.updateGroups();
List<MapMarkersGroup> groups = new ArrayList<>(helper.getMapMarkersGroups()); List<ItineraryGroup> groups = new ArrayList<>(helper.getItineraryGroups());
groups.addAll(helper.getGroupsForDisplayedGpx()); groups.addAll(helper.getGroupsForDisplayedGpx());
groups.addAll(helper.getGroupsForSavedArticlesTravelBook()); groups.addAll(helper.getGroupsForSavedArticlesTravelBook());
// evaluate time constants
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
long currentTimeMillis = System.currentTimeMillis();
Calendar currentDateCalendar = Calendar.getInstance();
currentDateCalendar.setTimeInMillis(currentTimeMillis);
// evaluate today, yesterday, last 7 days
String today = dateFormat.format(currentDateCalendar.getTime());
currentDateCalendar.add(Calendar.DAY_OF_YEAR, -1);
String yesterday = dateFormat.format(currentDateCalendar.getTime());
currentDateCalendar.set(Calendar.HOUR_OF_DAY, 0);
currentDateCalendar.set(Calendar.MINUTE, 0);
currentDateCalendar.add(Calendar.DAY_OF_YEAR, -6);
long last7Days = currentDateCalendar.getTimeInMillis();
// evaluate this year & last 3 months
currentDateCalendar.setTimeInMillis(currentTimeMillis);
String thisYear = dateFormat.format(currentDateCalendar.getTime()).substring(0, 5);
currentDateCalendar.add(Calendar.MONTH, -1);
String monthMinus1 = dateFormat.format(currentDateCalendar.getTime()).substring(0, 8);
currentDateCalendar.add(Calendar.MONTH, -1);
String monthMinus2 = dateFormat.format(currentDateCalendar.getTime()).substring(0, 8);
currentDateCalendar.add(Calendar.MONTH, -1);
String monthMinus3 = dateFormat.format(currentDateCalendar.getTime()).substring(0, 8);
Calendar markerCalendar = Calendar.getInstance();
for (int i = 0; i < groups.size(); i++) { for (int i = 0; i < groups.size(); i++) {
MapMarkersGroup group = groups.get(i); ItineraryGroup group = groups.get(i);
if (!group.isVisible()) { if (!group.isVisible()) {
continue; continue;
} }
String markerGroupName = group.getName(); String markerGroupName = group.getName();
if (markerGroupName == null) { if (markerGroupName == null) {
int previousGroupDateId = 0; int previousDateHeader = -1;
int monthsDisplayed = 0; int monthsDisplayed = 0;
Calendar currentDateCalendar = Calendar.getInstance();
currentDateCalendar.setTimeInMillis(System.currentTimeMillis());
int currentDay = currentDateCalendar.get(Calendar.DAY_OF_YEAR);
int currentMonth = currentDateCalendar.get(Calendar.MONTH);
int currentYear = currentDateCalendar.get(Calendar.YEAR);
Calendar markerCalendar = Calendar.getInstance();
List<MapMarker> groupMarkers = group.getActiveMarkers(); List<MapMarker> groupMarkers = group.getActiveMarkers();
for (int j = 0; j < groupMarkers.size(); j++) { for (int j = 0; j < groupMarkers.size(); j++) {
MapMarker marker = groupMarkers.get(j); MapMarker marker = groupMarkers.get(j);
String markerDate = dateFormat.format(new Date(marker.creationDate));
int currentGroupDateId;
MarkerGroupItem currentGroupItem = null ;
if (marker.creationDate >= currentTimeMillis || (today.equals(markerDate))) {
currentGroupDateId = -1;
currentGroupItem = MarkerGroupItem.TODAY_HEADER;
} else if (yesterday.equals(markerDate)) {
currentGroupDateId = -2;
currentGroupItem = MarkerGroupItem.YESTERDAY_HEADER;
} else if (marker.creationDate >= last7Days) {
currentGroupDateId = -3;
currentGroupItem = MarkerGroupItem.LAST_SEVEN_DAYS_HEADER;
} else if (markerDate.startsWith(monthMinus1)) {
currentGroupDateId = -5;
} else if (markerDate.startsWith(monthMinus2)) {
currentGroupDateId = -6;
} else if (markerDate.startsWith(monthMinus3)) {
currentGroupDateId = -7;
} else if (markerDate.startsWith(thisYear)) {
currentGroupItem = MarkerGroupItem.THIS_YEAR_HEADER;
currentGroupDateId = -4;
} else {
markerCalendar.setTimeInMillis(marker.creationDate); markerCalendar.setTimeInMillis(marker.creationDate);
currentGroupDateId = markerCalendar.get(Calendar.YEAR); int markerDay = markerCalendar.get(Calendar.DAY_OF_YEAR);
int markerMonth = markerCalendar.get(Calendar.MONTH);
int markerYear = markerCalendar.get(Calendar.YEAR);
if (markerYear == currentYear) {
if (markerDay == currentDay && previousDateHeader != TODAY_HEADER) {
items.add(TODAY_HEADER);
previousDateHeader = TODAY_HEADER;
} else if (markerDay == currentDay - 1 && previousDateHeader != YESTERDAY_HEADER) {
items.add(YESTERDAY_HEADER);
previousDateHeader = YESTERDAY_HEADER;
} else if (currentDay - markerDay >= 2 && currentDay - markerDay <= 8 && previousDateHeader != LAST_SEVEN_DAYS_HEADER) {
items.add(LAST_SEVEN_DAYS_HEADER);
previousDateHeader = LAST_SEVEN_DAYS_HEADER;
} else if (currentDay - markerDay > 8 && monthsDisplayed < 3 && previousDateHeader != markerMonth) {
items.add(markerMonth);
previousDateHeader = markerMonth;
monthsDisplayed += 1;
} else if (currentMonth - markerMonth >= 4 && previousDateHeader != markerMonth && previousDateHeader != THIS_YEAR_HEADER) {
items.add(THIS_YEAR_HEADER);
previousDateHeader = THIS_YEAR_HEADER;
} }
if (previousGroupDateId != currentGroupDateId) { } else if (previousDateHeader != markerYear) {
if (currentGroupItem != null) { items.add(markerYear);
items.add(currentGroupItem); previousDateHeader = markerYear;
} else if(currentGroupDateId < 0) {
SimpleDateFormat monthdateFormat = new SimpleDateFormat("LLLL", Locale.getDefault());
String monthStr = monthdateFormat.format(new Date(marker.creationDate));
if (monthStr.length() > 1) {
monthStr = Algorithms.capitalizeFirstLetter(monthStr);
}
items.add(new MarkerGroupItem(monthStr));
} else {
items.add(new MarkerGroupItem(currentGroupDateId + ""));
}
previousGroupDateId = currentGroupDateId;
} }
items.add(marker); items.add(marker);
} }
@ -193,7 +161,7 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter<RecyclerView.V
items.add(header); items.add(header);
if (!group.isDisabled()) { if (!group.isDisabled()) {
if (group.getWptCategories() != null && !group.getWptCategories().isEmpty()) { if (group.getWptCategories() != null && !group.getWptCategories().isEmpty()) {
CategoriesSubHeader categoriesSubHeader = new CategoriesSubHeader(group); CategoriesSubHeader categoriesSubHeader = group.getCategoriesSubHeader();
items.add(categoriesSubHeader); items.add(categoriesSubHeader);
} }
TravelHelper travelHelper = mapActivity.getMyApplication().getTravelHelper(); TravelHelper travelHelper = mapActivity.getMyApplication().getTravelHelper();
@ -209,7 +177,7 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter<RecyclerView.V
} }
} }
if (group.getWptCategories() == null || group.getWptCategories().isEmpty()) { if (group.getWptCategories() == null || group.getWptCategories().isEmpty()) {
helper.updateGroupWptCategories(group, getGpxFile(group.getGpxPath()).getPointsByCategories().keySet()); app.getItineraryHelper().updateGroupWptCategories(group, getGpxFile(group.getGpxPath()).getPointsByCategories().keySet());
} }
populateAdapterWithGroupMarkers(group, getItemCount()); populateAdapterWithGroupMarkers(group, getItemCount());
} }
@ -228,7 +196,7 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter<RecyclerView.V
return null; return null;
} }
private void populateAdapterWithGroupMarkers(MapMarkersGroup group, int position) { private void populateAdapterWithGroupMarkers(ItineraryGroup group, int position) {
if (position != RecyclerView.NO_POSITION) { if (position != RecyclerView.NO_POSITION) {
ShowHideHistoryButton showHideHistoryButton = group.getShowHideHistoryButton(); ShowHideHistoryButton showHideHistoryButton = group.getShowHideHistoryButton();
if (!group.isDisabled()) { if (!group.isDisabled()) {
@ -253,7 +221,7 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter<RecyclerView.V
public int getGroupHeaderPosition(String groupId) { public int getGroupHeaderPosition(String groupId) {
int pos = -1; int pos = -1;
MapMarkersGroup group = app.getMapMarkersHelper().getMapMarkerGroupById(groupId, MapMarkersGroup.ANY_TYPE); ItineraryGroup group = app.getItineraryHelper().getMapMarkerGroupById(groupId, ItineraryGroup.ANY_TYPE);
if (group != null) { if (group != null) {
pos = items.indexOf(group.getGroupHeader()); pos = items.indexOf(group.getGroupHeader());
} }
@ -413,19 +381,32 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter<RecyclerView.V
final MapMarkerHeaderViewHolder headerViewHolder = (MapMarkerHeaderViewHolder) holder; final MapMarkerHeaderViewHolder headerViewHolder = (MapMarkerHeaderViewHolder) holder;
final Object header = getItem(position); final Object header = getItem(position);
String headerString; String headerString;
if (header instanceof MarkerGroupItem) { if (header instanceof Integer) {
headerViewHolder.icon.setVisibility(View.GONE); headerViewHolder.icon.setVisibility(View.GONE);
headerViewHolder.iconSpace.setVisibility(View.VISIBLE); headerViewHolder.iconSpace.setVisibility(View.VISIBLE);
headerString = ((MarkerGroupItem) header).getName(app); Integer dateHeader = (Integer) header;
if (dateHeader == TODAY_HEADER) {
headerString = app.getString(R.string.today);
} else if (dateHeader == YESTERDAY_HEADER) {
headerString = app.getString(R.string.yesterday);
} else if (dateHeader == LAST_SEVEN_DAYS_HEADER) {
headerString = app.getString(R.string.last_seven_days);
} else if (dateHeader == THIS_YEAR_HEADER) {
headerString = app.getString(R.string.this_year);
} else if (dateHeader / 100 == 0) {
headerString = getMonth(dateHeader);
} else {
headerString = String.valueOf(dateHeader);
}
headerViewHolder.disableGroupSwitch.setVisibility(View.GONE); headerViewHolder.disableGroupSwitch.setVisibility(View.GONE);
headerViewHolder.articleDescription.setVisibility(View.GONE); headerViewHolder.articleDescription.setVisibility(View.GONE);
} else if (header instanceof GroupHeader) { } else if (header instanceof GroupHeader) {
final GroupHeader groupHeader = (GroupHeader) header; final GroupHeader groupHeader = (GroupHeader) header;
final MapMarkersGroup group = groupHeader.getGroup(); final ItineraryGroup group = groupHeader.getGroup();
String groupName = group.getName(); String groupName = group.getName();
if (groupName.isEmpty()) { if (groupName.isEmpty()) {
groupName = app.getString(R.string.shared_string_favorites); groupName = app.getString(R.string.shared_string_favorites);
} else if (group.getType() == MapMarkersGroup.GPX_TYPE) { } else if (group.getType() == ItineraryGroup.GPX_TYPE) {
groupName = groupName.replace(IndexConstants.GPX_FILE_EXT, "").replace("/", " ").replace("_", " "); groupName = groupName.replace(IndexConstants.GPX_FILE_EXT, "").replace("/", " ").replace("_", " ");
} }
if (group.isDisabled()) { if (group.isDisabled()) {
@ -482,8 +463,8 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter<RecyclerView.V
fragment.setUsedOnMap(false); fragment.setUsedOnMap(false);
fragment.show(mapActivity.getSupportFragmentManager(), SelectWptCategoriesBottomSheetDialogFragment.TAG); fragment.show(mapActivity.getSupportFragmentManager(), SelectWptCategoriesBottomSheetDialogFragment.TAG);
} }
mapMarkersHelper.updateGroupDisabled(group, disabled); app.getItineraryHelper().updateGroupDisabled(group, disabled);
if (group.getType() == MapMarkersGroup.GPX_TYPE) { if (group.getType() == ItineraryGroup.GPX_TYPE) {
group.setVisibleUntilRestart(disabled); group.setVisibleUntilRestart(disabled);
String gpxPath = group.getGpxPath(); String gpxPath = group.getGpxPath();
SelectedGpxFile selectedGpxFile = app.getSelectedGpxHelper().getSelectedFileByPath(gpxPath); SelectedGpxFile selectedGpxFile = app.getSelectedGpxHelper().getSelectedFileByPath(gpxPath);
@ -496,9 +477,9 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter<RecyclerView.V
switchGpxVisibility(gpxFile[0], selectedGpxFile, !disabled); switchGpxVisibility(gpxFile[0], selectedGpxFile, !disabled);
} }
if(!disabled) { if(!disabled) {
mapMarkersHelper.enableGroup(group); app.getItineraryHelper().enableGroup(group);
} else { } else {
mapMarkersHelper.runSynchronization(group); app.getItineraryHelper().runSynchronization(group);
} }
if (disabled) { if (disabled) {
@ -506,10 +487,10 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter<RecyclerView.V
.setAction(R.string.shared_string_undo, new View.OnClickListener() { .setAction(R.string.shared_string_undo, new View.OnClickListener() {
@Override @Override
public void onClick(View view) { public void onClick(View view) {
if (group.getType() == MapMarkersGroup.GPX_TYPE && gpxFile[0] != null) { if (group.getType() == ItineraryGroup.GPX_TYPE && gpxFile[0] != null) {
switchGpxVisibility(gpxFile[0], null, true); switchGpxVisibility(gpxFile[0], null, true);
} }
mapMarkersHelper.enableGroup(group); app.getItineraryHelper().enableGroup(group);
} }
}); });
UiUtilities.setupSnackbar(snackbar, night); UiUtilities.setupSnackbar(snackbar, night);
@ -549,7 +530,7 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter<RecyclerView.V
final Object header = getItem(position); final Object header = getItem(position);
if (header instanceof CategoriesSubHeader) { if (header instanceof CategoriesSubHeader) {
final CategoriesSubHeader categoriesSubHeader = (CategoriesSubHeader) header; final CategoriesSubHeader categoriesSubHeader = (CategoriesSubHeader) header;
final MapMarkersGroup group = categoriesSubHeader.getGroup(); final ItineraryGroup group = categoriesSubHeader.getGroup();
View.OnClickListener openChooseCategoriesDialog = new View.OnClickListener() { View.OnClickListener openChooseCategoriesDialog = new View.OnClickListener() {
@Override @Override
public void onClick(View view) { public void onClick(View view) {
@ -563,7 +544,7 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter<RecyclerView.V
fragment.setUsedOnMap(false); fragment.setUsedOnMap(false);
fragment.show(mapActivity.getSupportFragmentManager(), SelectWptCategoriesBottomSheetDialogFragment.TAG); fragment.show(mapActivity.getSupportFragmentManager(), SelectWptCategoriesBottomSheetDialogFragment.TAG);
} else { } else {
mapActivity.getMyApplication().getMapMarkersHelper().addOrEnableGpxGroup(new File(group.getGpxPath())); mapActivity.getMyApplication().getItineraryHelper().addOrEnableGpxGroup(new File(group.getGpxPath()));
} }
} }
}; };
@ -592,7 +573,7 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter<RecyclerView.V
} }
} }
private String getGroupWptCategoriesString(MapMarkersGroup group) { private String getGroupWptCategoriesString(ItineraryGroup group) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
Set<String> categories = group.getWptCategories(); Set<String> categories = group.getWptCategories();
if (categories != null && !categories.isEmpty()) { if (categories != null && !categories.isEmpty()) {
@ -636,46 +617,17 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter<RecyclerView.V
return items.get(position); return items.get(position);
} }
private String getMonth(int month) {
public static class MarkerGroupItem { SimpleDateFormat dateFormat = new SimpleDateFormat("LLLL", Locale.getDefault());
Date date = new Date();
static final MarkerGroupItem TODAY_HEADER = new MarkerGroupItem(R.string.today); date.setMonth(month);
static final MarkerGroupItem YESTERDAY_HEADER = new MarkerGroupItem(R.string.yesterday); String monthStr = dateFormat.format(date);
static final MarkerGroupItem LAST_SEVEN_DAYS_HEADER = new MarkerGroupItem(R.string.last_seven_days); if (monthStr.length() > 1) {
static final MarkerGroupItem THIS_YEAR_HEADER = new MarkerGroupItem(R.string.this_year); monthStr = Character.toUpperCase(monthStr.charAt(0)) + monthStr.substring(1);
private @StringRes int iname;
protected String name;
public MarkerGroupItem(@StringRes int name) {
this.iname = name;
} }
return monthStr;
public MarkerGroupItem(String name) {
this.name = name;
} }
public String getName(OsmandApplication app) {
if (name == null && iname != 0) {
name = app.getString(iname);
}
return name;
}
}
public class CategoriesSubHeader {
private MapMarkersGroup group;
public CategoriesSubHeader(MapMarkersGroup group) {
this.group = group;
}
public MapMarkersGroup getGroup() {
return group;
}
}
public interface MapMarkersGroupsAdapterListener { public interface MapMarkersGroupsAdapterListener {
void onItemClick(View view); void onItemClick(View view);

View file

@ -8,8 +8,7 @@ import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem;
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItemType; import net.osmand.plus.GpxSelectionHelper.GpxDisplayItemType;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.activities.SavingTrackHelper; import net.osmand.plus.activities.SavingTrackHelper;
import net.osmand.plus.mapmarkers.MapMarkersGroup; import net.osmand.plus.itinerary.ItineraryGroup;
import net.osmand.plus.mapmarkers.MapMarkersHelper;
import java.io.File; import java.io.File;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
@ -65,10 +64,9 @@ public class DeletePointsTask extends AsyncTask<Void, Void, Void> {
} }
private void syncGpx(GPXFile gpxFile) { private void syncGpx(GPXFile gpxFile) {
MapMarkersHelper helper = app.getMapMarkersHelper(); ItineraryGroup group = app.getItineraryHelper().getMarkersGroup(gpxFile);
MapMarkersGroup group = helper.getMarkersGroup(gpxFile);
if (group != null) { if (group != null) {
helper.runSynchronization(group); app.getItineraryHelper().runSynchronization(group);
} }
} }

View file

@ -49,7 +49,7 @@ import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem;
import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem; import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem;
import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.helpers.AndroidUiHelper;
import net.osmand.plus.helpers.FontCache; import net.osmand.plus.helpers.FontCache;
import net.osmand.plus.mapmarkers.MapMarkersGroup; import net.osmand.plus.itinerary.ItineraryGroup;
import net.osmand.plus.mapmarkers.MapMarkersHelper; import net.osmand.plus.mapmarkers.MapMarkersHelper;
import net.osmand.plus.measurementtool.OptionsDividerItem; import net.osmand.plus.measurementtool.OptionsDividerItem;
import net.osmand.plus.myplaces.DeletePointsTask.OnPointsDeleteListener; import net.osmand.plus.myplaces.DeletePointsTask.OnPointsDeleteListener;
@ -192,7 +192,7 @@ public class EditTrackGroupDialogFragment extends MenuBottomSheetDialogFragment
} }
private BaseBottomSheetItem createCopyToMarkersItem(final GPXFile gpxFile) { private BaseBottomSheetItem createCopyToMarkersItem(final GPXFile gpxFile) {
MapMarkersGroup markersGroup = mapMarkersHelper.getMarkersGroup(gpxFile); ItineraryGroup markersGroup = app.getItineraryHelper().getMarkersGroup(gpxFile);
final boolean synced = markersGroup != null && (Algorithms.isEmpty(markersGroup.getWptCategories()) final boolean synced = markersGroup != null && (Algorithms.isEmpty(markersGroup.getWptCategories())
|| markersGroup.getWptCategories().contains(group.getName())); || markersGroup.getWptCategories().contains(group.getName()));
@ -216,10 +216,10 @@ public class EditTrackGroupDialogFragment extends MenuBottomSheetDialogFragment
selectedGpxHelper.selectGpxFile(gpxFile, true, false, false, false, false); selectedGpxHelper.selectGpxFile(gpxFile, true, false, false, false, false);
} }
boolean groupCreated = false; boolean groupCreated = false;
MapMarkersGroup markersGroup = mapMarkersHelper.getMarkersGroup(gpxFile); ItineraryGroup markersGroup = app.getItineraryHelper().getMarkersGroup(gpxFile);
if (markersGroup == null) { if (markersGroup == null) {
groupCreated = true; groupCreated = true;
markersGroup = mapMarkersHelper.addOrEnableGroup(gpxFile); markersGroup = app.getItineraryHelper().addOrEnableGroup(gpxFile);
} }
Set<String> categories = markersGroup.getWptCategories(); Set<String> categories = markersGroup.getWptCategories();
Set<String> selectedCategories = new HashSet<>(); Set<String> selectedCategories = new HashSet<>();
@ -234,9 +234,9 @@ public class EditTrackGroupDialogFragment extends MenuBottomSheetDialogFragment
if (Algorithms.isEmpty(selectedCategories)) { if (Algorithms.isEmpty(selectedCategories)) {
mapMarkersHelper.removeMarkersGroup(markersGroup); mapMarkersHelper.removeMarkersGroup(markersGroup);
} else { } else {
mapMarkersHelper.updateGroupWptCategories(markersGroup, selectedCategories); app.getItineraryHelper().updateGroupWptCategories(markersGroup, selectedCategories);
if (!groupCreated) { if (!groupCreated) {
mapMarkersHelper.runSynchronization(markersGroup); app.getItineraryHelper().runSynchronization(markersGroup);
} }
} }
} }
@ -524,10 +524,9 @@ public class EditTrackGroupDialogFragment extends MenuBottomSheetDialogFragment
} }
private void syncGpx(GPXFile gpxFile) { private void syncGpx(GPXFile gpxFile) {
MapMarkersHelper markersHelper = app.getMapMarkersHelper(); ItineraryGroup group = app.getItineraryHelper().getMarkersGroup(gpxFile);
MapMarkersGroup group = markersHelper.getMarkersGroup(gpxFile);
if (group != null) { if (group != null) {
markersHelper.runSynchronization(group); app.getItineraryHelper().runSynchronization(group);
} }
} }
} }

View file

@ -287,8 +287,6 @@ public class SplitSegmentDialogFragment extends DialogFragment {
} }
int color = app.getResources().getColor(colorId); int color = app.getResources().getColor(colorId);
title.setTextColor(color); title.setTextColor(color);
String titleText = getString(R.string.gpx_split_interval);
title.setText(getString(R.string.ltr_or_rtl_combine_via_colon, titleText, ""));
text.setTextColor(color); text.setTextColor(color);
img.setImageDrawable(ic.getIcon(R.drawable.ic_action_arrow_drop_down, colorId)); img.setImageDrawable(ic.getIcon(R.drawable.ic_action_arrow_drop_down, colorId));
} }

View file

@ -63,7 +63,7 @@ import net.osmand.plus.base.OsmandExpandableListFragment;
import net.osmand.plus.base.PointImageDrawable; import net.osmand.plus.base.PointImageDrawable;
import net.osmand.plus.helpers.GpxUiHelper; import net.osmand.plus.helpers.GpxUiHelper;
import net.osmand.plus.mapmarkers.CoordinateInputDialogFragment; import net.osmand.plus.mapmarkers.CoordinateInputDialogFragment;
import net.osmand.plus.mapmarkers.MapMarkersGroup; import net.osmand.plus.itinerary.ItineraryGroup;
import net.osmand.plus.mapmarkers.MapMarkersHelper; import net.osmand.plus.mapmarkers.MapMarkersHelper;
import net.osmand.plus.myplaces.DeletePointsTask.OnPointsDeleteListener; import net.osmand.plus.myplaces.DeletePointsTask.OnPointsDeleteListener;
import net.osmand.plus.myplaces.TrackBitmapDrawer.TrackBitmapDrawerListener; import net.osmand.plus.myplaces.TrackBitmapDrawer.TrackBitmapDrawerListener;
@ -399,8 +399,7 @@ public class TrackPointFragment extends OsmandExpandableListFragment implements
createMenuItem(menu, SHARE_ID, R.string.shared_string_share, R.drawable.ic_action_gshare_dark, MenuItem.SHOW_AS_ACTION_NEVER, true); createMenuItem(menu, SHARE_ID, R.string.shared_string_share, R.drawable.ic_action_gshare_dark, MenuItem.SHOW_AS_ACTION_NEVER, true);
GPXFile gpxFile = getGpx(); GPXFile gpxFile = getGpx();
if (gpxFile != null && gpxFile.path != null) { if (gpxFile != null && gpxFile.path != null) {
final MapMarkersHelper markersHelper = app.getMapMarkersHelper(); final boolean synced = app.getItineraryHelper().getMarkersGroup(getGpx()) != null;
final boolean synced = markersHelper.getMarkersGroup(getGpx()) != null;
createMenuItem(menu, SELECT_MAP_MARKERS_ID, synced ? R.string.remove_from_map_markers createMenuItem(menu, SELECT_MAP_MARKERS_ID, synced ? R.string.remove_from_map_markers
: R.string.shared_string_add_to_map_markers, R.drawable.ic_action_flag, MenuItem.SHOW_AS_ACTION_NEVER); : R.string.shared_string_add_to_map_markers, R.drawable.ic_action_flag, MenuItem.SHOW_AS_ACTION_NEVER);
} }
@ -501,15 +500,15 @@ public class TrackPointFragment extends OsmandExpandableListFragment implements
return; return;
} }
final GPXFile gpxFile = getGpx(); final GPXFile gpxFile = getGpx();
MapMarkersGroup markersSearch = markersHelper.getMarkersGroup(gpxFile); ItineraryGroup markersSearch = app.getItineraryHelper().getMarkersGroup(gpxFile);
final MapMarkersGroup markersGr; final ItineraryGroup markersGr;
final boolean markersRemoved; final boolean markersRemoved;
if (markersSearch != null) { if (markersSearch != null) {
markersGr = markersSearch; markersGr = markersSearch;
markersHelper.removeMarkersGroup(markersGr); markersHelper.removeMarkersGroup(markersGr);
markersRemoved = true; markersRemoved = true;
} else if (gpxFile != null) { } else if (gpxFile != null) {
markersGr = markersHelper.addOrEnableGroup(gpxFile); markersGr = app.getItineraryHelper().addOrEnableGroup(gpxFile);
markersRemoved = false; markersRemoved = false;
} else { } else {
markersRemoved = false; markersRemoved = false;
@ -535,10 +534,10 @@ public class TrackPointFragment extends OsmandExpandableListFragment implements
if (trackActivity != null) { if (trackActivity != null) {
if (markersRemoved) { if (markersRemoved) {
if (gpxFile != null) { if (gpxFile != null) {
markersHelper.addOrEnableGroup(gpxFile); app.getItineraryHelper().addOrEnableGroup(gpxFile);
} }
} else { } else {
MapMarkersGroup group = markersHelper.getMarkersGroup(gpxFile); ItineraryGroup group = app.getItineraryHelper().getMarkersGroup(gpxFile);
if (group != null) { if (group != null) {
markersHelper.removeMarkersGroup(group); markersHelper.removeMarkersGroup(group);
} }

View file

@ -6,14 +6,12 @@ import androidx.annotation.ColorInt;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import net.osmand.plus.track.GradientScaleType;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
public class RouteLineDrawInfo { public class RouteLineDrawInfo {
private static final String LINE_COLOR_DAY = "line_color_day"; private static final String LINE_COLOR_DAY = "line_color_day";
private static final String LINE_COLOR_NIGHT = "line_color_night"; private static final String LINE_COLOR_NIGHT = "line_color_night";
private static final String LINE_COLOR_GRADIENT = "line_color_gradient";
private static final String LINE_WIDTH = "line_width"; private static final String LINE_WIDTH = "line_width";
private static final String NAVIGATION_ICON_ID = "navigation_icon_id"; private static final String NAVIGATION_ICON_ID = "navigation_icon_id";
private static final String NAVIGATION_ICON_COLOR = "navigation_icon_color"; private static final String NAVIGATION_ICON_COLOR = "navigation_icon_color";
@ -26,7 +24,6 @@ public class RouteLineDrawInfo {
@ColorInt @ColorInt
private Integer colorDay; private Integer colorDay;
private Integer colorNight; private Integer colorNight;
private GradientScaleType scaleType;
private String width; private String width;
// temporally parameters to show in preview // temporally parameters to show in preview
@ -40,11 +37,9 @@ public class RouteLineDrawInfo {
public RouteLineDrawInfo(@Nullable @ColorInt Integer colorDay, public RouteLineDrawInfo(@Nullable @ColorInt Integer colorDay,
@Nullable @ColorInt Integer colorNight, @Nullable @ColorInt Integer colorNight,
@Nullable GradientScaleType gradientScaleType,
@Nullable String width) { @Nullable String width) {
this.colorDay = colorDay; this.colorDay = colorDay;
this.colorNight = colorNight; this.colorNight = colorNight;
this.scaleType = gradientScaleType;
this.width = width; this.width = width;
} }
@ -55,7 +50,6 @@ public class RouteLineDrawInfo {
public RouteLineDrawInfo(@NonNull RouteLineDrawInfo existed) { public RouteLineDrawInfo(@NonNull RouteLineDrawInfo existed) {
this.colorDay = existed.colorDay; this.colorDay = existed.colorDay;
this.colorNight = existed.colorNight; this.colorNight = existed.colorNight;
this.scaleType = existed.scaleType;
this.width = existed.width; this.width = existed.width;
this.iconId = existed.iconId; this.iconId = existed.iconId;
this.iconColor = existed.iconColor; this.iconColor = existed.iconColor;
@ -77,10 +71,6 @@ public class RouteLineDrawInfo {
this.useDefaultColor = useDefaultColor; this.useDefaultColor = useDefaultColor;
} }
public void setGradientScaleType(@Nullable GradientScaleType scaleType) {
this.scaleType = scaleType;
}
public void setWidth(@Nullable String width) { public void setWidth(@Nullable String width) {
this.width = width; this.width = width;
} }
@ -118,11 +108,6 @@ public class RouteLineDrawInfo {
return nightMode ? colorNight : colorDay; return nightMode ? colorNight : colorDay;
} }
@Nullable
public GradientScaleType getGradientScaleType() {
return scaleType;
}
@Nullable @Nullable
public String getWidth() { public String getWidth() {
return width; return width;
@ -156,9 +141,6 @@ public class RouteLineDrawInfo {
if (bundle.containsKey(LINE_COLOR_NIGHT)) { if (bundle.containsKey(LINE_COLOR_NIGHT)) {
colorNight = bundle.getInt(LINE_COLOR_NIGHT); colorNight = bundle.getInt(LINE_COLOR_NIGHT);
} }
if (bundle.containsKey(LINE_COLOR_GRADIENT)) {
scaleType = GradientScaleType.getGradientTypeByName(bundle.getString(LINE_COLOR_GRADIENT));
}
width = bundle.getString(LINE_WIDTH); width = bundle.getString(LINE_WIDTH);
iconId = bundle.getInt(NAVIGATION_ICON_ID); iconId = bundle.getInt(NAVIGATION_ICON_ID);
iconColor = bundle.getInt(NAVIGATION_ICON_COLOR); iconColor = bundle.getInt(NAVIGATION_ICON_COLOR);
@ -175,9 +157,6 @@ public class RouteLineDrawInfo {
if (colorNight != null) { if (colorNight != null) {
bundle.putInt(LINE_COLOR_NIGHT, colorNight); bundle.putInt(LINE_COLOR_NIGHT, colorNight);
} }
if (scaleType != null) {
bundle.putString(LINE_COLOR_GRADIENT, scaleType.getTypeName());
}
if (width != null) { if (width != null) {
bundle.putString(LINE_WIDTH, width); bundle.putString(LINE_WIDTH, width);
} }
@ -198,7 +177,6 @@ public class RouteLineDrawInfo {
if (!Algorithms.objectEquals(getColor(false), that.getColor(false))) return false; if (!Algorithms.objectEquals(getColor(false), that.getColor(false))) return false;
if (!Algorithms.objectEquals(getColor(true), that.getColor(true))) return false; if (!Algorithms.objectEquals(getColor(true), that.getColor(true))) return false;
if (!Algorithms.objectEquals(scaleType, that.scaleType)) return false;
return Algorithms.objectEquals(width, that.width); return Algorithms.objectEquals(width, that.width);
} }
@ -206,7 +184,6 @@ public class RouteLineDrawInfo {
public int hashCode() { public int hashCode() {
int result = colorDay != null ? colorDay.hashCode() : 0; int result = colorDay != null ? colorDay.hashCode() : 0;
result = 31 * result + (colorNight != null ? colorNight.hashCode() : 0); result = 31 * result + (colorNight != null ? colorNight.hashCode() : 0);
result = 31 * result + (scaleType != null ? scaleType.getTypeName().hashCode() : 0);
result = 31 * result + (width != null ? width.hashCode() : 0); result = 31 * result + (width != null ? width.hashCode() : 0);
return result; return result;
} }

View file

@ -21,7 +21,6 @@ import net.osmand.AndroidUtils;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.UiUtilities; import net.osmand.plus.UiUtilities;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.helpers.AndroidUiHelper;
import net.osmand.plus.helpers.ColorDialogs; import net.osmand.plus.helpers.ColorDialogs;
import net.osmand.plus.helpers.enums.DayNightMode; import net.osmand.plus.helpers.enums.DayNightMode;
import net.osmand.plus.routepreparationmenu.cards.BaseCard; import net.osmand.plus.routepreparationmenu.cards.BaseCard;
@ -33,8 +32,6 @@ import net.osmand.plus.settings.fragments.HeaderUiAdapter;
import net.osmand.plus.track.AppearanceViewHolder; import net.osmand.plus.track.AppearanceViewHolder;
import net.osmand.plus.track.ColorsCard; import net.osmand.plus.track.ColorsCard;
import net.osmand.plus.track.CustomColorBottomSheet.ColorPickerListener; import net.osmand.plus.track.CustomColorBottomSheet.ColorPickerListener;
import net.osmand.plus.track.GradientCard;
import net.osmand.plus.track.GradientScaleType;
import net.osmand.plus.widgets.multistatetoggle.RadioItem; import net.osmand.plus.widgets.multistatetoggle.RadioItem;
import net.osmand.plus.widgets.multistatetoggle.RadioItem.OnRadioItemClickListener; import net.osmand.plus.widgets.multistatetoggle.RadioItem.OnRadioItemClickListener;
import net.osmand.plus.widgets.multistatetoggle.TextToggleButton; import net.osmand.plus.widgets.multistatetoggle.TextToggleButton;
@ -54,7 +51,6 @@ public class RouteLineColorCard extends BaseCard implements CardListener, ColorP
private HeaderUiAdapter headerUiAdapter; private HeaderUiAdapter headerUiAdapter;
private ColorsCard colorsCard; private ColorsCard colorsCard;
private GradientCard gradientCard;
private ColorTypeAdapter colorAdapter; private ColorTypeAdapter colorAdapter;
private RecyclerView groupRecyclerView; private RecyclerView groupRecyclerView;
private TextView tvDescription; private TextView tvDescription;
@ -68,9 +64,7 @@ public class RouteLineColorCard extends BaseCard implements CardListener, ColorP
private enum ColorMode { private enum ColorMode {
DEFAULT(R.string.map_widget_renderer, R.drawable.ic_action_map_style), DEFAULT(R.string.map_widget_renderer, R.drawable.ic_action_map_style),
CUSTOM(R.string.shared_string_custom, R.drawable.ic_action_settings), CUSTOM(R.string.shared_string_custom, R.drawable.ic_action_settings);
ALTITUDE(R.string.altitude, R.drawable.ic_action_hillshade_dark),
SLOPE(R.string.shared_string_slope, R.drawable.ic_action_altitude_ascent);
ColorMode(int titleId, int iconId) { ColorMode(int titleId, int iconId) {
this.titleId = titleId; this.titleId = titleId;
@ -114,43 +108,28 @@ public class RouteLineColorCard extends BaseCard implements CardListener, ColorP
setupRadioGroup(radioGroup); setupRadioGroup(radioGroup);
cardsContainer = (ViewGroup) view.findViewById(R.id.colors_card_container); cardsContainer = (ViewGroup) view.findViewById(R.id.colors_card_container);
createCards(cardsContainer); createColorSelector(cardsContainer);
initSelectedMode(); initSelectedMode();
} }
private void initSelectedMode() { private void initSelectedMode() {
if (routeLineDrawInfo.getGradientScaleType() == GradientScaleType.ALTITUDE) {
selectedMode = ColorMode.ALTITUDE;
} else if (routeLineDrawInfo.getGradientScaleType() == GradientScaleType.SLOPE) {
selectedMode = ColorMode.SLOPE;
} else {
selectedMode = getRouteLineColor() == null ? ColorMode.DEFAULT : ColorMode.CUSTOM; selectedMode = getRouteLineColor() == null ? ColorMode.DEFAULT : ColorMode.CUSTOM;
}
modeChanged(); modeChanged();
} }
private void modeChanged() { private void modeChanged() {
if (selectedMode == ColorMode.DEFAULT) { if (selectedMode == ColorMode.DEFAULT) {
themeToggleContainer.setVisibility(View.GONE); themeToggleContainer.setVisibility(View.GONE);
AndroidUiHelper.updateVisibility(colorsCard.getView(), false); cardsContainer.setVisibility(View.GONE);
AndroidUiHelper.updateVisibility(gradientCard.getView(), false);
routeLineDrawInfo.setUseDefaultColor(true); routeLineDrawInfo.setUseDefaultColor(true);
changeMapTheme(initMapTheme); changeMapTheme(initMapTheme);
} else if (selectedMode == ColorMode.CUSTOM) { } else {
themeToggleContainer.setVisibility(View.VISIBLE); themeToggleContainer.setVisibility(View.VISIBLE);
AndroidUiHelper.updateVisibility(colorsCard.getView(), true); cardsContainer.setVisibility(View.VISIBLE);
AndroidUiHelper.updateVisibility(gradientCard.getView(), false);
routeLineDrawInfo.setUseDefaultColor(false); routeLineDrawInfo.setUseDefaultColor(false);
changeMapTheme(isNightMap() ? DayNightMode.NIGHT : DayNightMode.DAY); changeMapTheme(isNightMap() ? DayNightMode.NIGHT : DayNightMode.DAY);
} else {
gradientCard.setSelectedScaleType(getGradientScaleTypeFromMode());
AndroidUiHelper.updateVisibility(colorsCard.getView(), false);
AndroidUiHelper.updateVisibility(gradientCard.getView(), true);
themeToggleContainer.setVisibility(View.GONE);
routeLineDrawInfo.setUseDefaultColor(false);
} }
routeLineDrawInfo.setGradientScaleType(getGradientScaleTypeFromMode());
updateColorItems(); updateColorItems();
updateDescription(); updateDescription();
} }
@ -191,7 +170,7 @@ public class RouteLineColorCard extends BaseCard implements CardListener, ColorP
} }
} }
private void createCards(ViewGroup container) { private void createColorSelector(ViewGroup container) {
MapActivity mapActivity = getMapActivity(); MapActivity mapActivity = getMapActivity();
if (mapActivity != null) { if (mapActivity != null) {
List<Integer> colors = new ArrayList<>(); List<Integer> colors = new ArrayList<>();
@ -205,9 +184,6 @@ public class RouteLineColorCard extends BaseCard implements CardListener, ColorP
colorsCard = new ColorsCard(mapActivity, selectedColor, targetFragment, colors, preference, null); colorsCard = new ColorsCard(mapActivity, selectedColor, targetFragment, colors, preference, null);
colorsCard.setListener(this); colorsCard.setListener(this);
container.addView(colorsCard.build(mapActivity)); container.addView(colorsCard.build(mapActivity));
gradientCard = new GradientCard(mapActivity, routeLineDrawInfo.getGradientScaleType());
container.addView(gradientCard.build(mapActivity));
} }
} }
@ -236,17 +212,6 @@ public class RouteLineColorCard extends BaseCard implements CardListener, ColorP
return routeLineDrawInfo.getColor(isNightMap()); return routeLineDrawInfo.getColor(isNightMap());
} }
@Nullable
private GradientScaleType getGradientScaleTypeFromMode() {
if (selectedMode == ColorMode.ALTITUDE) {
return GradientScaleType.ALTITUDE;
} else if (selectedMode == ColorMode.SLOPE) {
return GradientScaleType.SLOPE;
} else {
return null;
}
}
private void updateSelectedColor() { private void updateSelectedColor() {
int selectedColor = colorsCard.getSelectedColor(); int selectedColor = colorsCard.getSelectedColor();
routeLineDrawInfo.setColor(selectedColor, isNightMap()); routeLineDrawInfo.setColor(selectedColor, isNightMap());
@ -270,8 +235,6 @@ public class RouteLineColorCard extends BaseCard implements CardListener, ColorP
String colorName = ""; String colorName = "";
if (selectedMode == ColorMode.DEFAULT) { if (selectedMode == ColorMode.DEFAULT) {
colorName = app.getString(R.string.map_widget_renderer); colorName = app.getString(R.string.map_widget_renderer);
} else if (selectedMode == ColorMode.ALTITUDE || selectedMode == ColorMode.SLOPE) {
colorName = app.getString(selectedMode.titleId);
} else if (getRouteLineColor() != null) { } else if (getRouteLineColor() != null) {
int colorNameId = ColorDialogs.getColorName(getRouteLineColor()); int colorNameId = ColorDialogs.getColorName(getRouteLineColor());
colorName = app.getString(colorNameId); colorName = app.getString(colorNameId);
@ -285,12 +248,10 @@ public class RouteLineColorCard extends BaseCard implements CardListener, ColorP
String pattern = app.getString(R.string.route_line_use_map_style_appearance); String pattern = app.getString(R.string.route_line_use_map_style_appearance);
String color = app.getString(R.string.shared_string_color).toLowerCase(); String color = app.getString(R.string.shared_string_color).toLowerCase();
description = String.format(pattern, color, app.getRendererRegistry().getSelectedRendererName()); description = String.format(pattern, color, app.getRendererRegistry().getSelectedRendererName());
} else if (selectedMode == ColorMode.CUSTOM) { } else {
String pattern = app.getString(R.string.specify_color_for_map_mode); String pattern = app.getString(R.string.specify_color_for_map_mode);
String mapModeTitle = app.getString(isNightMap() ? NIGHT_TITLE_ID : DAY_TITLE_ID); String mapModeTitle = app.getString(isNightMap() ? NIGHT_TITLE_ID : DAY_TITLE_ID);
description = String.format(pattern, mapModeTitle.toLowerCase()); description = String.format(pattern, mapModeTitle.toLowerCase());
} else {
description = app.getString(R.string.route_line_use_gradient_coloring);
} }
tvDescription.setText(description); tvDescription.setText(description);
} }

View file

@ -6,8 +6,6 @@ import android.view.View;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.Nullable;
import net.osmand.AndroidNetworkUtils; import net.osmand.AndroidNetworkUtils;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
@ -73,7 +71,7 @@ public class SendSearchQueryBottomSheet extends MenuBottomSheetDialogFragment {
AndroidNetworkUtils.sendRequestAsync(app, "https://osmand.net/api/missing_search", params, AndroidNetworkUtils.sendRequestAsync(app, "https://osmand.net/api/missing_search", params,
null, true, true, new AndroidNetworkUtils.OnRequestResultListener() { null, true, true, new AndroidNetworkUtils.OnRequestResultListener() {
@Override @Override
public void onResult(@Nullable String result, @Nullable String error) { public void onResult(String result) {
if (result != null && isAdded()) { if (result != null && isAdded()) {
try { try {
JSONObject obj = new JSONObject(result); JSONObject obj = new JSONObject(result);

View file

@ -958,7 +958,7 @@ public class OsmandSettings {
DEFAULT_SPEED.setModeDefaultValue(ApplicationMode.BICYCLE, 2.77f); DEFAULT_SPEED.setModeDefaultValue(ApplicationMode.BICYCLE, 2.77f);
DEFAULT_SPEED.setModeDefaultValue(ApplicationMode.PEDESTRIAN, 1.11f); DEFAULT_SPEED.setModeDefaultValue(ApplicationMode.PEDESTRIAN, 1.11f);
DEFAULT_SPEED.setModeDefaultValue(ApplicationMode.BOAT, 1.38f); DEFAULT_SPEED.setModeDefaultValue(ApplicationMode.BOAT, 1.38f);
DEFAULT_SPEED.setModeDefaultValue(ApplicationMode.AIRCRAFT, 200f); DEFAULT_SPEED.setModeDefaultValue(ApplicationMode.AIRCRAFT, 40f);
DEFAULT_SPEED.setModeDefaultValue(ApplicationMode.SKI, 1.38f); DEFAULT_SPEED.setModeDefaultValue(ApplicationMode.SKI, 1.38f);
} }
@ -2641,7 +2641,7 @@ public class OsmandSettings {
return lang + IndexConstants.VOICE_PROVIDER_SUFFIX; return lang + IndexConstants.VOICE_PROVIDER_SUFFIX;
} }
} }
return "en-tts"; return VOICE_PROVIDER_NOT_USE;
} }
}.makeProfile(); }.makeProfile();
@ -2708,7 +2708,6 @@ public class OsmandSettings {
public final ListStringPreference CUSTOM_ROUTE_LINE_COLORS = (ListStringPreference) new ListStringPreference(this, "custom_route_line_colors", null, ",").makeShared().makeGlobal(); public final ListStringPreference CUSTOM_ROUTE_LINE_COLORS = (ListStringPreference) new ListStringPreference(this, "custom_route_line_colors", null, ",").makeShared().makeGlobal();
public final CommonPreference<Integer> ROUTE_LINE_COLOR_DAY = new IntPreference(this, "route_line_color", 0).cache().makeProfile(); public final CommonPreference<Integer> ROUTE_LINE_COLOR_DAY = new IntPreference(this, "route_line_color", 0).cache().makeProfile();
public final CommonPreference<Integer> ROUTE_LINE_COLOR_NIGHT = new IntPreference(this, "route_line_color_night", 0).cache().makeProfile(); public final CommonPreference<Integer> ROUTE_LINE_COLOR_NIGHT = new IntPreference(this, "route_line_color_night", 0).cache().makeProfile();
public final CommonPreference<GradientScaleType> ROUTE_LINE_GRADIENT = new EnumStringPreference<>(this, "route_line_gradient", null, new GradientScaleType[] {GradientScaleType.ALTITUDE, GradientScaleType.SLOPE}).cache().makeProfile();
public final CommonPreference<String> ROUTE_LINE_WIDTH = new StringPreference(this, "route_line_width", null).makeProfile(); public final CommonPreference<String> ROUTE_LINE_WIDTH = new StringPreference(this, "route_line_width", null).makeProfile();
public final OsmandPreference<Boolean> USE_OSM_LIVE_FOR_ROUTING = new BooleanPreference(this, "enable_osmc_routing", true).makeProfile(); public final OsmandPreference<Boolean> USE_OSM_LIVE_FOR_ROUTING = new BooleanPreference(this, "enable_osmc_routing", true).makeProfile();

View file

@ -12,7 +12,7 @@ import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.mapmarkers.MapMarker; import net.osmand.plus.mapmarkers.MapMarker;
import net.osmand.plus.mapmarkers.MapMarkersDbHelper; import net.osmand.plus.mapmarkers.MapMarkersDbHelper;
import net.osmand.plus.mapmarkers.MapMarkersGroup; import net.osmand.plus.itinerary.ItineraryGroup;
import net.osmand.plus.mapmarkers.MapMarkersHelper; import net.osmand.plus.mapmarkers.MapMarkersHelper;
import net.osmand.plus.settings.backend.ExportSettingsType; import net.osmand.plus.settings.backend.ExportSettingsType;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
@ -46,7 +46,7 @@ public class HistoryMarkersSettingsItem extends CollectionSettingsItem<MapMarker
protected void init() { protected void init() {
super.init(); super.init();
markersHelper = app.getMapMarkersHelper(); markersHelper = app.getMapMarkersHelper();
existingItems = new ArrayList<>(markersHelper.getMapMarkersFromDefaultGroups(true)); existingItems = new ArrayList<>(app.getItineraryHelper().getMapMarkersFromDefaultGroups(true));
} }
@NonNull @NonNull
@ -122,10 +122,10 @@ public class HistoryMarkersSettingsItem extends CollectionSettingsItem<MapMarker
} }
} }
public MapMarkersGroup getMarkersGroup() { public ItineraryGroup getMarkersGroup() {
String name = app.getString(R.string.markers_history); String name = app.getString(R.string.markers_history);
String groupId = ExportSettingsType.HISTORY_MARKERS.name(); String groupId = ExportSettingsType.HISTORY_MARKERS.name();
MapMarkersGroup markersGroup = new MapMarkersGroup(groupId, name, MapMarkersGroup.ANY_TYPE); ItineraryGroup markersGroup = new ItineraryGroup(groupId, name, ItineraryGroup.ANY_TYPE);
markersGroup.setMarkers(items); markersGroup.setMarkers(items);
return markersGroup; return markersGroup;
} }

View file

@ -12,7 +12,7 @@ import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.mapmarkers.MapMarker; import net.osmand.plus.mapmarkers.MapMarker;
import net.osmand.plus.mapmarkers.MapMarkersDbHelper; import net.osmand.plus.mapmarkers.MapMarkersDbHelper;
import net.osmand.plus.mapmarkers.MapMarkersGroup; import net.osmand.plus.itinerary.ItineraryGroup;
import net.osmand.plus.mapmarkers.MapMarkersHelper; import net.osmand.plus.mapmarkers.MapMarkersHelper;
import net.osmand.plus.settings.backend.ExportSettingsType; import net.osmand.plus.settings.backend.ExportSettingsType;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
@ -46,7 +46,7 @@ public class MarkersSettingsItem extends CollectionSettingsItem<MapMarker> {
protected void init() { protected void init() {
super.init(); super.init();
markersHelper = app.getMapMarkersHelper(); markersHelper = app.getMapMarkersHelper();
existingItems = new ArrayList<>(markersHelper.getMapMarkersFromDefaultGroups(false)); existingItems = new ArrayList<>(app.getItineraryHelper().getMapMarkersFromDefaultGroups(false));
} }
@NonNull @NonNull
@ -122,10 +122,10 @@ public class MarkersSettingsItem extends CollectionSettingsItem<MapMarker> {
} }
} }
public MapMarkersGroup getMarkersGroup() { public ItineraryGroup getMarkersGroup() {
String name = app.getString(R.string.map_markers); String name = app.getString(R.string.map_markers);
String groupId = ExportSettingsType.ACTIVE_MARKERS.name(); String groupId = ExportSettingsType.ACTIVE_MARKERS.name();
MapMarkersGroup markersGroup = new MapMarkersGroup(groupId, name, MapMarkersGroup.ANY_TYPE); ItineraryGroup markersGroup = new ItineraryGroup(groupId, name, ItineraryGroup.ANY_TYPE);
markersGroup.setMarkers(items); markersGroup.setMarkers(items);
return markersGroup; return markersGroup;
} }

Some files were not shown because too many files have changed in this diff Show more