diff --git a/OsmAnd-shared/src/commonMain/kotlin/net/osmand/shared/gpx/TrackFolderLoaderTask.kt b/OsmAnd-shared/src/commonMain/kotlin/net/osmand/shared/gpx/TrackFolderLoaderTask.kt index 5b1db67aa09..b4222663461 100644 --- a/OsmAnd-shared/src/commonMain/kotlin/net/osmand/shared/gpx/TrackFolderLoaderTask.kt +++ b/OsmAnd-shared/src/commonMain/kotlin/net/osmand/shared/gpx/TrackFolderLoaderTask.kt @@ -51,7 +51,7 @@ class TrackFolderLoaderTask( if (!shouldLoadFolder(cachedRootFolder)) return cachedRootFolder!! val start = currentTimeMillis() - log.info("Start loading tracks in ${folder.getDirName()}") + log.info("Start loading tracks in ${folder.getDirName(true)}") folder.clearData() loadingTime = currentTimeMillis() diff --git a/OsmAnd-shared/src/commonMain/kotlin/net/osmand/shared/gpx/data/ComparableTracksGroup.kt b/OsmAnd-shared/src/commonMain/kotlin/net/osmand/shared/gpx/data/ComparableTracksGroup.kt index 62573f09aea..317b45a2648 100644 --- a/OsmAnd-shared/src/commonMain/kotlin/net/osmand/shared/gpx/data/ComparableTracksGroup.kt +++ b/OsmAnd-shared/src/commonMain/kotlin/net/osmand/shared/gpx/data/ComparableTracksGroup.kt @@ -4,6 +4,7 @@ import net.osmand.shared.gpx.filters.TrackFolderAnalysis interface ComparableTracksGroup { fun getFolderAnalysis(): TrackFolderAnalysis - fun getDirName(): String + fun getDirName(includingSubdirs: Boolean): String fun lastModified(): Long + fun getDefaultOrder(): Int = -1 } \ No newline at end of file diff --git a/OsmAnd-shared/src/commonMain/kotlin/net/osmand/shared/gpx/data/SmartFolder.kt b/OsmAnd-shared/src/commonMain/kotlin/net/osmand/shared/gpx/data/SmartFolder.kt index baf2640e457..f45bd199247 100644 --- a/OsmAnd-shared/src/commonMain/kotlin/net/osmand/shared/gpx/data/SmartFolder.kt +++ b/OsmAnd-shared/src/commonMain/kotlin/net/osmand/shared/gpx/data/SmartFolder.kt @@ -10,6 +10,9 @@ import net.osmand.shared.util.KCollectionUtils @Serializable class SmartFolder(@Serializable var folderName: String) : TracksGroup, ComparableTracksGroup { + companion object { + const val ID_PREFIX = "SMART_FOLDER___" + } @Transient private var trackItems: List? = null @@ -25,6 +28,10 @@ class SmartFolder(@Serializable var folderName: String) : TracksGroup, Comparabl @Transient private var folderAnalysis: TrackFolderAnalysis? = null + override fun getId(): String { + return ID_PREFIX + folderName + } + override fun getName() = folderName override fun getTrackItems(): List { @@ -52,7 +59,7 @@ class SmartFolder(@Serializable var folderName: String) : TracksGroup, Comparabl return analysis } - override fun getDirName() = folderName + override fun getDirName(includingSubdirs: Boolean) = folderName override fun lastModified() = creationTime diff --git a/OsmAnd-shared/src/commonMain/kotlin/net/osmand/shared/gpx/data/TrackFolder.kt b/OsmAnd-shared/src/commonMain/kotlin/net/osmand/shared/gpx/data/TrackFolder.kt index 429754ac594..2cbe0ee006b 100644 --- a/OsmAnd-shared/src/commonMain/kotlin/net/osmand/shared/gpx/data/TrackFolder.kt +++ b/OsmAnd-shared/src/commonMain/kotlin/net/osmand/shared/gpx/data/TrackFolder.kt @@ -5,7 +5,6 @@ import net.osmand.shared.gpx.TrackItem import net.osmand.shared.gpx.filters.TrackFolderAnalysis import net.osmand.shared.io.KFile import net.osmand.shared.util.KAlgorithms -import net.osmand.shared.util.KCollectionUtils import kotlin.math.max class TrackFolder(dirFile: KFile, parentFolder: TrackFolder?) : @@ -37,6 +36,8 @@ class TrackFolder(dirFile: KFile, parentFolder: TrackFolder?) : lastModified = folder.lastModified } + override fun getId() = relativePath + override fun getName(): String { return GpxHelper.getFolderName(dirFile, false) } @@ -50,15 +51,21 @@ class TrackFolder(dirFile: KFile, parentFolder: TrackFolder?) : } val relativePath: String - get() { - val dirName = getDirName() - val parentFolder = getParentFolder() - return if (parentFolder != null && !parentFolder.isRootFolder) parentFolder.relativePath + "/" + dirName else dirName - } + get() = + if (!isRootFolder) { + val dirName = dirFile.name() + val parent = getParentFolder() + if (parent?.isRootFolder == false) parent.relativePath + "/" + dirName else dirName + } else { + "" + } + val isRootFolder: Boolean get() = getParentFolder() == null + fun getRootFolder(): TrackFolder = getParentFolder()?.getRootFolder() ?: this + fun getParentFolder(): TrackFolder? { return parentFolder } @@ -144,8 +151,8 @@ class TrackFolder(dirFile: KFile, parentFolder: TrackFolder?) : return analysis } - override fun getDirName(): String { - return dirFile.name() + override fun getDirName(includingSubdirs: Boolean): String { + return if (includingSubdirs) relativePath else dirFile.name() } fun getLastModified(): Long { diff --git a/OsmAnd-shared/src/commonMain/kotlin/net/osmand/shared/gpx/data/TracksGroup.kt b/OsmAnd-shared/src/commonMain/kotlin/net/osmand/shared/gpx/data/TracksGroup.kt index d8973bb6ddf..f47c21da226 100644 --- a/OsmAnd-shared/src/commonMain/kotlin/net/osmand/shared/gpx/data/TracksGroup.kt +++ b/OsmAnd-shared/src/commonMain/kotlin/net/osmand/shared/gpx/data/TracksGroup.kt @@ -3,6 +3,8 @@ package net.osmand.shared.gpx.data import net.osmand.shared.gpx.TrackItem interface TracksGroup { + fun getId(): String + fun getName(): String fun getTrackItems(): List diff --git a/OsmAnd-shared/src/commonMain/kotlin/net/osmand/shared/gpx/filters/TrackFolderAnalysis.kt b/OsmAnd-shared/src/commonMain/kotlin/net/osmand/shared/gpx/filters/TrackFolderAnalysis.kt index ec4aa8ee39c..3cfc13033a2 100644 --- a/OsmAnd-shared/src/commonMain/kotlin/net/osmand/shared/gpx/filters/TrackFolderAnalysis.kt +++ b/OsmAnd-shared/src/commonMain/kotlin/net/osmand/shared/gpx/filters/TrackFolderAnalysis.kt @@ -52,7 +52,7 @@ class TrackFolderAnalysis(folder: TracksGroup) { timeSpan = timeSpanSum.toInt() tracksCount = items.size - log.info(">>>> ${folder.getName()} = (tracks: $tracksCount, totalDistance: ${"%.2f".format(totalDistance)}, " + + log.info(">>>> ${folder.getId()} = (tracks: $tracksCount, totalDistance: ${"%.2f".format(totalDistance)}, " + "timeSpan: $timeSpan, fileSize: $fileSize, diffElevationUp: ${"%.2f".format(diffElevationUp)}, diffElevationDown: ${"%.2f".format(diffElevationDown)}") } } diff --git a/OsmAnd/res/values-b+sr+Latn/strings.xml b/OsmAnd/res/values-b+sr+Latn/strings.xml index 313e50bffba..ad68c83ae7e 100644 --- a/OsmAnd/res/values-b+sr+Latn/strings.xml +++ b/OsmAnd/res/values-b+sr+Latn/strings.xml @@ -5556,7 +5556,7 @@ Tip goriva Metrika vozila OBD podrška - Pratite ključne metrike vozila koristeći OBD-II protokol. Pristup podacima uključujući: * Brzina motora * Potrošnja goriva * Preostalo gorivo * Razdaljina od pokretanja motora * Usisna temperatura * Temperatura okoline * Temperatura rashladne tečnosti * Brzina vozila * Procenat baterije + Pratite ključne metrike vozila koristeći OBD-II protokol. Pristup podacima uključujući:\n • Brzina motora, vreme rada motora, izračunato opterećenje motora \n • Potrošnja goriva, Pritisak goriva, Preostalo gorivo\n • Usisna temperatura, temperatura okoline, temperatura rashladne tečnosti, temperatura motornog ulja\n • Brzina vozila, položaj gasa, napon baterije\n Pokazuje razdaljinu koju vozilo može da pređe sa preostalim gorivom preko OBD senzora VIN Nepoznat uređaj @@ -5581,7 +5581,7 @@ Omogućava ili onemogućava funkciju ekrana osetljivog na dodir da spreči slučajne dodire Dugme za prikaz ili skrivanje lokalnih OSM izmena na mapi. Prikaži staze terenskih motocikla - l/h + L/h • Dodan je preglednik galerije preko celog ekrana za slike Vikimedije\n\n • Uveden je novi dodatak „Metrika vozila“ za praćenje performansi vozila koristeći OBD-II protokol\n\n • Dodata mogućnost dodeljivanja aktivnosti stazama i filtriranja u skladu sa tim\n\n • Implementirane nove brze akcije za snimanje putovanja i zaključavanje ekrana na dodir\n\n • Uveden je prilagodljiv izgled dugmeta mape i precizna mreža\n\n • Dodat je kontekstni meni i akcija „Reset prosečne brzine“ u vidžete\n\n • Dodan je novi sloj rute „Staze terenskih motocikla“\n\n • Ispravljeno „Automatsko snimanje staze tokom navigacije“\n\n • Rešen problem sa preokrenutim koordinatama u RTL-u\n\n • Ispravljeni propušteni podaci senzora za trenutno snimljenu stazu\n\n • Dodate informacije o okolnim područjima za izabranu tačku\n\n • Dodata brza akcija za kontrolu vidljivosti OSM izmena\n\n • Odvojeni parametri vidljivosti za opcije kolorizacije terena\n\n • Dodata ikona koja se može dodirnuti za prikaz pristupa ili drugih atributa puta ili putanje Ekran je zaključan. Za otključavanje pritisni dugme %1$s ili dodirni dugme na ekranu. Ekran osetljiv na dodir je otključan. @@ -5612,19 +5612,20 @@ Nivo goriva (l) Preostalo goriva za (km) Potrošnja goriva (OBD) - Potrošnja goriva l/h + Potrošnja goriva L/h Potrošnja goriva %/h - Potrošnja goriva (l/h) - Prikazuje potrošnju goriva na temelju senzora (l/h) - Prikazuje potrošnju goriva na temelju proračuna (l/h) + Potrošnja goriva (L/h) + Prikazuje potrošnju goriva na temelju senzora (L/h) + Prikazuje potrošnju goriva na temelju proračuna (L/h) + Preostalo goriva (%) Nivo goriva (%) l Maksimum %/h Prikazuje potrošnju goriva vozila na osnovu proračuna (%/h) - l/100km - Potrošnja goriva (l/km) - Prikazuje potrošnju goriva vozila na osnovu proračuna (l/km) + L/100km + Potrošnja goriva (L/km) + Prikazuje potrošnju goriva vozila na osnovu proračuna (L/km) Simulira OBD podatke kPa Pritisak goriva diff --git a/OsmAnd/res/values-da/strings.xml b/OsmAnd/res/values-da/strings.xml index a98b9731a2a..3d9157226e7 100644 --- a/OsmAnd/res/values-da/strings.xml +++ b/OsmAnd/res/values-da/strings.xml @@ -5617,7 +5617,7 @@ Brændstofniveau (%) Brændstof tilbage (km) Brændstofforbrug (obd) - Brændstofforbrug L/t + Brændstofforbrug Brændstofforbrug %/t Maksimum %/t diff --git a/OsmAnd/res/values-es/strings.xml b/OsmAnd/res/values-es/strings.xml index 1adab33276a..97c65a8fd01 100644 --- a/OsmAnd/res/values-es/strings.xml +++ b/OsmAnd/res/values-es/strings.xml @@ -6004,7 +6004,7 @@ Nivel de combustible (%) Combustible restante (km) Tasa de consumo (obd) - Consumo de combustible L/h + Consumo de combustible Consumo de combustible %/h l %/h diff --git a/OsmAnd/res/values-gl/phrases.xml b/OsmAnd/res/values-gl/phrases.xml index dbe133631b5..f315792217a 100644 --- a/OsmAnd/res/values-gl/phrases.xml +++ b/OsmAnd/res/values-gl/phrases.xml @@ -4198,4 +4198,10 @@ Sementes Ferramentas Recambios mecánicos + Tipo de campamento + Básico + Estándar + Atendido + De luxo + Acampar nun cámping \ No newline at end of file diff --git a/OsmAnd/res/values-in/strings.xml b/OsmAnd/res/values-in/strings.xml index 2d38e62a440..5ecadf0e71c 100644 --- a/OsmAnd/res/values-in/strings.xml +++ b/OsmAnd/res/values-in/strings.xml @@ -5821,7 +5821,7 @@ Bahan Bakar Ganda menggunakan Etanol Tombol untuk menampilkan atau menyembunyikan penyuntingan OSM lokal pada peta. Ubah aktivitas - l/j + L/j Mulai / Jeda Skema Warna Perangkat tidak diketahui @@ -5923,7 +5923,7 @@ Metrik kendaraan Tingkat konsumsi bahan bakar Menampilkan jenis bahan bakar kendaraan melalui sensor OBD - Pantau metrik kendaraan utama menggunakan protokol OBD-II. Akses data termasuk: * Kecepatan mesin * Konsumsi bahan bakar * Bahan bakar tersisa * Jarak sejak penilaian mesin * Suhu masukan * Suhu sekitar * Suhu pendingin * Kecepatan kendaraan * Persentase baterai + Pantau metrik kendaraan utama menggunakan protokol OBD-II. Akses data termasuk:\n• Kecepatan mesin, Waktu Operasi Mesin, Beban Mesin yang Dihitung\n• Konsumsi bahan bakar, Tekanan bahan bakar, Bahan bakar yang tersisa\n• Suhu masuk, Suhu sekitar, Suhu cairan pendingin, Suhu oli mesin\n• Kecepatan kendaraan, Posisi katup gas, Tegangan baterai\n Saklar untuk navigasi ke layar sebelumnya. Saklar untuk menampilkan atau menyembunyikan menu samping. Menu samping @@ -5966,13 +5966,13 @@ Mohon periksa berikut:\n – Pastikan Bluetooth nyala\n – Mesin kendaraan berjalan\n – Pastikan perangkat Anda dalam jarak pemindai. Mohon dekatkan perangkat Anda pada pemindai. Pastikan mesin kendaraan sedang berjalan. Tingkat konsumsi bahan bakar (sensor) - Menampilkan tingkat konsumsi bahan bakar kendaraan berdasarkan perhitungan (l/j) - Menampilkan tingkat konsumsi bahan bakar kendaraan berdasarkan sensor (l/j) + Menampilkan tingkat konsumsi bahan bakar kendaraan berdasarkan perhitungan (L/j) + Menampilkan tingkat konsumsi bahan bakar kendaraan berdasarkan sensor (L/j) Tingkat bahan bakar (l) Tingkat bahan bakar (%) Bahan bakar tersisa (km) Tingkat konsumsi bahan bakar (obd) - Tingkat konsumsi bahan bakar l/j + Tingkat konsumsi bahan bakar L/j Tingkat konsumsi bahan bakar %/j Menyediakan panduan rute waktu nyata, termasuk jarak belokan berikutnya, nama jalan, nama jalan saat ini, dan informasi jalur. Widget aktif selama navigasi. Tidak ada pemindai yang ditemukan @@ -5980,7 +5980,7 @@ Mencari pemindai Lupakan pemindai Pemindai akan dihapus dari daftar. Anda akan dapat menyandingkan pemindai ini lagi kapan pun. - Tingkat konsumsi bahan bakar (l/j) + Tingkat konsumsi bahan bakar (L/j) 1. Hubungkan pemindai ke porta OBD-II kendaraan Anda.\n\n 2. Nyalakan mesin kendaraan Anda\n\n 3. Aktifkan Bluetooth di perangkat Anda\n\n 4. Ketuk \'%1$s\' dan pilih pemindai Anda dari daftar. Maksimum l @@ -5988,13 +5988,13 @@ Ikon berubah berdasarkan keadaan tindakan. Tidak dapat memulai penyandingan dengan perangkat Menampilkan tingkat konsumsi bahan bakar kendaraan berdasarka perhitungan (%/j) - l/100km - Tingkat konsumsi bahan bakar (l/km) + L/100km + Tingkat konsumsi bahan bakar (L/km) Terputus dari %s Terhubung ke %s Dinamis Menghubungkan ke %s - Menampilkan tingkat konsumsi bahan bakar kendaraan berdasarkan perhitungan (l/km) + Menampilkan tingkat konsumsi bahan bakar kendaraan berdasarkan perhitungan (L/km) Simulasikan data obd kPa Tekanan bahan bakar diff --git a/OsmAnd/res/values-is/strings.xml b/OsmAnd/res/values-is/strings.xml index 096c950e812..0b09ecc2018 100644 --- a/OsmAnd/res/values-is/strings.xml +++ b/OsmAnd/res/values-is/strings.xml @@ -5492,7 +5492,7 @@ Viðmót Víxlhnappur til að fara á fyrri skjá. Flakka - l/klst + L/klst Leitarsýn Bæta viðmótshluta til vinstri Úthlutun lykils fyrir valda aðgerð verður hreinsuð. @@ -5511,7 +5511,7 @@ Birtir vegalengdina í gegnum OBD-skynjara sem farartæki getur keyrt með því eldsneyti sem eftir er Birtir gerð eldsneytis á farartæki í gegnum OBD-skynjara Birtir eldsneytiseyðslu farartækis út frá OBD-skynjara og staðsetningu - Gefur aðgang að upplýsingum farartækis í gegnum OBD-II samskiptamáta. Fáðu aðgang að gögnum á borð við: * Snúningshraða vélar * Eldsnytiseyðslu* Eldsneytisbirgðum * Vegalengd síðan vél var ræst * Inntakshita * Umhverfishita * Kælihita * Hraða farartækis * Hleðsluprósentu rafhlöðu + Gefur aðgang að upplýsingum farartækis í gegnum OBD-II samskiptamáta. Fáðu aðgang að gögnum á borð við:\n • Snúningshraða vélar, Keyrslutíma vélar, álag á vél\n • Eldsnytiseyðslu, þrýstingi eldsneytis, eldsneytisbirgðum\n • Inntakshita, umhverfishita, kælihita, hita á vélaolíu\n • Hraða farartækis, stöðu inngjafar, hleðsluprósentu rafhlöðu\n Tvinn-dísel Tvinn-rafmagns Tveggja eldsneytistegunda farartæki sem keyrir á etanóli @@ -5569,27 +5569,27 @@ Skynjari verður fjarlægður af listanum. Þú munt geta parað þennan skynjara aftur hvenær sem er. Breytilegt Tengt við %s - l/100km + L/100km Táknmynd breytist eftir stöðu aðgerðar. Hámark l %/klst - Eldsneytiseyðsla (l/klst) + Eldsneytiseyðsla (L/klst) Eldsneytiseyðsla (skynjari) - Birtir eldsneytiseyðslu farartækis út frá útreikningum (l/klst) + Birtir eldsneytiseyðslu farartækis út frá útreikningum (L/klst) Magn eldsneytis (l) - Birtir eldsneytiseyðslu farartækis út frá skynjara (l/klst) + Birtir eldsneytiseyðslu farartækis út frá skynjara (L/klst) 1. Tengdu skynjarann í OBD-II gátt farartækisins.\n\n 2. Kveiktu á vél farartækisins\n\n 3. Virkjaðu Bluetooth á tækinu þínu\n\n 4. Ýttu á \'%1$s\' og veldu skynjarann þinn úr listanum. Magn eldsneytis (%) - Eldsneytiseyðsla l/klst + Hraði eldsneytiseyðslu Birtir eldsneytiseyðslu farartækis út frá útreikningum (%/klst) - Birtir eldsneytiseyðslu farartækis út frá útreikningum (l/km) + Birtir eldsneytiseyðslu farartækis út frá útreikningum (L/km) Þrýstingur eldsneytis Líkja eftir OBD-gögnum Aftengt frá %s Tengist við %s Mistókst að setja af stað pörun við tækið - Eldsneytiseyðsla (l/km) + Eldsneytiseyðsla (L/km) Eldsneytiseyðsla (%/klst Gleyma skynjara Sýnir hitastigið fyrir utan farartækið. diff --git a/OsmAnd/res/values-sr/strings.xml b/OsmAnd/res/values-sr/strings.xml index 8e45a614d4b..6cb6f983604 100644 --- a/OsmAnd/res/values-sr/strings.xml +++ b/OsmAnd/res/values-sr/strings.xml @@ -5551,7 +5551,7 @@ Врста горива Метрика возила ДНВ подршка - Пратите кључне метрике возила користећи ДНВ-ИИ протокол. Приступ подацима укључујући: * Брзина мотора * Потрошња горива * Преостало гориво * Раздаљина од покретања мотора * Топлота усиса * Топлота околине * Температура расхладне течности * Брзина возила * Проценат батерије + Пратите кључне метрике возила користећи ДНВ-ИИ протокол. Приступ подацима укључујући:\n • Брзина мотора, време рада мотора, израчунато оптерећење мотора \n • Потрошња горива, Притисак горива, Преостало гориво\n • Усисна температура, температура околине, температура расхладне течности, температура моторног уља\n • Брзина возила, положај гаса, напон батерије\n Двогоривно покретано водоником Показује раздаљину коју возило може да пређе са преосталим горивом преко пријемника ОБД Непознати уређај @@ -5577,7 +5577,7 @@ Омогућава или онемогућава функцију екрана осетљивог на додир да спречи случајне додире Дугме за приказ или сакривање местних измена ОСМ-а на карти. Стазе теренских мотоцикла - l/h + L/h • Додан је прегледник слика преко целог заслона за слике Викимедије\n\n • Уведен је нови додатак „Метрика возила“ за праћење учинка возила користећи ДНВ-ИИ протокол\n\n • Додата могућност додељивања дејстава стазама и одабира у складу са тим\n\n • Примењена су нова брза дејства за снимање путовања и закључавање заслона на додир\n\n • Уведен је прилагодљив изглед дугмета карте и тачна мрежа\n\n • Додат је приручни изборник и дејство „Поништавање просечне брзине“ у справице\n\n • Додан је нови слој путање „Стазе теренских мотоцикла“\n\n • Исправљено је „Самостално снимање стазе током навођења“\n\n • Решен је проблем са преокренутим координатама у РТЛ-у\n\n • Исправљено је пропуштање података пријемника за тренутно снимљени траг\n\n • Додати су подаци о околним подручјима за изабрану тачку\n\n • Додато је брзо дејство за управљање видљивости измена ОСМ-а\n\n • Одвојене су одреднице видљивости за могућности бојења терена\n\n • Додата је сличица која се може додирнути за приказ приступа или других својстава пута или путање Заслон осетљив на додир је закључан. Ради откључавања притисните дугме %1$s или додирните дугме на заслону. Екран осетљив на додир је откључан. @@ -5605,24 +5605,24 @@ Пријемник ће бити уклоњен са списка. Моћи ћете поново да упарите овај пријемник у било ком тренутку. 1. Повежите пријемник са прикључком ДНВ-ИИ свог возила.\n\n 2. Укључите мотор свог возила\n\n 3. Омогућите Блутут на свом уређају\n\n 4. Додирните „%1$s“ и изаберите свој пријемник са списка. Брзина потрошње горива (пријемник) - Приказује потрошњу горива возила на основу прорачуна (l/h) - Приказује потрошњу горива возила на основу пријемника (l/h) + Приказује потрошњу горива возила на основу прорачуна (L/h) + Приказује потрошњу горива возила на основу пријемника (L/h) Ниво горива (l) Ниво горива (%) Преостало гориво (km) Брзина потрошње горива (днв) - Брзина потрошње горива l/h + Брзина потрошње горива L/h Брзина потрошње горива %/h - Брзина потрошње горива (l/h) + Брзина потрошње горива (L/h) l %/h Највише - Приказује потрошњу горива возила на основу прорачуна (l/km) - Потрошња горива (l/km) + Приказује потрошњу горива возила на основу прорачуна (L/km) + Потрошња горива (L/km) Опонашај податке днв kPa Притисак горива - l/100km + L/100km Приказује потрошњу горива возила на основу прорачуна (%/h) Нисам успео да се упарим са уређајем Променљиво diff --git a/OsmAnd/src/net/osmand/core/android/MapRendererContext.java b/OsmAnd/src/net/osmand/core/android/MapRendererContext.java index 138b8a8518e..2132c8cc953 100644 --- a/OsmAnd/src/net/osmand/core/android/MapRendererContext.java +++ b/OsmAnd/src/net/osmand/core/android/MapRendererContext.java @@ -100,19 +100,29 @@ public MapRendererContext(OsmandApplication app, float density) { * * @param mapRendererView Reference to MapRendererView */ - public void setMapRendererView(@Nullable MapRendererView mapRendererView) { - boolean update = (this.mapRendererView != mapRendererView); - if (update && this.mapRendererView != null) - this.mapRendererView.stopRenderer(); - this.mapRendererView = mapRendererView; - if (!update) { + public synchronized void setMapRendererView(@Nullable MapRendererView mapRendererView) { + if (this.mapRendererView == mapRendererView) { return; } + this.mapRendererView = mapRendererView; if (mapRendererView != null) { applyCurrentContextToView(); } } + public synchronized void suspendMapRendererView(@Nullable MapRendererView mapRendererView) { + if (this.mapRendererView != null && (mapRendererView == null || this.mapRendererView == mapRendererView)) { + this.mapRendererView.handleOnPause(); + } + } + + public synchronized void releaseMapRendererView(@Nullable MapRendererView mapRendererView) { + if (this.mapRendererView != null && (mapRendererView == null || this.mapRendererView == mapRendererView)) { + this.mapRendererView.stopRenderer(); + this.mapRendererView = null; + } + } + @Nullable public MapRendererView getMapRendererView() { return mapRendererView; @@ -428,13 +438,15 @@ private void updateObfMapSymbolsProvider(@NonNull MapPrimitivesProvider mapPrimi } } + public void presetMapRendererOptions(@NonNull MapRendererView mapRendererView) { + mapRendererView.setupOptions.setMaxNumberOfRasterMapLayersInBatch(1); + } + private void applyCurrentContextToView() { MapRendererView mapRendererView = this.mapRendererView; if (mapRendererView == null) { return; } - mapRendererView.setMapRendererSetupOptionsConfigurator( - mapRendererSetupOptions -> mapRendererSetupOptions.setMaxNumberOfRasterMapLayersInBatch(1)); if (mapRendererView instanceof AtlasMapRendererView) { cachedReferenceTileSize = getReferenceTileSize(); ((AtlasMapRendererView) mapRendererView).setReferenceTileSizeOnScreenInPixels(cachedReferenceTileSize); @@ -442,6 +454,7 @@ private void applyCurrentContextToView() { updateElevationConfiguration(); if (obfMapRasterLayerProvider != null) { + mapRendererView.resetMapLayerProvider(providerType.layerIndex); mapRendererView.setMapLayerProvider(providerType.layerIndex, obfMapRasterLayerProvider); } if (obfMapSymbolsProvider != null) { diff --git a/OsmAnd/src/net/osmand/plus/AppInitializer.java b/OsmAnd/src/net/osmand/plus/AppInitializer.java index 6d3e9066b79..2964da2aa0f 100644 --- a/OsmAnd/src/net/osmand/plus/AppInitializer.java +++ b/OsmAnd/src/net/osmand/plus/AppInitializer.java @@ -32,6 +32,7 @@ import net.osmand.plus.base.MapViewTrackingUtilities; import net.osmand.plus.base.dialog.DialogManager; import net.osmand.plus.configmap.routes.RouteLayersHelper; +import net.osmand.plus.configmap.tracks.TrackSortModesHelper; import net.osmand.plus.download.local.LocalIndexHelper; import net.osmand.plus.download.local.LocalItem; import net.osmand.plus.feedback.AnalyticsHelper; @@ -332,6 +333,7 @@ public void onCreateApplication() { app.dialogManager = startupInit(new DialogManager(), DialogManager.class); app.routeLayersHelper = startupInit(new RouteLayersHelper(app), RouteLayersHelper.class); app.model3dHelper = startupInit(new Model3dHelper(app), Model3dHelper.class); + app.trackSortModesHelper = startupInit(new TrackSortModesHelper(app), TrackSortModesHelper.class); initOpeningHoursParser(); } diff --git a/OsmAnd/src/net/osmand/plus/OsmandApplication.java b/OsmAnd/src/net/osmand/plus/OsmandApplication.java index c440c6830b8..1bba4177886 100644 --- a/OsmAnd/src/net/osmand/plus/OsmandApplication.java +++ b/OsmAnd/src/net/osmand/plus/OsmandApplication.java @@ -31,6 +31,7 @@ import androidx.multidex.MultiDex; import androidx.multidex.MultiDexApplication; +import net.osmand.plus.configmap.tracks.TrackSortModesHelper; import net.osmand.plus.plugins.OsmandPlugin; import net.osmand.plus.shared.OsmAndContextImpl; import net.osmand.PlatformUtil; @@ -221,6 +222,7 @@ public class OsmandApplication extends MultiDexApplication { DialogManager dialogManager; RouteLayersHelper routeLayersHelper; Model3dHelper model3dHelper; + TrackSortModesHelper trackSortModesHelper; private final Map customRoutingConfigs = new ConcurrentHashMap<>(); private File externalStorageDirectory; @@ -661,6 +663,11 @@ public Model3dHelper getModel3dHelper() { return model3dHelper; } + @NonNull + public TrackSortModesHelper getTrackSortModesHelper() { + return trackSortModesHelper; + } + public CommandPlayer getPlayer() { return player; } diff --git a/OsmAnd/src/net/osmand/plus/auto/SurfaceRenderer.java b/OsmAnd/src/net/osmand/plus/auto/SurfaceRenderer.java index 75b418c4800..fe4c7c5ab9d 100644 --- a/OsmAnd/src/net/osmand/plus/auto/SurfaceRenderer.java +++ b/OsmAnd/src/net/osmand/plus/auto/SurfaceRenderer.java @@ -1,6 +1,7 @@ package net.osmand.plus.auto; import static net.osmand.plus.views.OsmandMapTileView.DEFAULT_ELEVATION_ANGLE; +import static net.osmand.plus.views.MapViewWithLayers.SYMBOLS_UPDATE_INTERVAL; import android.graphics.Canvas; import android.graphics.Color; @@ -331,41 +332,43 @@ public void onFinish(@NonNull AppInitializer init) { setupOffscreenRenderer(); } - public void setupOffscreenRenderer() { + public synchronized void setupOffscreenRenderer() { Log.i(TAG, "setupOffscreenRenderer"); if (getApp().useOpenGlRenderer()) { if (surface != null && surface.isValid()) { if (offscreenMapRendererView != null) { MapRendererContext mapRendererContext = NativeCoreContext.getMapRendererContext(); - if (mapRendererContext != null) { - if (mapRendererContext.getMapRendererView() == offscreenMapRendererView) - return; + if (mapRendererContext != null && mapRendererContext.getMapRendererView() != offscreenMapRendererView) { offscreenMapRendererView = null; } } if (offscreenMapRendererView == null) { - MapRendererView mapRendererView = null; MapRendererContext mapRendererContext = NativeCoreContext.getMapRendererContext(); if (mapRendererContext != null) { - if (mapView != null && mapView.getMapRenderer() != null) - mapView.setMapRenderer(null); + MapRendererView mapRendererView = null; + if (mapView != null && mapView.getMapRenderer() != null) { + mapView.detachMapRenderer(); + } if (mapRendererContext.getMapRendererView() != null) { mapRendererView = mapRendererContext.getMapRendererView(); mapRendererContext.setMapRendererView(null); } - offscreenMapRendererView = new AtlasMapRendererView(carContext); - offscreenMapRendererView.setMapRendererSetupOptionsConfigurator( - mapRendererSetupOptions -> mapRendererSetupOptions.setMaxNumberOfRasterMapLayersInBatch(1)); - offscreenMapRendererView.setupRenderer(carContext, getWidth(), getHeight(), mapRendererView); - offscreenMapRendererView.setMinZoomLevel(ZoomLevel.swigToEnum(mapView.getMinZoom())); - offscreenMapRendererView.setMaxZoomLevel(ZoomLevel.swigToEnum(mapView.getMaxZoom())); - offscreenMapRendererView.setAzimuth(0); - mapView.setMinAllowedElevationAngle(MIN_ALLOWED_ELEVATION_ANGLE_AA); - float elevationAngle = mapView.normalizeElevationAngle(getApp().getSettings().getLastKnownMapElevation()); NativeCoreContext.setMapRendererContext(getApp(), surfaceView.getDensity()); mapRendererContext = NativeCoreContext.getMapRendererContext(); if (mapRendererContext != null) { + offscreenMapRendererView = new AtlasMapRendererView(carContext); + mapRendererContext.presetMapRendererOptions(offscreenMapRendererView); + offscreenMapRendererView.setupRenderer(carContext, getWidth(), getHeight(), mapRendererView); + offscreenMapRendererView.setMinZoomLevel(ZoomLevel.swigToEnum(mapView.getMinZoom())); + offscreenMapRendererView.setMaxZoomLevel(ZoomLevel.swigToEnum(mapView.getMaxZoom())); + offscreenMapRendererView.setAzimuth(0); + offscreenMapRendererView.removeAllSymbolsProviders(); + offscreenMapRendererView.resumeSymbolsUpdate(); + offscreenMapRendererView.setSymbolsUpdateInterval(SYMBOLS_UPDATE_INTERVAL); + offscreenMapRendererView.enableBatterySavingMode(); mapRendererContext.setMapRendererView(offscreenMapRendererView); + mapView.setMinAllowedElevationAngle(MIN_ALLOWED_ELEVATION_ANGLE_AA); + float elevationAngle = mapView.normalizeElevationAngle(getApp().getSettings().getLastKnownMapElevation()); mapView.setMapRenderer(offscreenMapRendererView); mapView.setElevationAngle(elevationAngle); mapView.addElevationListener(this); @@ -374,28 +377,27 @@ public void setupOffscreenRenderer() { offscreenMapRendererView.addListener(this); mapView.getAnimatedDraggingThread().toggleAnimations(); } - offscreenMapRendererView.enableBatterySavingMode(); } } } } } - public void stopOffscreenRenderer() { + public synchronized void stopOffscreenRenderer() { Log.i(TAG, "stopOffscreenRenderer"); if (offscreenMapRendererView != null) { - AtlasMapRendererView offscreenMapRendererView = this.offscreenMapRendererView; - this.offscreenMapRendererView = null; if (mapView != null) { mapView.removeElevationListener(this); mapView.getAnimatedDraggingThread().toggleAnimations(); if (mapView.getMapRenderer() == offscreenMapRendererView) { - mapView.setMapRenderer(null); + mapView.detachMapRenderer(); } } MapRendererContext mapRendererContext = NativeCoreContext.getMapRendererContext(); - if (mapRendererContext != null && mapRendererContext.getMapRendererView() == offscreenMapRendererView) - offscreenMapRendererView.stopRenderer(); + if (mapRendererContext != null) { + mapRendererContext.suspendMapRendererView(offscreenMapRendererView); + } + offscreenMapRendererView = null; } } diff --git a/OsmAnd/src/net/osmand/plus/auto/screens/TracksFoldersScreen.kt b/OsmAnd/src/net/osmand/plus/auto/screens/TracksFoldersScreen.kt index 10ccde8c56d..526542d7aa1 100644 --- a/OsmAnd/src/net/osmand/plus/auto/screens/TracksFoldersScreen.kt +++ b/OsmAnd/src/net/osmand/plus/auto/screens/TracksFoldersScreen.kt @@ -81,7 +81,7 @@ class TracksFoldersScreen( .setTitle(app.getString(R.string.sort_last_modified)) .setImage(iconLastModified) .setBrowsable(true) - .setOnClickListener { onClickTabFolder(trackTabsHelper.trackTabs[TrackTabType.ALL.name]!!) } + .setOnClickListener { onClickTabFolder(trackTabsHelper.getTrackTab(TrackTabType.ALL.name)!!) } .build()) if (trackTabsHelper.trackTabs.isEmpty()) { @@ -93,14 +93,14 @@ class TracksFoldersScreen( } templateBuilder.setLoading(false) var itemsCount = 1 - for (trackTab in trackTabsHelper.trackTabs.values) { + for (trackTab in trackTabsHelper.getSortedTrackTabs(false)) { if (trackTab.type != TrackTabType.FOLDER) { continue } if (itemsCount == contentLimit) { break } - val title = trackTab.getName(app) + val title = trackTab.getName() val iconColorId = ColorUtilities.getDefaultIconColorId(app.daynightHelper.isNightMode) val iconDrawable = app.uiUtilities.getIcon(trackTab.type.iconId, iconColorId) val icon = CarIcon.Builder( @@ -131,7 +131,7 @@ class TracksFoldersScreen( } override fun loadTracksFinished(folder: TrackFolder) { - trackTabsHelper.updateTrackItems(folder.getFlattenedTrackItems()) + trackTabsHelper.updateTrackItems(folder) invalidate() } diff --git a/OsmAnd/src/net/osmand/plus/auto/screens/TracksScreen.kt b/OsmAnd/src/net/osmand/plus/auto/screens/TracksScreen.kt index 60cc38ee25f..3b189bb87eb 100644 --- a/OsmAnd/src/net/osmand/plus/auto/screens/TracksScreen.kt +++ b/OsmAnd/src/net/osmand/plus/auto/screens/TracksScreen.kt @@ -83,7 +83,7 @@ class TracksScreen( val title = if (trackTab.type == TrackTabType.ALL) { app.getString(R.string.sort_last_modified) } else { - trackTab.getName(app) + trackTab.getName() } val isLoading = loadTracksTask.status != AsyncTask.Status.FINISHED templateBuilder.setLoading(isLoading) diff --git a/OsmAnd/src/net/osmand/plus/configmap/tracks/PreselectedTabParams.java b/OsmAnd/src/net/osmand/plus/configmap/tracks/PreselectedTabParams.java index b4ab9117e06..d1d7b446253 100644 --- a/OsmAnd/src/net/osmand/plus/configmap/tracks/PreselectedTabParams.java +++ b/OsmAnd/src/net/osmand/plus/configmap/tracks/PreselectedTabParams.java @@ -1,33 +1,19 @@ package net.osmand.plus.configmap.tracks; -import static net.osmand.plus.configmap.tracks.TrackTabType.SMART_FOLDER; - -import android.content.Context; - import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import net.osmand.util.Algorithms; - -import java.util.Collections; -import java.util.List; public class PreselectedTabParams { - public static final String PRESELECTED_TRACKS_TAB_NAME = "preselected_tab_name"; - public static final String PRESELECTED_TRACKS_TAB_TYPE = "preselected_tab_type"; + public static final String PRESELECTED_TRACKS_TAB_ID = "preselected_tab_id"; public static final String SELECT_ALL_ITEMS_ON_TAB = "select_all_items_on_tab"; public static final String CALLING_FRAGMENT_TAG = "calling_fragment_tag"; @NonNull - private final String name; - @NonNull - private final TrackTabType type; + private final String id; private final boolean selectAll; - public PreselectedTabParams(@NonNull String name, @NonNull TrackTabType type, boolean selectAll) { - this.name = name; - this.type = type; + public PreselectedTabParams(@NonNull String id, boolean selectAll) { + this.id = id; this.selectAll = selectAll; } @@ -36,16 +22,7 @@ public boolean shouldSelectAll() { } @NonNull - public String getPreselectedTabName(@NonNull Context context, @NonNull List trackTabs) { - if (type == SMART_FOLDER) { - for (TrackTab tab : trackTabs) { - String tabName = tab.getName(context); - if (tab.type == SMART_FOLDER && Algorithms.stringsEqual(tabName, name)) { - return tab.getTypeName(); - } - } - return ""; - } - return name; + public String getPreselectedTabId() { + return id; } } \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/configmap/tracks/SelectTrackTabsHelper.java b/OsmAnd/src/net/osmand/plus/configmap/tracks/SelectTrackTabsHelper.java new file mode 100644 index 00000000000..27e707fb17d --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/configmap/tracks/SelectTrackTabsHelper.java @@ -0,0 +1,21 @@ +package net.osmand.plus.configmap.tracks; + +import androidx.annotation.NonNull; + +import net.osmand.plus.OsmandApplication; +import net.osmand.shared.gpx.data.TrackFolder; + +public class SelectTrackTabsHelper extends TrackTabsHelper { + + public SelectTrackTabsHelper(@NonNull OsmandApplication app) { + super(app); + } + + @Override + protected void updateTrackTabs(@NonNull TrackFolder rootFolder) { + trackTabs.clear(); + trackTabs.put(TrackTabType.ON_MAP.name(), getTracksOnMapTab()); + trackTabs.put(TrackTabType.ALL.name(), getAllTracksTab()); + trackTabs.put(TrackTabType.FOLDERS.name(), getFoldersTab(rootFolder)); + } +} diff --git a/OsmAnd/src/net/osmand/plus/configmap/tracks/TrackFolderLoaderTask.java b/OsmAnd/src/net/osmand/plus/configmap/tracks/TrackFolderLoaderTask.java index b592fa8d017..3cd70776fa6 100644 --- a/OsmAnd/src/net/osmand/plus/configmap/tracks/TrackFolderLoaderTask.java +++ b/OsmAnd/src/net/osmand/plus/configmap/tracks/TrackFolderLoaderTask.java @@ -66,7 +66,7 @@ protected void onProgressUpdate(TrackItem... items) { @Override protected Void doInBackground(Void... voids) { long start = System.currentTimeMillis(); - LOG.info("Start loading tracks in " + folder.getDirName()); + LOG.info("Start loading tracks in " + folder.getDirName(true)); folder.clearData(); loadingTime = System.currentTimeMillis(); diff --git a/OsmAnd/src/net/osmand/plus/configmap/tracks/TrackGroupsBottomSheet.java b/OsmAnd/src/net/osmand/plus/configmap/tracks/TrackGroupsBottomSheet.java index 3874b86d0b8..ae007df96ee 100644 --- a/OsmAnd/src/net/osmand/plus/configmap/tracks/TrackGroupsBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/configmap/tracks/TrackGroupsBottomSheet.java @@ -42,9 +42,8 @@ public void onCreate(@Nullable Bundle savedInstanceState) { nightMode = isNightMode(true); Fragment target = getTargetFragment(); - if (target instanceof TracksTabsFragment) { - TracksTabsFragment fragment = (TracksTabsFragment) target; - trackTabs = fragment.getTrackTabs(); + if (target instanceof TracksTabsFragment fragment) { + trackTabs = fragment.getSortedTrackTabs(true); selectedTab = fragment.getSelectedTab(); } } @@ -87,7 +86,7 @@ public TrackGroupViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int vi public void onBindViewHolder(@NonNull TrackGroupViewHolder holder, int position) { TrackTab trackTab = trackTabs.get(position); - holder.title.setText(trackTab.getName(app, true)); + holder.title.setText(trackTab.getDirName(true)); boolean selected = trackTab == selectedTab; int colorId = selected ? activeColorId : defaultColorId; @@ -101,7 +100,7 @@ public void onBindViewHolder(@NonNull TrackGroupViewHolder holder, int position) int adapterPosition = holder.getAdapterPosition(); if (adapterPosition != RecyclerView.NO_POSITION && target instanceof TracksTabsFragment) { TrackTab tab = trackTabs.get(adapterPosition); - ((TracksTabsFragment) target).setSelectedTab(tab.getTypeName()); + ((TracksTabsFragment) target).setSelectedTab(tab.getId()); } dismiss(); }); diff --git a/OsmAnd/src/net/osmand/plus/configmap/tracks/TrackItemsFragment.java b/OsmAnd/src/net/osmand/plus/configmap/tracks/TrackItemsFragment.java index da2bbb77b3c..35d28591c2d 100644 --- a/OsmAnd/src/net/osmand/plus/configmap/tracks/TrackItemsFragment.java +++ b/OsmAnd/src/net/osmand/plus/configmap/tracks/TrackItemsFragment.java @@ -27,9 +27,9 @@ public class TrackItemsFragment extends BaseOsmAndFragment implements OsmAndComp public static final String TAG = TrackItemsFragment.class.getSimpleName(); - private static final String TRACK_TAB_NAME_KEY = "track_tab_name_key"; + private static final String TRACK_TAB_ID_KEY = "track_tab_id_key"; - private String trackTabName; + private String trackTabId; private TracksAdapter adapter; private RecyclerView recyclerView; @@ -79,11 +79,11 @@ private void setupAdapter(@NonNull TrackTab trackTab) { @Nullable public TrackTab getTrackTab() { BaseTracksTabsFragment fragment = (BaseTracksTabsFragment) requireParentFragment(); - return fragment.getTab(trackTabName); + return fragment.getTab(trackTabId); } public void setTrackTab(@NonNull TrackTab trackTab) { - this.trackTabName = trackTab.getTypeName(); + this.trackTabId = trackTab.getId(); } @Override @@ -118,7 +118,7 @@ public void onPause() { @Override public void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); - outState.putString(TRACK_TAB_NAME_KEY, trackTabName); + outState.putString(TRACK_TAB_ID_KEY, trackTabId); } @Override diff --git a/OsmAnd/src/net/osmand/plus/configmap/tracks/TrackSortModesHelper.java b/OsmAnd/src/net/osmand/plus/configmap/tracks/TrackSortModesHelper.java new file mode 100644 index 00000000000..03d67f37644 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/configmap/tracks/TrackSortModesHelper.java @@ -0,0 +1,119 @@ +package net.osmand.plus.configmap.tracks; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import net.osmand.IndexConstants; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.settings.backend.OsmandSettings; +import net.osmand.plus.settings.backend.preferences.ListStringPreference; +import net.osmand.plus.settings.enums.TracksSortMode; +import net.osmand.shared.gpx.data.TrackFolder; +import net.osmand.util.Algorithms; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; + +public class TrackSortModesHelper { + + private static final String ROOT_FOLDER = IndexConstants.GPX_INDEX_DIR; + private static final String SEPARATOR = ",,"; + + private final Map cachedSortModes = new ConcurrentHashMap<>(); + private final ListStringPreference preference; + + public TrackSortModesHelper(@NonNull OsmandApplication app) { + OsmandSettings settings = app.getSettings(); + preference = settings.TRACKS_TABS_SORT_MODES; + loadFromPreference(app); + } + + @NonNull + public TracksSortMode getRootFolderSortMode() { + return requireSortMode(""); + } + + @NonNull + public TracksSortMode requireSortMode(@Nullable String id) { + TracksSortMode sortMode = getSortMode(id); + return sortMode != null ? sortMode : TracksSortMode.getDefaultSortMode(); + } + + @Nullable + public TracksSortMode getSortMode(@Nullable String id) { + id = removeExtraFileSeparator(id); + return cachedSortModes.get(id); + } + + public void setSortMode(@NonNull String id, @NonNull TracksSortMode sortMode) { + id = removeExtraFileSeparator(id); + cachedSortModes.put(id, sortMode); + } + + public void setSortModes(@NonNull Map sortModes) { + cachedSortModes.clear(); + cachedSortModes.putAll(sortModes); + } + + public void updateAfterMoveTrackFolder(@NonNull TrackFolder trackFolder, @NonNull File oldDir) { + String previousId = getFolderId(oldDir.getAbsolutePath()); + TracksSortMode sortMode = getSortMode(previousId); + if (sortMode != null) { + setSortMode(trackFolder.getId(), sortMode); + syncSettings(); + } + } + + public void updateAfterDeleteTrackFolder(@NonNull TrackFolder trackFolder) { + cachedSortModes.remove(trackFolder.getId()); + syncSettings(); + } + + public void syncSettings() { + saveToPreference(); + } + + private void loadFromPreference(@NonNull OsmandApplication app) { + List tokens = preference.getStringsList(); + if (!Algorithms.isEmpty(tokens)) { + for (String token : tokens) { + String[] tokenParts = token.split(SEPARATOR); + if (tokenParts.length == 2) { + cachedSortModes.put(tokenParts[0], TracksSortMode.getByValue(tokenParts[1])); + } + } + UpgradeTrackSortModeKeysAlgorithm.execute(app, this); + } + } + + private void saveToPreference() { + List tokens = new ArrayList<>(); + for (Entry entry : cachedSortModes.entrySet()) { + tokens.add(entry.getKey() + SEPARATOR + entry.getValue().name()); + } + preference.setStringsList(tokens); + } + + @NonNull + public static String getFolderId(@NonNull String absolutePath) { + int index = absolutePath.indexOf(ROOT_FOLDER); + if (index > 0) { + index += ROOT_FOLDER.length(); + } + return index > 0 ? absolutePath.substring(index) : absolutePath; + } + + @Nullable + private static String removeExtraFileSeparator(@Nullable String id) { + // Ensure consistency by removing trailing File.separator from relative paths + // before querying or saving to settings to avoid key mismatches. + if (id != null && id.endsWith(File.separator)) { + return id.substring(0, id.length() - 1); + } + return id; + } +} diff --git a/OsmAnd/src/net/osmand/plus/configmap/tracks/TrackTab.java b/OsmAnd/src/net/osmand/plus/configmap/tracks/TrackTab.java index 2d268606f58..fbc66a5c198 100644 --- a/OsmAnd/src/net/osmand/plus/configmap/tracks/TrackTab.java +++ b/OsmAnd/src/net/osmand/plus/configmap/tracks/TrackTab.java @@ -1,52 +1,95 @@ package net.osmand.plus.configmap.tracks; +import static net.osmand.plus.configmap.tracks.TrackTabType.FOLDER; +import static net.osmand.plus.configmap.tracks.TrackTabType.SMART_FOLDER; + import android.content.Context; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import net.osmand.plus.settings.enums.TracksSortMode; +import net.osmand.shared.gpx.data.ComparableTracksGroup; import net.osmand.shared.gpx.data.SmartFolder; import net.osmand.shared.gpx.data.TrackFolder; import net.osmand.plus.track.helpers.GpxUiHelper; import net.osmand.shared.gpx.TrackItem; +import net.osmand.shared.gpx.data.TracksGroup; +import net.osmand.shared.gpx.filters.TrackFolderAnalysis; import java.io.File; import java.util.ArrayList; import java.util.List; -public class TrackTab { - public static final String SMART_FOLDER_TAB_NAME_PREFIX = "SMART_FOLDER___"; +public class TrackTab implements TracksGroup, ComparableTracksGroup { + @NonNull public final TrackTabType type; public final List items = new ArrayList<>(); @Nullable public final File directory; - @Nullable - private final String name; - private String typeName = null; + public final SmartFolder smartFolder; + public final String initialName; private TracksSortMode sortMode = TracksSortMode.getDefaultSortMode(); + private TrackFolderAnalysis analysis = null; - public TrackTab(@NonNull File directory) { - this.directory = directory; - this.name = null; - this.type = TrackTabType.FOLDER; + public TrackTab(@NonNull Context context, @NonNull File directory) { + this(context, directory, null, FOLDER); + } + + public TrackTab(@NonNull Context context, @NonNull SmartFolder smartFolder) { + this(context, null, smartFolder, SMART_FOLDER); } - public TrackTab(@NonNull TrackTabType type) { - this.directory = null; - this.name = null; + public TrackTab(@NonNull Context context, @NonNull TrackTabType type) { + this(context, null, null, type); + } + + private TrackTab(@NonNull Context context, @Nullable File directory, + @Nullable SmartFolder smartFolder, @NonNull TrackTabType type) { + this.directory = directory; + this.smartFolder = smartFolder; this.type = type; + this.initialName = createInitialName(context); + } + + @NonNull + private String createInitialName(@NonNull Context context) { + if (type.titleId != -1) { + return context.getString(type.titleId); + } + if (directory != null) { + return GpxUiHelper.getFolderName(context, directory); + } + if (smartFolder != null) { + return smartFolder.getFolderName(); + } + return ""; + } + + @NonNull + @Override + public String getId() { + return switch (type) { + case FOLDER -> directory != null ? TrackSortModesHelper.getFolderId(directory.getAbsolutePath()) : ""; + case SMART_FOLDER -> smartFolder != null ? smartFolder.getId() : ""; + default -> type.name(); + }; } - public TrackTab(@NonNull SmartFolder smartFolder) { - this.directory = null; - this.name = smartFolder.getFolderName(); - this.type = TrackTabType.SMART_FOLDER; - typeName = SMART_FOLDER_TAB_NAME_PREFIX + name; + @NonNull + @Override + public TrackFolderAnalysis getFolderAnalysis() { + // Note: To avoid excessive calculations that could slow down the UI, + // analysis is not recalculated when folder or track parameters change. + // For example after file deletion or moving to another directory. + if (analysis == null) { + analysis = smartFolder != null ? smartFolder.getFolderAnalysis() : new TrackFolderAnalysis(this); + } + return analysis; } @NonNull @@ -59,34 +102,22 @@ public void setSortMode(@NonNull TracksSortMode sortMode) { } @NonNull - public String getName(@NonNull Context context) { - return getName(context, false); + @Override + public String getName() { + return getDirName(false); } @NonNull - public String getName(@NonNull Context context, boolean includeParentDir) { - if (type.titleId != -1) { - return context.getString(type.titleId); - } - if (directory != null) { - return GpxUiHelper.getFolderName(context, directory, includeParentDir); - } - if (name != null) { - return name; - } - return ""; + @Override + public String getDirName(boolean includingSubdirs) { + return directory != null && includingSubdirs + ? GpxUiHelper.getFolderPath(directory, initialName) + : initialName; } - @NonNull - public String getTypeName() { - switch (type) { - case FOLDER: - return directory != null ? directory.getName() : ""; - case SMART_FOLDER: - return typeName != null ? typeName : ""; - default: - return type.name(); - } + @Override + public int getDefaultOrder() { + return type.ordinal(); } @NonNull @@ -111,9 +142,20 @@ public List getTrackFolders() { return trackFolders; } + @Override + public long lastModified() { + if (directory != null) { + return directory.lastModified(); + } + if (smartFolder != null) { + return smartFolder.lastModified(); + } + return 0; + } + @NonNull @Override public String toString() { - return "TrackTab{name=" + getTypeName() + "}"; + return "TrackTab{name=" + getId() + "}"; } } diff --git a/OsmAnd/src/net/osmand/plus/configmap/tracks/TrackTabType.java b/OsmAnd/src/net/osmand/plus/configmap/tracks/TrackTabType.java index 63b4ed63c5c..cdfda0dd3d0 100644 --- a/OsmAnd/src/net/osmand/plus/configmap/tracks/TrackTabType.java +++ b/OsmAnd/src/net/osmand/plus/configmap/tracks/TrackTabType.java @@ -9,8 +9,8 @@ public enum TrackTabType { ON_MAP(R.string.shared_string_on_map, R.drawable.ic_show_on_map), ALL(R.string.shared_string_all, R.drawable.ic_action_list_header), - FOLDER(-1, R.drawable.ic_action_folder), SMART_FOLDER(-1, R.drawable.ic_action_folder_smart), + FOLDER(-1, R.drawable.ic_action_folder), FOLDERS(R.string.shared_string_folders, R.drawable.ic_action_folder); diff --git a/OsmAnd/src/net/osmand/plus/configmap/tracks/TrackTabsHelper.java b/OsmAnd/src/net/osmand/plus/configmap/tracks/TrackTabsHelper.java index 2c334f04c72..a4531733252 100644 --- a/OsmAnd/src/net/osmand/plus/configmap/tracks/TrackTabsHelper.java +++ b/OsmAnd/src/net/osmand/plus/configmap/tracks/TrackTabsHelper.java @@ -8,14 +8,10 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import net.osmand.Collator; -import net.osmand.IndexConstants; -import net.osmand.OsmAndCollator; import net.osmand.plus.shared.SharedUtil; import net.osmand.data.LatLon; import net.osmand.shared.gpx.GpxFile; import net.osmand.plus.OsmandApplication; -import net.osmand.plus.R; import net.osmand.plus.myplaces.tracks.ItemsSelectionHelper; import net.osmand.plus.plugins.PluginsHelper; import net.osmand.plus.plugins.monitoring.OsmandMonitoringPlugin; @@ -30,6 +26,7 @@ import net.osmand.util.Algorithms; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.LinkedHashMap; @@ -46,8 +43,7 @@ public class TrackTabsHelper { private final ItemsSelectionHelper itemsSelectionHelper; private final Set recentlyVisibleTrackItem = new HashSet<>(); - private final Map trackTabs = new LinkedHashMap<>(); - private final Collator collator = OsmAndCollator.primaryCollator(); + protected final Map trackTabs = new LinkedHashMap<>(); public TrackTabsHelper(@NonNull OsmandApplication app) { this.app = app; @@ -62,90 +58,73 @@ public ItemsSelectionHelper getItemsSelectionHelper() { } @NonNull - public Map getTrackTabs() { - return trackTabs; + public List getSortedTrackTabs(boolean useSubdirs) { + List result = getTrackTabs(); + result.sort(new TracksComparator(getRootSortMode(), getDefaultLocation(), useSubdirs)); + return result; } @NonNull - public Set getRecentlyVisibleTracks() { - return new HashSet<>(recentlyVisibleTrackItem); + public List getTrackTabs() { + return new ArrayList<>(trackTabs.values()); } - public void updateTrackItems(@NonNull List trackItems) { - List allTrackItems = new ArrayList<>(trackItems); - if (settings.SAVE_GLOBAL_TRACK_TO_GPX.get() || gpxSelectionHelper.getSelectedCurrentRecordingTrack() != null) { - SelectedGpxFile selectedGpxFile = app.getSavingTrackHelper().getCurrentTrack(); - TrackItem trackItem = new TrackItem(selectedGpxFile.getGpxFile()); - allTrackItems.add(trackItem); - } - itemsSelectionHelper.setAllItems(allTrackItems); - Map trackTabs = new LinkedHashMap<>(); - for (TrackItem item : trackItems) { - addTrackItem(trackTabs, item); - } - updateTrackTabs(trackTabs); + @Nullable + public TrackTab getTrackTab(@NonNull String id) { + return trackTabs.get(id); } - public void updateItems(@NonNull TrackFolder folder){ - List allTrackItems = new ArrayList<>(folder.getFlattenedTrackItems()); - if (settings.SAVE_GLOBAL_TRACK_TO_GPX.get() || gpxSelectionHelper.getSelectedCurrentRecordingTrack() != null) { - SelectedGpxFile selectedGpxFile = app.getSavingTrackHelper().getCurrentTrack(); - TrackItem trackItem = new TrackItem(selectedGpxFile.getGpxFile()); - allTrackItems.add(trackItem); - } - itemsSelectionHelper.setAllItems(allTrackItems); - updateSelectTrackTabs(folder); + @NonNull + public Set getRecentlyVisibleTracks() { + return new HashSet<>(recentlyVisibleTrackItem); } - private void updateTrackTabs(@NonNull Map folderTabs) { + public void updateTrackItems(@NonNull TrackFolder rootFolder) { + List allTrackItems = new ArrayList<>(rootFolder.getFlattenedTrackItems()); + addCurrentTrackItemIfPresent(allTrackItems); + itemsSelectionHelper.setAllItems(allTrackItems); + processVisibleTracks(); processRecentlyVisibleTracks(); + + updateTrackTabs(rootFolder); + loadTabsSortModes(); + sortTrackTabsContent(); + } + + protected void updateTrackTabs(@NonNull TrackFolder rootFolder) { trackTabs.clear(); trackTabs.put(TrackTabType.ON_MAP.name(), getTracksOnMapTab()); trackTabs.put(TrackTabType.ALL.name(), getAllTracksTab()); - for (TrackTab tab : sortTrackTabs(getAllSmartFoldersTabs())) { - trackTabs.put(tab.getTypeName(), tab); + for (TrackTab tab : getAllSmartFoldersTabs()) { + trackTabs.put(tab.getId(), tab); } - for (TrackTab tab : sortTrackTabs(folderTabs)) { - trackTabs.put(tab.getTypeName(), tab); + for (TrackTab tab : getAllTrackFoldersTabs(rootFolder)) { + trackTabs.put(tab.getId(), tab); } - loadTabsSortModes(); - sortTrackTabs(); } - private List sortTrackTabs(Map folderTabs) { - List sortedTabs = new ArrayList<>(folderTabs.values()); - Map tabsSortModes = settings.getTrackSortModes(); - TracksSortMode sortMode = TracksSortMode.getDefaultSortMode(); - String trackRootDir = app.getAppPath(IndexConstants.GPX_INDEX_DIR).getName(); - String sortModeKey = tabsSortModes.get(trackRootDir); - if (sortModeKey != null) { - sortMode = TracksSortMode.getByValue(sortModeKey); + private void addCurrentTrackItemIfPresent(@NonNull List trackItems) { + if (settings.SAVE_GLOBAL_TRACK_TO_GPX.get() || gpxSelectionHelper.getSelectedCurrentRecordingTrack() != null) { + SelectedGpxFile selectedGpxFile = app.getSavingTrackHelper().getCurrentTrack(); + TrackItem trackItem = new TrackItem(selectedGpxFile.getGpxFile()); + trackItems.add(trackItem); } - int sign = sortMode == TracksSortMode.NAME_DESCENDING ? -1 : 1; - // PRELIMINARY: Should ultimately use TracksComparator for trackTabs, similar to trackFolders - Collections.sort(sortedTabs, (tab1, tab2) -> { - String name1 = tab1.getTypeName(); - String name2 = tab2.getTypeName(); - return sign * collator.compare(name1, name2); - }); - return sortedTabs; } - private void updateSelectTrackTabs(@NonNull TrackFolder folder) { - processVisibleTracks(); - processRecentlyVisibleTracks(); - trackTabs.clear(); - trackTabs.put(app.getString(R.string.shared_string_visible), getTracksOnMapTab()); - trackTabs.put(app.getString(R.string.shared_string_all_tracks), getAllTracksTab()); - trackTabs.put(app.getString(R.string.shared_string_folders), getFoldersTab(folder)); - loadTabsSortModes(); - sortTrackTabs(); + @NonNull + private Collection getAllTrackFoldersTabs(@NonNull TrackFolder rootFolder) { + List trackItems = rootFolder.getFlattenedTrackItems(); + Map trackFolderTabs = new LinkedHashMap<>(); + for (TrackItem item : trackItems) { + addTrackItem(trackFolderTabs, item); + } + return trackFolderTabs.values(); } @NonNull - private TrackTab getTracksOnMapTab() { - TrackTab trackTab = new TrackTab(TrackTabType.ON_MAP); + protected TrackTab getTracksOnMapTab() { + TrackTab trackTab = new TrackTab(app, TrackTabType.ON_MAP); trackTab.items.addAll(getOnMapTabItems()); return trackTab; } @@ -157,8 +136,8 @@ public void updateTracksOnMap() { } @NonNull - private TrackTab getAllTracksTab() { - TrackTab trackTab = new TrackTab(TrackTabType.ALL); + protected TrackTab getAllTracksTab() { + TrackTab trackTab = new TrackTab(app, TrackTabType.ALL); trackTab.items.addAll(getAllTabItems()); return trackTab; } @@ -187,8 +166,8 @@ private List getAllTabItems() { } @NonNull - private TrackTab getFoldersTab(@NonNull TrackFolder folder) { - TrackTab trackTab = new TrackTab(TrackTabType.FOLDERS); + protected TrackTab getFoldersTab(@NonNull TrackFolder folder) { + TrackTab trackTab = new TrackTab(app, TrackTabType.FOLDERS); trackTab.items.add(TYPE_SORT_TRACKS); trackTab.items.addAll(folder.getSubFolders()); trackTab.items.addAll(folder.getTrackItems()); @@ -245,13 +224,13 @@ public void processVisibleTracks() { } @NonNull - private Map getAllSmartFoldersTabs() { - Map smartFoldersTabs = new LinkedHashMap<>(); + private List getAllSmartFoldersTabs() { + List smartFoldersTabs = new ArrayList<>(); for (SmartFolder folder : app.getSmartFolderHelper().getSmartFolders()) { - TrackTab folderTab = new TrackTab(folder); + TrackTab folderTab = new TrackTab(app, folder); folderTab.items.add(TYPE_SORT_TRACKS); folderTab.items.addAll(folder.getTrackItems()); - smartFoldersTabs.put(folderTab.getTypeName(), folderTab); + smartFoldersTabs.add(folderTab); } return smartFoldersTabs; } @@ -261,12 +240,13 @@ private TrackTab addTrackItem(@NonNull Map trackTabs, @NonNull KFile file = item.getFile(); if (file != null && file.getParentFile() != null) { KFile dir = file.getParentFile(); - if(dir != null) { - TrackTab trackTab = trackTabs.get(dir.name()); + if (dir != null) { + String folderId = TrackSortModesHelper.getFolderId(dir.absolutePath()); + TrackTab trackTab = trackTabs.get(folderId); if (trackTab == null) { - trackTab = new TrackTab(SharedUtil.jFile(dir)); + trackTab = new TrackTab(app, SharedUtil.jFile(dir)); trackTab.items.add(TYPE_SORT_TRACKS); - trackTabs.put(trackTab.getTypeName(), trackTab); + trackTabs.put(folderId, trackTab); } trackTab.items.add(item); return trackTab; @@ -300,14 +280,14 @@ public void saveTracksVisibility() { gpxSelectionHelper.saveTracksVisibility(itemsSelectionHelper.getSelectedItems()); } - private void sortTrackTabs() { + private void sortTrackTabsContent() { for (TrackTab trackTab : trackTabs.values()) { sortTrackTab(trackTab); } } public void sortTrackTab(@NonNull TrackTab trackTab) { - LatLon latLon = app.getMapViewTrackingUtilities().getDefaultLocation(); + LatLon latLon = getDefaultLocation(); if (trackTab.type == TrackTabType.ON_MAP) { List visibleItems = getVisibleItems(); List recentlyVisibleItems = getRecentlyVisibleItems(); @@ -326,24 +306,31 @@ public void sortTrackTab(@NonNull TrackTab trackTab) { } public void loadTabsSortModes() { - Map tabsSortModes = settings.getTrackSortModes(); - if (!Algorithms.isEmpty(tabsSortModes)) { - for (Entry entry : tabsSortModes.entrySet()) { - TrackTab trackTab = trackTabs.get(entry.getKey()); - if (trackTab != null) { - trackTab.setSortMode(TracksSortMode.getByValue(entry.getValue())); - } + TrackSortModesHelper sortModes = app.getTrackSortModesHelper(); + for (Entry entry : trackTabs.entrySet()) { + TracksSortMode sortMode = sortModes.getSortMode(entry.getKey()); + if (sortMode != null) { + TrackTab trackTab = entry.getValue(); + trackTab.setSortMode(sortMode); } } } public void saveTabsSortModes() { - Map tabsSortModes = settings.getTrackSortModes(); + TrackSortModesHelper sortModesHelper = app.getTrackSortModesHelper(); for (TrackTab trackTab : trackTabs.values()) { - String name = trackTab.getTypeName(); - String sortType = trackTab.getSortMode().name(); - tabsSortModes.put(name, sortType); + sortModesHelper.setSortMode(trackTab.getId(), trackTab.getSortMode()); } - settings.saveTabsSortModes(tabsSortModes); + sortModesHelper.syncSettings(); + } + + @NonNull + private TracksSortMode getRootSortMode() { + return app.getTrackSortModesHelper().getRootFolderSortMode(); + } + + @NonNull + private LatLon getDefaultLocation() { + return app.getMapViewTrackingUtilities().getDefaultLocation(); } } diff --git a/OsmAnd/src/net/osmand/plus/configmap/tracks/TracksComparator.java b/OsmAnd/src/net/osmand/plus/configmap/tracks/TracksComparator.java index 2121fa93041..6907a10fd6e 100644 --- a/OsmAnd/src/net/osmand/plus/configmap/tracks/TracksComparator.java +++ b/OsmAnd/src/net/osmand/plus/configmap/tracks/TracksComparator.java @@ -1,6 +1,9 @@ package net.osmand.plus.configmap.tracks; import static com.jwetherell.openmap.common.LatLonPoint.EQUIVALENT_TOLERANCE; +import static net.osmand.plus.settings.enums.TracksSortMode.DATE_DESCENDING; +import static net.osmand.plus.settings.enums.TracksSortMode.DISTANCE_ASCENDING; +import static net.osmand.plus.settings.enums.TracksSortMode.DURATION_ASCENDING; import static net.osmand.plus.settings.enums.TracksSortMode.LAST_MODIFIED; import static net.osmand.plus.settings.enums.TracksSortMode.NAME_ASCENDING; import static net.osmand.plus.settings.enums.TracksSortMode.NAME_DESCENDING; @@ -16,7 +19,6 @@ import net.osmand.plus.myplaces.tracks.VisibleTracksGroup; import net.osmand.plus.settings.enums.TracksSortMode; import net.osmand.shared.gpx.data.ComparableTracksGroup; -import net.osmand.shared.gpx.filters.TrackFolderAnalysis; import net.osmand.shared.data.KLatLon; import net.osmand.shared.gpx.GpxDataItem; import net.osmand.shared.gpx.GpxTrackAnalysis; @@ -33,6 +35,7 @@ public class TracksComparator implements Comparator { public final TrackTab trackTab; public final TracksSortMode sortMode; public final Collator collator = OsmAndCollator.primaryCollator(); + private boolean useSubdirs = false; public TracksComparator(@NonNull TrackTab trackTab, @NonNull LatLon latLon) { this.trackTab = trackTab; @@ -40,8 +43,14 @@ public TracksComparator(@NonNull TrackTab trackTab, @NonNull LatLon latLon) { this.latLon = SharedUtil.kLatLon(latLon); } + public TracksComparator(@NonNull TracksSortMode sortMode, + @NonNull LatLon latLon, boolean useSubdirs) { + this(sortMode, latLon); + this.useSubdirs = useSubdirs; + } + public TracksComparator(@NonNull TracksSortMode sortMode, @NonNull LatLon latLon) { - trackTab = null; + this.trackTab = null; this.sortMode = sortMode; this.latLon = SharedUtil.kLatLon(latLon); } @@ -66,8 +75,16 @@ public int compare(Object o1, Object o2) { if (o2 instanceof VisibleTracksGroup) { return 1; } - if (o1 instanceof ComparableTracksGroup) { - return o2 instanceof ComparableTracksGroup ? compareTrackFolders((ComparableTracksGroup) o1, (ComparableTracksGroup) o2) : -1; + if (o1 instanceof ComparableTracksGroup folder1) { + if (o2 instanceof ComparableTracksGroup folder2) { + int predefinedOrder1 = folder1.getDefaultOrder(); + int predefinedOrder2 = folder2.getDefaultOrder(); + if (predefinedOrder1 != predefinedOrder2) { + return Integer.compare(predefinedOrder1, predefinedOrder2); + } + return compareTrackFolders(folder1, folder2); + } + return -1; } if (o2 instanceof ComparableTracksGroup) { return 1; @@ -79,43 +96,35 @@ public int compare(Object o1, Object o2) { } private int compareTrackFolders(@NonNull ComparableTracksGroup folder1, @NonNull ComparableTracksGroup folder2) { - TrackFolderAnalysis folderAnalysis1; - TrackFolderAnalysis folderAnalysis2; + int multiplier; switch (sortMode) { - case NAME_ASCENDING: - return compareTrackFolderNames(folder1, folder2); - case NAME_DESCENDING: - return -compareTrackFolderNames(folder1, folder2); - case DATE_ASCENDING: - return compareFolderFilesByLastModified(folder1, folder2); - case DATE_DESCENDING: - return -compareFolderFilesByLastModified(folder1, folder2); - case LAST_MODIFIED: - return compareFolderFilesByLastModified(folder1, folder2); - case DISTANCE_DESCENDING: - folderAnalysis1 = folder1.getFolderAnalysis(); - folderAnalysis2 = folder2.getFolderAnalysis(); - if (Math.abs(folderAnalysis1.getTotalDistance() - folderAnalysis2.getTotalDistance()) >= EQUIVALENT_TOLERANCE) { - return -Float.compare(folderAnalysis1.getTotalDistance(), folderAnalysis2.getTotalDistance()); - } - case DISTANCE_ASCENDING: - folderAnalysis1 = folder1.getFolderAnalysis(); - folderAnalysis2 = folder2.getFolderAnalysis(); - if (Math.abs(folderAnalysis1.getTotalDistance() - folderAnalysis2.getTotalDistance()) >= EQUIVALENT_TOLERANCE) { - return Float.compare(folderAnalysis1.getTotalDistance(), folderAnalysis2.getTotalDistance()); - } - case DURATION_DESCENDING: - folderAnalysis1 = folder1.getFolderAnalysis(); - folderAnalysis2 = folder2.getFolderAnalysis(); - if (folderAnalysis1.getTimeSpan() != folderAnalysis2.getTimeSpan()) { - return -Long.compare(folderAnalysis1.getTimeSpan(), folderAnalysis2.getTimeSpan()); + case NAME_ASCENDING, NAME_DESCENDING: { + multiplier = sortMode == NAME_ASCENDING ? 1 : -1; + return multiplier * compareTrackFolderNames(folder1, folder2); + } + + case LAST_MODIFIED, DATE_ASCENDING, DATE_DESCENDING: { + multiplier = sortMode == DATE_DESCENDING ? -1 : 1; + return multiplier * compareFolderFilesByLastModified(folder1, folder2); + } + + case DISTANCE_ASCENDING, DISTANCE_DESCENDING: { + float dist1 = folder1.getFolderAnalysis().getTotalDistance(); + float dist2 = folder2.getFolderAnalysis().getTotalDistance(); + if (Math.abs(dist1 - dist2) >= EQUIVALENT_TOLERANCE) { + multiplier = sortMode == DISTANCE_ASCENDING ? 1 : -1; + return multiplier * Float.compare(dist1, dist2); } - case DURATION_ASCENDING: - folderAnalysis1 = folder1.getFolderAnalysis(); - folderAnalysis2 = folder2.getFolderAnalysis(); - if (folderAnalysis1.getTimeSpan() != folderAnalysis2.getTimeSpan()) { - return Long.compare(folderAnalysis1.getTimeSpan(), folderAnalysis2.getTimeSpan()); + } + + case DURATION_ASCENDING, DURATION_DESCENDING: { + int timeSpan1 = folder1.getFolderAnalysis().getTimeSpan(); + int timeSpan2 = folder2.getFolderAnalysis().getTimeSpan(); + if (timeSpan1 != timeSpan2) { + multiplier = sortMode == DURATION_ASCENDING ? 1 : -1; + return multiplier * Long.compare(timeSpan1, timeSpan2); } + } } return compareTrackFolderNames(folder1, folder2); } @@ -292,8 +301,9 @@ private int compareTrackItemNames(@NonNull TrackItem item1, @NonNull TrackItem i return compareNames(item1.getName(), item2.getName()); } - private int compareTrackFolderNames(@NonNull ComparableTracksGroup folder1, @NonNull ComparableTracksGroup folder2) { - return compareNames(folder1.getDirName(), folder2.getDirName()); + private int compareTrackFolderNames(@NonNull ComparableTracksGroup folder1, + @NonNull ComparableTracksGroup folder2) { + return compareNames(folder1.getDirName(useSubdirs), folder2.getDirName(useSubdirs)); } private int compareNames(@NonNull String item1, @NonNull String item2) { diff --git a/OsmAnd/src/net/osmand/plus/configmap/tracks/TracksTabAdapter.java b/OsmAnd/src/net/osmand/plus/configmap/tracks/TracksTabAdapter.java index 63a83a0fcc9..8ac7fd76113 100644 --- a/OsmAnd/src/net/osmand/plus/configmap/tracks/TracksTabAdapter.java +++ b/OsmAnd/src/net/osmand/plus/configmap/tracks/TracksTabAdapter.java @@ -15,25 +15,22 @@ public class TracksTabAdapter extends FragmentStatePagerAdapter { - private final OsmandApplication app; private final List trackTabs = new ArrayList<>(); - public TracksTabAdapter(@NonNull OsmandApplication app, @NonNull FragmentManager manager, @NonNull List tabs) { + public TracksTabAdapter(@NonNull FragmentManager manager, @NonNull List tabs) { super(manager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT); - this.app = app; trackTabs.addAll(tabs); } - public void setTrackTabs(@NonNull Map tabs) { + public void setTrackTabs(@NonNull List tabs) { trackTabs.clear(); - trackTabs.addAll(tabs.values()); + trackTabs.addAll(tabs); notifyDataSetChanged(); } @Override public int getItemPosition(@NonNull Object object) { - if (object instanceof TrackItemsFragment) { - TrackItemsFragment fragment = (TrackItemsFragment) object; + if (object instanceof TrackItemsFragment fragment) { int index = trackTabs.indexOf(fragment.getTrackTab()); return index >= 0 ? index : POSITION_NONE; } @@ -56,7 +53,7 @@ public Fragment getItem(int position) { @Override public CharSequence getPageTitle(int position) { - return trackTabs.get(position).getName(app); + return trackTabs.get(position).getName(); } @Override diff --git a/OsmAnd/src/net/osmand/plus/configmap/tracks/TracksTabsFragment.java b/OsmAnd/src/net/osmand/plus/configmap/tracks/TracksTabsFragment.java index 12174dc0de6..98fcf8d0d6c 100644 --- a/OsmAnd/src/net/osmand/plus/configmap/tracks/TracksTabsFragment.java +++ b/OsmAnd/src/net/osmand/plus/configmap/tracks/TracksTabsFragment.java @@ -25,6 +25,7 @@ import androidx.fragment.app.FragmentManager; import androidx.viewpager.widget.ViewPager.SimpleOnPageChangeListener; +import net.osmand.IndexConstants; import net.osmand.plus.shared.SharedUtil; import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; @@ -228,7 +229,7 @@ private void updateButtonsState() { selectionButton.setEnabled(!Algorithms.isEmpty(itemsSelectionHelper.getSelectedItems()) || notAllSelected); } applyButton.setEnabled(itemsSelectionHelper.hasItemsToApply()); - TrackTab allTracksTab = trackTabsHelper.getTrackTabs().get(TrackTabType.ALL.name()); + TrackTab allTracksTab = trackTabsHelper.getTrackTab(TrackTabType.ALL.name()); searchButton.setVisibility(allTracksTab == null ? View.GONE : View.VISIBLE); } } @@ -262,7 +263,7 @@ public void tracksLoaded(@NonNull TrackFolder folder) { @Override public void loadTracksFinished(@NonNull TrackFolder folder) { - trackTabsHelper.updateTrackItems(folder.getFlattenedTrackItems()); + trackTabsHelper.updateTrackItems(folder); AndroidUiHelper.updateVisibility(progressBar, false); updateTrackTabs(); applyPreselectedParams(); @@ -277,10 +278,10 @@ public void deferredLoadTracksFinished(@NonNull TrackFolder folder) { private void applyPreselectedParams() { if (preselectedTabParams != null) { - String tabName = preselectedTabParams.getPreselectedTabName(app, getTrackTabs()); - TrackTab trackTab = getTab(tabName); + String tabId = preselectedTabParams.getPreselectedTabId(); + TrackTab trackTab = getTab(tabId); if (trackTab != null) { - setSelectedTab(tabName); + setSelectedTab(tabId); if (preselectedTabParams.shouldSelectAll()) { itemsSelectionHelper.onItemsSelected(trackTab.getTrackItems(), true); diff --git a/OsmAnd/src/net/osmand/plus/configmap/tracks/UpgradeTrackSortModeKeysAlgorithm.java b/OsmAnd/src/net/osmand/plus/configmap/tracks/UpgradeTrackSortModeKeysAlgorithm.java new file mode 100644 index 00000000000..c12527091fa --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/configmap/tracks/UpgradeTrackSortModeKeysAlgorithm.java @@ -0,0 +1,116 @@ +package net.osmand.plus.configmap.tracks; + +import static net.osmand.IndexConstants.GPX_INDEX_DIR; +import static net.osmand.plus.AppInitEvents.GPX_DB_INITIALIZED; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.settings.enums.TracksSortMode; +import net.osmand.shared.gpx.GpxDataItem; +import net.osmand.shared.gpx.GpxDbHelper; +import net.osmand.shared.gpx.SmartFolderHelper; +import net.osmand.shared.gpx.data.SmartFolder; +import net.osmand.shared.io.KFile; + +import java.io.File; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +/** + * Removes surplus keys and upgrades outdated ones. + * Upgraded keys will use folder relative path as a key (V2) instead of folder name (V1). + */ +public class UpgradeTrackSortModeKeysAlgorithm { + + private final OsmandApplication app; + private final GpxDbHelper gpxDbHelper; + private final SmartFolderHelper smartFolderHelper; + private final TrackSortModesHelper sortModesHelper; + + private UpgradeTrackSortModeKeysAlgorithm(@NonNull OsmandApplication app, + @NonNull TrackSortModesHelper sortModesHelper) { + this.app = app; + this.sortModesHelper = sortModesHelper; + this.gpxDbHelper = app.getGpxDbHelper(); + this.smartFolderHelper = app.getSmartFolderHelper(); + } + + public static void execute(@NonNull OsmandApplication app, + @NonNull TrackSortModesHelper sortModesHelper) { + new UpgradeTrackSortModeKeysAlgorithm(app, sortModesHelper).execute(); + } + + private void execute() { + if (gpxDbHelper.isInitialized()) { + executeImpl(); + } else { + app.getAppInitializer().addOnProgressListener(GPX_DB_INITIALIZED, init -> executeImpl()); + } + } + + private void executeImpl() { + Map upgradedCache = new HashMap<>(); + putUpgradedKey(upgradedCache, TrackTabType.ON_MAP.name()); + putUpgradedKey(upgradedCache, TrackTabType.ALL.name()); + putUpgradedKey(upgradedCache, TrackTabType.FOLDERS.name()); + for (String id : getDirIds()) { + putUpgradedKey(upgradedCache, id); + } + for (SmartFolder folder : smartFolderHelper.getSmartFolders()) { + putUpgradedKey(upgradedCache, folder.getId()); + } + sortModesHelper.setSortModes(upgradedCache); + sortModesHelper.syncSettings(); + } + + @NonNull + private Set getDirIds() { + Set ids = new HashSet<>(); + for (GpxDataItem item : gpxDbHelper.getItems()) { + KFile file = item.getFile(); + KFile dir = file.getParentFile(); + if (dir != null) { + String path = dir.absolutePath(); + if (!path.endsWith(File.separator)) { + path += File.separator; + } + ids.add(getFolderIdV2(path)); + } + } + return ids; + } + + private void putUpgradedKey(@NonNull Map map, @NonNull String id) { + TracksSortMode sortMode = getSortMode(id); + if (sortMode != null) { + map.put(id, sortMode); + } + } + + private TracksSortMode getSortMode(@NonNull String id) { + TracksSortMode sortMode = sortModesHelper.getSortMode(id); + if (sortMode == null) { + String idV1 = getFolderIdV1(id); + return idV1 != null ? sortModesHelper.getSortMode(idV1) : null; + } + return sortMode; + } + + @NonNull + private static String getFolderIdV2(@NonNull String absolutePath) { + return TrackSortModesHelper.getFolderId(absolutePath); + } + + @Nullable + private static String getFolderIdV1(@Nullable String id) { + if (id != null && id.isEmpty()) { + return GPX_INDEX_DIR; + } + int index = id != null ? id.lastIndexOf(File.separator) : -1; + return index > 0 ? id.substring(index + 1) : null; + } +} diff --git a/OsmAnd/src/net/osmand/plus/helpers/IntentHelper.java b/OsmAnd/src/net/osmand/plus/helpers/IntentHelper.java index 25b8e943bfe..b7c97af043d 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/IntentHelper.java +++ b/OsmAnd/src/net/osmand/plus/helpers/IntentHelper.java @@ -2,8 +2,7 @@ import static net.osmand.plus.backup.BackupListeners.OnRegisterDeviceListener; import static net.osmand.plus.configmap.tracks.PreselectedTabParams.CALLING_FRAGMENT_TAG; -import static net.osmand.plus.configmap.tracks.PreselectedTabParams.PRESELECTED_TRACKS_TAB_NAME; -import static net.osmand.plus.configmap.tracks.PreselectedTabParams.PRESELECTED_TRACKS_TAB_TYPE; +import static net.osmand.plus.configmap.tracks.PreselectedTabParams.PRESELECTED_TRACKS_TAB_ID; import static net.osmand.plus.configmap.tracks.PreselectedTabParams.SELECT_ALL_ITEMS_ON_TAB; import static net.osmand.plus.helpers.MapFragmentsHelper.CLOSE_ALL_FRAGMENTS; import static net.osmand.plus.settings.fragments.ExportSettingsFragment.SELECTED_TYPES; @@ -560,13 +559,12 @@ public void parseContentIntent() { clearIntent(intent); } Bundle extras = intent.getExtras(); - if (extras != null && intent.hasExtra(PRESELECTED_TRACKS_TAB_NAME) && intent.hasExtra(PRESELECTED_TRACKS_TAB_TYPE)) { - String name = extras.getString(PRESELECTED_TRACKS_TAB_NAME, TrackTabType.ALL.name()); + if (extras != null && intent.hasExtra(PRESELECTED_TRACKS_TAB_ID)) { + String id = extras.getString(PRESELECTED_TRACKS_TAB_ID, TrackTabType.ALL.name()); String callingFragmentTag = extras.getString(CALLING_FRAGMENT_TAG, null); - TrackTabType type = AndroidUtils.getSerializable(extras, PRESELECTED_TRACKS_TAB_TYPE, TrackTabType.class); boolean selectAllItems = intent.getBooleanExtra(SELECT_ALL_ITEMS_ON_TAB, false); - PreselectedTabParams params = new PreselectedTabParams(name, type != null ? type : TrackTabType.ALL, selectAllItems); + PreselectedTabParams params = new PreselectedTabParams(id, selectAllItems); TracksTabsFragment.showInstance(mapActivity.getSupportFragmentManager(), params, callingFragmentTag); clearIntent(intent); } diff --git a/OsmAnd/src/net/osmand/plus/myplaces/tracks/VisibleTracksGroup.java b/OsmAnd/src/net/osmand/plus/myplaces/tracks/VisibleTracksGroup.java index 004350c6c8f..8e555593a17 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/tracks/VisibleTracksGroup.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/tracks/VisibleTracksGroup.java @@ -4,6 +4,7 @@ import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; +import net.osmand.plus.configmap.tracks.TrackTabType; import net.osmand.shared.gpx.TrackItem; import net.osmand.shared.gpx.data.TracksGroup; import net.osmand.plus.track.helpers.GpxSelectionHelper; @@ -22,6 +23,12 @@ public VisibleTracksGroup(@NonNull OsmandApplication app) { this.selectedGpxHelper = app.getSelectedGpxHelper(); } + @NonNull + @Override + public String getId() { + return TrackTabType.ON_MAP.name(); + } + @NonNull @Override public List getTrackItems() { diff --git a/OsmAnd/src/net/osmand/plus/myplaces/tracks/controller/TrackFolderOptionsController.java b/OsmAnd/src/net/osmand/plus/myplaces/tracks/controller/TrackFolderOptionsController.java index b9b1133a2ad..2cdb74686ab 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/tracks/controller/TrackFolderOptionsController.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/tracks/controller/TrackFolderOptionsController.java @@ -20,7 +20,6 @@ import net.osmand.plus.base.dialog.data.DisplayItem; import net.osmand.plus.base.dialog.interfaces.controller.IDialogItemClicked; import net.osmand.plus.base.dialog.interfaces.controller.IDisplayDataProvider; -import net.osmand.shared.gpx.TrackItem; import net.osmand.plus.myplaces.tracks.TrackFoldersHelper; import net.osmand.plus.settings.bottomsheets.CustomizableOptionsBottomSheet; import net.osmand.shared.gpx.data.TrackFolder; @@ -37,11 +36,9 @@ import org.apache.commons.logging.Log; import java.io.File; -import java.util.ArrayList; -import java.util.List; -public class TrackFolderOptionsController extends BaseDialogController implements IDisplayDataProvider, - IDialogItemClicked, TrackFolderOptionsListener { +public class TrackFolderOptionsController extends BaseDialogController + implements IDisplayDataProvider, IDialogItemClicked, TrackFolderOptionsListener { private final static Log LOG = PlatformUtil.getLog(TrackFolderOptionsController.class); @@ -165,7 +162,7 @@ private void showRenameDialog() { } }); String caption = activity.getString(R.string.enter_new_name); - CustomAlert.showInput(dialogData, activity, trackFolder.getDirName(), caption); + CustomAlert.showInput(dialogData, activity, trackFolder.getDirName(false), caption); } } @@ -175,15 +172,7 @@ private void renameFolder(@NonNull String newName) { if (oldDir.renameTo(newDir)) { trackFolder.setDirFile(SharedUtil.kFile(newDir)); trackFolder.resetCachedData(); - - List files = new ArrayList<>(); - for (TrackItem trackItem : trackFolder.getFlattenedTrackItems()) { - KFile file = trackItem.getFile(); - if (file != null) { - files.add(SharedUtil.jFile(file)); - } - } - FileUtils.updateMovedGpxFiles(app, files, oldDir, newDir); + FileUtils.updateMovedTrackFolder(app, trackFolder, oldDir, newDir); dialogManager.askRefreshDialogCompletely(PROCESS_ID); @@ -234,6 +223,8 @@ private void showDeleteDialog() { @Override public void onFolderDeleted() { + FileUtils.updateAfterDeleteTrackFolder(app, trackFolder); + // Close options dialog after folder deleted dialogManager.askDismissDialog(PROCESS_ID); diff --git a/OsmAnd/src/net/osmand/plus/myplaces/tracks/dialogs/BaseTrackFolderFragment.java b/OsmAnd/src/net/osmand/plus/myplaces/tracks/dialogs/BaseTrackFolderFragment.java index 86ca7e61dfd..e13f10869c2 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/tracks/dialogs/BaseTrackFolderFragment.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/tracks/dialogs/BaseTrackFolderFragment.java @@ -1,10 +1,8 @@ package net.osmand.plus.myplaces.tracks.dialogs; import static net.osmand.plus.configmap.tracks.PreselectedTabParams.CALLING_FRAGMENT_TAG; -import static net.osmand.plus.configmap.tracks.PreselectedTabParams.PRESELECTED_TRACKS_TAB_NAME; -import static net.osmand.plus.configmap.tracks.PreselectedTabParams.PRESELECTED_TRACKS_TAB_TYPE; +import static net.osmand.plus.configmap.tracks.PreselectedTabParams.PRESELECTED_TRACKS_TAB_ID; import static net.osmand.plus.configmap.tracks.PreselectedTabParams.SELECT_ALL_ITEMS_ON_TAB; -import static net.osmand.plus.configmap.tracks.TrackTab.SMART_FOLDER_TAB_NAME_PREFIX; import static net.osmand.plus.configmap.tracks.TrackTabType.FOLDER; import static net.osmand.plus.configmap.tracks.TrackTabType.SMART_FOLDER; import static net.osmand.plus.importfiles.ImportHelper.IMPORT_FILE_REQUEST; @@ -33,7 +31,7 @@ import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView.ViewHolder; -import net.osmand.IndexConstants; +import net.osmand.plus.configmap.tracks.TrackSortModesHelper; import net.osmand.plus.myplaces.tracks.DialogClosedListener; import net.osmand.plus.shared.SharedUtil; import net.osmand.data.LatLon; @@ -63,7 +61,6 @@ import net.osmand.plus.myplaces.tracks.dialogs.MoveGpxFileBottomSheet.OnTrackFileMoveListener; import net.osmand.plus.myplaces.tracks.dialogs.viewholders.TracksGroupViewHolder.TrackGroupsListener; import net.osmand.plus.plugins.osmedit.oauth.OsmOAuthHelper.OsmAuthorizationListener; -import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.enums.TracksSortMode; import net.osmand.plus.track.fragments.TrackMenuFragment; import net.osmand.plus.track.helpers.GpxSelectionHelper; @@ -84,10 +81,7 @@ import java.io.File; import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; import java.util.List; -import java.util.Map; -import java.util.Map.Entry; import java.util.Set; public abstract class BaseTrackFolderFragment extends BaseOsmAndFragment implements FragmentStateHolder, @@ -333,23 +327,14 @@ public void showSortByDialog() { @NonNull @Override public TracksSortMode getTracksSortMode() { - Map tabsSortModes = settings.getTrackSortModes(); - for (Entry entry : tabsSortModes.entrySet()) { - if (KAlgorithms.INSTANCE.stringsEqual(entry.getKey(), getSortEntryName())) { - return TracksSortMode.getByValue(entry.getValue()); - } - } - return TracksSortMode.getDefaultSortMode(); + TrackSortModesHelper sortModesHelper = app.getTrackSortModesHelper(); + return sortModesHelper.requireSortMode(getSortEntryId()); } - protected String getSortEntryName() { - if (selectedFolder != null) { - return selectedFolder.getDirName(); - } - if (smartFolder != null) { - return SMART_FOLDER_TAB_NAME_PREFIX + smartFolder.getName(); - } - return null; + @Nullable + protected String getSortEntryId() { + TracksGroup folder = selectedFolder != null ? selectedFolder : smartFolder; + return folder != null ? folder.getId() : null; } @Override @@ -357,53 +342,28 @@ public void setTracksSortMode(@NonNull TracksSortMode sortMode, boolean sortSubF if (sortSubFolders) { sortSubFolder(sortMode); } else { - Map tabsSortModes = settings.getTrackSortModes(); - if (smartFolder != null) { - tabsSortModes.put(SMART_FOLDER_TAB_NAME_PREFIX + smartFolder.getFolderName(), sortMode.name()); - } else { - tabsSortModes.put(selectedFolder.getDirName(), sortMode.name()); - } - settings.saveTabsSortModes(tabsSortModes); - + TracksGroup folder = smartFolder != null ? smartFolder : selectedFolder; + TrackSortModesHelper sortModesHelper = app.getTrackSortModesHelper(); + sortModesHelper.setSortMode(folder.getId(), sortMode); + sortModesHelper.syncSettings(); updateContent(); } } - private void sortSubFolder(TracksSortMode sortMode) { - OsmandSettings settings = app.getSettings(); - Map tabsSortModes = settings.getTrackSortModes(); - sortFolders(selectedFolder, tabsSortModes, sortMode); - settings.saveTabsSortModes(tabsSortModes); + private void sortSubFolder(@NonNull TracksSortMode sortMode) { + TrackSortModesHelper sortModesHelper = app.getTrackSortModesHelper(); + sortFolders(selectedFolder, sortModesHelper, sortMode); + sortModesHelper.syncSettings(); app.showToastMessage(app.getString(R.string.sorted_sufolders_toast, selectedFolder.getName(), app.getString(sortMode.getNameId()))); } - private void sortFolders(TrackFolder trackFolder, Map tabsSortModes, TracksSortMode sortMode) { + private void sortFolders(@NonNull TrackFolder trackFolder, + @NonNull TrackSortModesHelper sortModesHelper, + @NonNull TracksSortMode sortMode) { for (TrackFolder folder : trackFolder.getFlattenedSubFolders()) { - tabsSortModes.put(folder.getDirName(), sortMode.name()); - } - } - - private void removeSurplusTabsSortModes() { - if (!rootFolder.getDirFile().equals(app.getAppPathKt(IndexConstants.GPX_INDEX_DIR))) { - // Execute only from tracks root folder to not lose valid entries - return; - } - OsmandSettings settings = app.getSettings(); - Map oldTabsSortModes = settings.getTrackSortModes(); - Map tabsSortModes = new HashMap<>(); - - tabsSortModes.put(TrackTabType.ON_MAP.name(), oldTabsSortModes.get(TrackTabType.ON_MAP.name())); - tabsSortModes.put(TrackTabType.ALL.name(), oldTabsSortModes.get(TrackTabType.ALL.name())); - tabsSortModes.put(rootFolder.getDirName(), oldTabsSortModes.get(rootFolder.getDirName())); - for (TrackFolder folder : rootFolder.getFlattenedSubFolders()) { - tabsSortModes.put(folder.getDirName(), oldTabsSortModes.get(folder.getDirName())); - } - for (SmartFolder folder : app.getSmartFolderHelper().getSmartFolders()) { - String key = SMART_FOLDER_TAB_NAME_PREFIX + folder.getFolderName(); - tabsSortModes.put(key, oldTabsSortModes.get(key)); + sortModesHelper.setSortMode(folder.getId(), sortMode); } - settings.saveTabsSortModes(tabsSortModes); } @Override @@ -517,31 +477,28 @@ public ScreenPositionData getFirstSuitableItemScreenPosition() { @Override public void onFolderRenamed(@NonNull File newDir) { updateContent(); - removeSurplusTabsSortModes(); } @Override public void onFolderDeleted() { reloadTracks(); - removeSurplusTabsSortModes(); } @Override public void showFolderTracksOnMap(@NonNull TrackFolder folder) { - showTracksVisibilityDialog(folder.getDirName(), FOLDER, true); + showTracksVisibilityDialog(folder.getId(), FOLDER, true); } @Override public void showSmartFolderTracksOnMap(@NonNull SmartFolder smartFolder) { - showTracksVisibilityDialog(smartFolder.getFolderName(), SMART_FOLDER, true); + showTracksVisibilityDialog(smartFolder.getId(), SMART_FOLDER, true); } - protected void showTracksVisibilityDialog(@NonNull String name, @NonNull TrackTabType type, boolean selectAll) { + protected void showTracksVisibilityDialog(@NonNull String id, @NonNull TrackTabType type, boolean selectAll) { FragmentActivity activity = getActivity(); if (activity != null) { Bundle bundle = new Bundle(); - bundle.putString(PRESELECTED_TRACKS_TAB_NAME, name); - bundle.putSerializable(PRESELECTED_TRACKS_TAB_TYPE, type); + bundle.putString(PRESELECTED_TRACKS_TAB_ID, id); bundle.putBoolean(SELECT_ALL_ITEMS_ON_TAB, selectAll); bundle.putString(CALLING_FRAGMENT_TAG, TAG); MapActivity.launchMapActivityMoveToTop(activity, storeState(), null, bundle); diff --git a/OsmAnd/src/net/osmand/plus/myplaces/tracks/tasks/MoveTrackFoldersTask.java b/OsmAnd/src/net/osmand/plus/myplaces/tracks/tasks/MoveTrackFoldersTask.java index 10ee98784a0..52626052551 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/tracks/tasks/MoveTrackFoldersTask.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/tracks/tasks/MoveTrackFoldersTask.java @@ -15,10 +15,8 @@ import net.osmand.util.Algorithms; import java.io.File; -import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; -import java.util.List; import java.util.Set; public class MoveTrackFoldersTask extends BaseLoadAsyncTask { @@ -68,15 +66,7 @@ private void moveTrackFolder(@NonNull TrackFolder trackFolder) { File dest = new File(destinationFolder, src.name()); if (src.renameTo(dest.getAbsolutePath())) { dest.setLastModified(System.currentTimeMillis()); - - List files = new ArrayList<>(); - for (TrackItem trackItem : trackFolder.getFlattenedTrackItems()) { - KFile file = trackItem.getFile(); - if (file != null) { - files.add(SharedUtil.jFile(file)); - } - } - FileUtils.updateMovedGpxFiles(app, files, SharedUtil.jFile(src), dest); + FileUtils.updateMovedTrackFolder(app, trackFolder, SharedUtil.jFile(src), dest); } } } diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java index f5250d95e4b..a4b8c7cf3ef 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java @@ -109,7 +109,6 @@ import java.io.File; import java.io.IOException; import java.util.*; -import java.util.Map.Entry; public class OsmandSettings { @@ -2054,39 +2053,6 @@ private String getPagedWidgetIds(@NonNull List pages) { public final CommonPreference SEARCH_TRACKS_SORT_MODE = new EnumStringPreference<>(this, "search_tracks_sort_mode", TracksSortMode.getDefaultSortMode(), TracksSortMode.values()); public final ListStringPreference TRACKS_TABS_SORT_MODES = (ListStringPreference) new ListStringPreference(this, "tracks_tabs_sort_modes", null, ";;").makeGlobal().makeShared().cache(); - @NonNull - public Map getTrackSortModes() { - return getTrackSortModes(TRACKS_TABS_SORT_MODES.getStringsList()); - } - - public void saveTabsSortModes(@NonNull Map tabsSortModes) { - List sortModes = getPlainSortModes(tabsSortModes); - TRACKS_TABS_SORT_MODES.setStringsList(sortModes); - } - - @NonNull - private Map getTrackSortModes(@Nullable List modes) { - Map sortModes = new HashMap<>(); - if (!Algorithms.isEmpty(modes)) { - for (String sortMode : modes) { - String[] tabSortMode = sortMode.split(",,"); - if (tabSortMode.length == 2) { - sortModes.put(tabSortMode[0], tabSortMode[1]); - } - } - } - return sortModes; - } - - @NonNull - private List getPlainSortModes(@NonNull Map tabsSortModes) { - List sortTypes = new ArrayList<>(); - for (Entry entry : tabsSortModes.entrySet()) { - sortTypes.add(entry.getKey() + ",," + entry.getValue()); - } - return sortTypes; - } - public final OsmandPreference ANIMATE_MY_LOCATION = new BooleanPreference(this, "animate_my_location", true).makeProfile().cache(); public final OsmandPreference EXTERNAL_INPUT_DEVICE = new StringPreference(this, "selected_external_input_device", KeyboardDeviceProfile.ID).makeProfile(); diff --git a/OsmAnd/src/net/osmand/plus/track/BaseTracksTabsFragment.java b/OsmAnd/src/net/osmand/plus/track/BaseTracksTabsFragment.java index fa30aa525e9..572aeed17f9 100644 --- a/OsmAnd/src/net/osmand/plus/track/BaseTracksTabsFragment.java +++ b/OsmAnd/src/net/osmand/plus/track/BaseTracksTabsFragment.java @@ -22,6 +22,7 @@ import androidx.fragment.app.FragmentManager; import androidx.viewpager.widget.ViewPager; +import net.osmand.plus.OsmandApplication; import net.osmand.plus.shared.SharedUtil; import net.osmand.plus.R; import net.osmand.plus.base.BaseOsmAndDialogFragment; @@ -61,7 +62,6 @@ import net.osmand.util.Algorithms; import java.io.File; -import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Set; @@ -108,20 +108,20 @@ public ItemsSelectionHelper getSelectionHelper() { public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); importHelper = app.getImportHelper(); - trackTabsHelper = new TrackTabsHelper(app); + trackTabsHelper = createTrackTabsHelper(app); gpxSelectionHelper = app.getSelectedGpxHelper(); itemsSelectionHelper = trackTabsHelper.getItemsSelectionHelper(); } protected void setupTabLayout(@NonNull View view) { viewPager = view.findViewById(R.id.view_pager); - List tabs = getTrackTabs(); + List tabs = getSortedTrackTabs(); tabLayout = view.findViewById(R.id.sliding_tabs); tabLayout.setTabBackground(nightMode ? R.color.app_bar_main_dark : R.color.card_and_list_background_light); tabLayout.setCustomTabProvider(new PagerSlidingTabStrip.CustomTabProvider() { @Override public View getCustomTabView(@NonNull ViewGroup parent, int position) { - TrackTab trackTab = getTrackTabs().get(position); + TrackTab trackTab = getSortedTrackTabs().get(position); int activeColor = ColorUtilities.getActiveColor(app, nightMode); int textColor = ColorUtilities.getPrimaryTextColor(app, nightMode); @@ -132,7 +132,7 @@ public View getCustomTabView(@NonNull ViewGroup parent, int position) { TextView textView = customView.findViewById(android.R.id.text1); textView.setPadding(sidePadding, textView.getPaddingTop(), sidePadding, textView.getPaddingBottom()); textView.setTextColor(AndroidUtils.createColorStateList(android.R.attr.state_selected, activeColor, textColor)); - textView.setText(trackTab.getName(app)); + textView.setText(trackTab.getName()); return customView; } @@ -154,27 +154,42 @@ public void tabStylesUpdated(View tabsContainer, int currentPosition) { setTabs(tabs); } + @NonNull + protected TrackTabsHelper createTrackTabsHelper(@NonNull OsmandApplication app) { + return new TrackTabsHelper(app); + } + @NonNull public List getTrackTabs() { - return new ArrayList<>(trackTabsHelper.getTrackTabs().values()); + return trackTabsHelper.getTrackTabs(); + } + + @NonNull + public List getSortedTrackTabs() { + return getSortedTrackTabs(false); + } + + @NonNull + public List getSortedTrackTabs(boolean useSubdirs) { + return trackTabsHelper.getSortedTrackTabs(useSubdirs); } protected void setViewPagerAdapter(@NonNull ViewPager pager, List items) { - adapter = new TracksTabAdapter(app, getChildFragmentManager(), items); + adapter = new TracksTabAdapter(getChildFragmentManager(), items); pager.setAdapter(adapter); } @Nullable public TrackTab getSelectedTab() { - List trackTabs = getTrackTabs(); + List trackTabs = getSortedTrackTabs(); return trackTabs.isEmpty() ? null : trackTabs.get(viewPager.getCurrentItem()); } - public void setSelectedTab(@NonNull String name) { - List trackTabs = getTrackTabs(); + public void setSelectedTab(@NonNull String id) { + List trackTabs = getSortedTrackTabs(); for (int i = 0; i < trackTabs.size(); i++) { TrackTab tab = trackTabs.get(i); - if (Algorithms.stringsEqual(tab.getTypeName(), name)) { + if (Algorithms.stringsEqual(tab.getId(), id)) { viewPager.setCurrentItem(i); break; } @@ -182,9 +197,9 @@ public void setSelectedTab(@NonNull String name) { } @Nullable - public TrackTab getTab(@NonNull String name) { + public TrackTab getTab(@NonNull String id) { for (TrackTab trackTab : getTrackTabs()) { - if (Algorithms.stringsEqual(name, trackTab.getTypeName())) { + if (Algorithms.stringsEqual(id, trackTab.getId())) { return trackTab; } } @@ -209,7 +224,7 @@ public TracksSortMode getTracksSortMode() { @Override public void onResume() { super.onResume(); - List tabs = getTrackTabs(); + List tabs = getSortedTrackTabs(); if (tabs.size() != tabSize) { setTabs(tabs); } @@ -238,7 +253,7 @@ public void loadTracksStarted() { } protected void updateTrackTabs() { - adapter.setTrackTabs(trackTabsHelper.getTrackTabs()); + adapter.setTrackTabs(trackTabsHelper.getSortedTrackTabs(false)); } @Override diff --git a/OsmAnd/src/net/osmand/plus/track/SelectTrackFolderFragment.java b/OsmAnd/src/net/osmand/plus/track/SelectTrackFolderFragment.java index 3d562f2dc9e..52e6b57cd47 100644 --- a/OsmAnd/src/net/osmand/plus/track/SelectTrackFolderFragment.java +++ b/OsmAnd/src/net/osmand/plus/track/SelectTrackFolderFragment.java @@ -181,7 +181,7 @@ private void updateAdapter() { } private TrackTab getUpdatedTrackTab() { - TrackTab trackTab = new TrackTab(TrackTabType.FOLDERS); + TrackTab trackTab = new TrackTab(app, TrackTabType.FOLDERS); List subFolders = currentTrackFolder.getSubFolders(); List trackItems = currentTrackFolder.getTrackItems(); if (Algorithms.isEmpty(subFolders) && Algorithms.isEmpty(trackItems)) { diff --git a/OsmAnd/src/net/osmand/plus/track/SelectTrackTabsFragment.java b/OsmAnd/src/net/osmand/plus/track/SelectTrackTabsFragment.java index 1108cacaee3..c956cac4345 100644 --- a/OsmAnd/src/net/osmand/plus/track/SelectTrackTabsFragment.java +++ b/OsmAnd/src/net/osmand/plus/track/SelectTrackTabsFragment.java @@ -19,6 +19,10 @@ import androidx.fragment.app.FragmentManager; import net.osmand.CallbackWithObject; +import net.osmand.IndexConstants; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.configmap.tracks.SelectTrackTabsHelper; +import net.osmand.plus.configmap.tracks.TrackTabsHelper; import net.osmand.plus.shared.SharedUtil; import net.osmand.shared.gpx.GpxFile; import net.osmand.plus.R; @@ -94,6 +98,12 @@ protected void setTabs(@NonNull List tabs) { viewPager.setCurrentItem(0); } + @NonNull + @Override + protected TrackTabsHelper createTrackTabsHelper(@NonNull OsmandApplication app) { + return new SelectTrackTabsHelper(app); + } + @Override public void loadTracksProgress(@NonNull TrackItem... items) { } @@ -104,7 +114,7 @@ public void tracksLoaded(@NonNull TrackFolder folder) { @Override public void loadTracksFinished(@NonNull TrackFolder folder) { - trackTabsHelper.updateItems(folder); + trackTabsHelper.updateTrackItems(folder); AndroidUiHelper.updateVisibility(progressBar, false); updateTrackTabs(); updateTabsContent(); @@ -158,9 +168,10 @@ public void onTrackItemsSelected(@NonNull Set trackItems, boolean sel } @Nullable - public TrackTab getTab(@NonNull String name) { + @Override + public TrackTab getTab(@NonNull String id) { for (TrackTab trackTab : getTrackTabs()) { - if (Algorithms.stringsEqual(name, trackTab.getTypeName())) { + if (Algorithms.stringsEqual(id, trackTab.getId())) { updateTrackItemsVisibility(trackTab); return trackTab; } diff --git a/OsmAnd/src/net/osmand/plus/track/fragments/TrackMenuFragment.java b/OsmAnd/src/net/osmand/plus/track/fragments/TrackMenuFragment.java index 2e189503af0..4bbaee2b5fd 100644 --- a/OsmAnd/src/net/osmand/plus/track/fragments/TrackMenuFragment.java +++ b/OsmAnd/src/net/osmand/plus/track/fragments/TrackMenuFragment.java @@ -883,6 +883,9 @@ private void onRouteActivitySelected(@Nullable RouteActivity activity) { if (infoCard != null) { infoCard.updateContent(); } + if (metadataExtensionsCard != null) { + metadataExtensionsCard.updateContent(); + } } private void updateCardsLayout() { diff --git a/OsmAnd/src/net/osmand/plus/track/helpers/GpxUiHelper.java b/OsmAnd/src/net/osmand/plus/track/helpers/GpxUiHelper.java index 4cacb0fc1a2..12877fab62b 100644 --- a/OsmAnd/src/net/osmand/plus/track/helpers/GpxUiHelper.java +++ b/OsmAnd/src/net/osmand/plus/track/helpers/GpxUiHelper.java @@ -67,6 +67,7 @@ import net.osmand.shared.gpx.primitives.WptPt; import net.osmand.shared.io.KFile; import net.osmand.util.Algorithms; +import net.osmand.util.CollectionUtils; import net.osmand.util.MapUtils; import org.apache.commons.logging.Log; @@ -189,26 +190,29 @@ public static void selectSingleGPXFile(FragmentActivity activity, boolean showCu } @NonNull - public static String getFolderName(@NonNull Context context, @NonNull File dir, boolean includeParentDir) { - String name = dir.getName(); + public static String getFolderName(@NonNull Context context, @NonNull File directory) { + String name = directory.getName(); if (GPX_INDEX_DIR.equals(name + File.separator)) { return context.getString(R.string.shared_string_tracks); } - String dirPath = dir.getPath() + File.separator; + String dirPath = directory.getPath() + File.separator; if (dirPath.endsWith(GPX_IMPORT_DIR) || dirPath.endsWith(GPX_RECORDED_INDEX_DIR)) { return Algorithms.capitalizeFirstLetter(name); } - if (includeParentDir) { - File parent = dir.getParentFile(); - String parentName = parent != null ? parent.getName() : ""; - if (!Algorithms.isEmpty(parentName) && !GPX_INDEX_DIR.equals(parentName + File.separator)) { - name = parentName + File.separator + name; - } - return name; - } return name; } + @NonNull + public static String getFolderPath(@NonNull File directory, @NonNull String initialName) { + String name = directory.getName() + File.separator; + File parent = directory.getParentFile(); + String parentName = parent != null ? parent.getName() + File.separator : ""; + if (!CollectionUtils.equalsToAny(GPX_INDEX_DIR, name, parentName)) { + return parentName + initialName; + } + return initialName; + } + @NonNull public static String getFolderDescription(@NonNull OsmandApplication app, @NonNull TrackFolder folder) { long lastModified = folder.getLastModified(); diff --git a/OsmAnd/src/net/osmand/plus/utils/FileUtils.java b/OsmAnd/src/net/osmand/plus/utils/FileUtils.java index 12d5553aa48..50d59589bde 100644 --- a/OsmAnd/src/net/osmand/plus/utils/FileUtils.java +++ b/OsmAnd/src/net/osmand/plus/utils/FileUtils.java @@ -12,6 +12,7 @@ import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; +import net.osmand.plus.configmap.tracks.TrackSortModesHelper; import net.osmand.plus.shared.SharedUtil; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; @@ -24,7 +25,10 @@ import net.osmand.plus.track.helpers.SelectedGpxFile; import net.osmand.plus.track.helpers.save.SaveGpxHelper; import net.osmand.shared.gpx.GpxFile; +import net.osmand.shared.gpx.TrackItem; +import net.osmand.shared.gpx.data.TrackFolder; import net.osmand.shared.gpx.primitives.Metadata; +import net.osmand.shared.io.KFile; import net.osmand.util.Algorithms; import net.osmand.util.CollectionUtils; @@ -174,8 +178,28 @@ private static void updateGpxMetadata(@NonNull GpxFile gpxFile, @NonNull String } } - public static void updateMovedGpxFiles(@NonNull OsmandApplication app, @NonNull List files, - @NonNull File srcDir, @NonNull File destDir) { + public static void updateMovedTrackFolder(@NonNull OsmandApplication app, @NonNull TrackFolder trackFolder, + @NonNull File srcDir, @NonNull File destDir) { + List files = new ArrayList<>(); + for (TrackItem trackItem : trackFolder.getFlattenedTrackItems()) { + KFile file = trackItem.getFile(); + if (file != null) { + files.add(SharedUtil.jFile(file)); + } + } + updateMovedGpxFiles(app, files, srcDir, destDir); + + TrackSortModesHelper sortModesHelper = app.getTrackSortModesHelper(); + sortModesHelper.updateAfterMoveTrackFolder(trackFolder, srcDir); + } + + public static void updateAfterDeleteTrackFolder(@NonNull OsmandApplication app, @NonNull TrackFolder trackFolder) { + TrackSortModesHelper sortModesHelper = app.getTrackSortModesHelper(); + sortModesHelper.updateAfterDeleteTrackFolder(trackFolder); + } + + private static void updateMovedGpxFiles(@NonNull OsmandApplication app, @NonNull List files, + @NonNull File srcDir, @NonNull File destDir) { for (File srcFile : files) { String path = srcFile.getAbsolutePath(); String newPath = path.replace(srcDir.getAbsolutePath(), destDir.getAbsolutePath()); diff --git a/OsmAnd/src/net/osmand/plus/views/MapViewWithLayers.java b/OsmAnd/src/net/osmand/plus/views/MapViewWithLayers.java index ce467a7005b..b73ed23141a 100644 --- a/OsmAnd/src/net/osmand/plus/views/MapViewWithLayers.java +++ b/OsmAnd/src/net/osmand/plus/views/MapViewWithLayers.java @@ -30,7 +30,7 @@ public class MapViewWithLayers extends FrameLayout { - private static final int SYMBOLS_UPDATE_INTERVAL = 2000; + public static final int SYMBOLS_UPDATE_INTERVAL = 2000; private final OsmandApplication app; private final OsmandSettings settings; @@ -96,8 +96,8 @@ public void setupRenderingView() { private void resetMapRendererView() { MapRendererContext mapRendererContext = NativeCoreContext.getMapRendererContext(); - if (mapRendererContext != null && atlasMapRendererView != null && mapRendererContext.getMapRendererView() == atlasMapRendererView) - mapRendererContext.setMapRendererView(null); + if (mapRendererContext != null && atlasMapRendererView != null) + mapRendererContext.releaseMapRendererView(atlasMapRendererView); } private void setupAtlasMapRendererView() { @@ -124,12 +124,13 @@ private void setupAtlasMapRendererView() { } else { atlasMapRendererView.handleOnCreate(null); } - atlasMapRendererView.setMapRendererSetupOptionsConfigurator( - mapRendererSetupOptions -> mapRendererSetupOptions.setMaxNumberOfRasterMapLayersInBatch(1)); + mapRendererContext.presetMapRendererOptions(atlasMapRendererView); atlasMapRendererView.setupRenderer(getContext(), 0, 0, mapRendererView); atlasMapRendererView.setMinZoomLevel(ZoomLevel.swigToEnum(mapView.getMinZoom())); atlasMapRendererView.setMaxZoomLevel(ZoomLevel.swigToEnum(mapView.getMaxZoom())); atlasMapRendererView.setAzimuth(0); + atlasMapRendererView.removeAllSymbolsProviders(); + atlasMapRendererView.resumeSymbolsUpdate(); float elevationAngle = mapView.normalizeElevationAngle(settings.getLastKnownMapElevation()); atlasMapRendererView.setElevationAngle(elevationAngle); atlasMapRendererView.setSymbolsUpdateInterval(SYMBOLS_UPDATE_INTERVAL); diff --git a/OsmAnd/src/net/osmand/plus/views/OsmandMapTileView.java b/OsmAnd/src/net/osmand/plus/views/OsmandMapTileView.java index edf33c19f68..f1f681b6a39 100644 --- a/OsmAnd/src/net/osmand/plus/views/OsmandMapTileView.java +++ b/OsmAnd/src/net/osmand/plus/views/OsmandMapTileView.java @@ -1992,6 +1992,14 @@ public void setMapRenderer(@Nullable MapRendererView mapRenderer) { } } + public void detachMapRenderer() { + if (mapRenderer != null) { + mapRenderer.removeAllSymbolsProviders(); + mapRenderer.resetElevationDataProvider(); + mapRenderer = null; + } + } + @Nullable public MapRendererView getMapRenderer() { return mapRenderer; diff --git a/OsmAnd/src/net/osmand/plus/views/corenative/NativeCoreContext.java b/OsmAnd/src/net/osmand/plus/views/corenative/NativeCoreContext.java index 9e24b03762b..fbd533d39de 100644 --- a/OsmAnd/src/net/osmand/plus/views/corenative/NativeCoreContext.java +++ b/OsmAnd/src/net/osmand/plus/views/corenative/NativeCoreContext.java @@ -109,10 +109,8 @@ public static MapRendererContext getMapRendererContext() { } public static void setMapRendererContext(@NonNull OsmandApplication app, float density) { - if (mapRendererContext != null) { - if (mapRendererContext.getDensity() == density) - return; - mapRendererContext.setMapRendererView(null); + if (mapRendererContext != null && mapRendererContext.getDensity() == density) { + return; } mapRendererContext = new MapRendererContext(app, density); mapRendererContext.setupObfMap(new MapStylesCollection(), obfsCollectionsByProviderType); diff --git a/OsmAnd/src/net/osmand/plus/views/mapwidgets/TurnDrawable.java b/OsmAnd/src/net/osmand/plus/views/mapwidgets/TurnDrawable.java index 35b3797a639..5d109f2854c 100644 --- a/OsmAnd/src/net/osmand/plus/views/mapwidgets/TurnDrawable.java +++ b/OsmAnd/src/net/osmand/plus/views/mapwidgets/TurnDrawable.java @@ -1,27 +1,26 @@ package net.osmand.plus.views.mapwidgets; import android.content.Context; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.ColorFilter; -import android.graphics.Matrix; -import android.graphics.Paint; -import android.graphics.Path; -import android.graphics.PointF; -import android.graphics.Rect; +import android.graphics.*; import android.graphics.drawable.Drawable; import android.text.TextPaint; import androidx.annotation.ColorRes; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.core.content.ContextCompat; +import net.osmand.PlatformUtil; import net.osmand.plus.R; import net.osmand.plus.views.TurnPathHelper; import net.osmand.router.TurnType; +import org.apache.commons.logging.Log; + public class TurnDrawable extends Drawable { + protected static final Log log = PlatformUtil.getLog(TurnDrawable.class); + protected Paint paintBlack; protected Paint paintRouteDirection; protected Path pathForTurn = new Path(); @@ -109,7 +108,7 @@ public void draw(@NonNull Canvas canvas) { } } - public void setTextPaint(TextPaint textPaint) { + public void setTextPaint(@NonNull TextPaint textPaint) { this.textPaint = textPaint; this.textPaint.setTextAlign(Paint.Align.CENTER); } @@ -129,11 +128,12 @@ public int getOpacity() { return 0; } + @Nullable public TurnType getTurnType() { return turnType; } - public boolean setTurnType(TurnType turnType) { + public boolean setTurnType(@Nullable TurnType turnType) { if (turnType != this.turnType && !getBounds().isEmpty()) { this.turnType = turnType; TurnPathHelper.calcTurnPath(pathForTurn, pathForTurnOutlay, turnType, null, diff --git a/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgets/NextTurnBaseWidget.java b/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgets/NextTurnBaseWidget.java index 844af51cc60..13c22d95047 100644 --- a/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgets/NextTurnBaseWidget.java +++ b/OsmAnd/src/net/osmand/plus/views/mapwidgets/widgets/NextTurnBaseWidget.java @@ -77,7 +77,8 @@ public class NextTurnBaseWidget extends TextInfoWidget implements IComplexWidget private boolean isFullRow; protected boolean verticalWidget; - public NextTurnBaseWidget(@NonNull MapActivity mapActivity, @Nullable String customId, @NonNull WidgetType widgetType, @Nullable WidgetsPanel panel, boolean horizontalMini) { + public NextTurnBaseWidget(@NonNull MapActivity mapActivity, @Nullable String customId, + @NonNull WidgetType widgetType, @Nullable WidgetsPanel panel, boolean horizontalMini) { super(mapActivity, widgetType); this.horizontalMini = horizontalMini; this.customId = customId; @@ -179,7 +180,7 @@ public void setTurnType(TurnType turnType) { } else { boolean vis = updateVisibility(turnType != null); if (turnDrawable.setTurnType(turnType) || vis) { - turnDrawable.setTextPaint(topTextView.getPaint()); + turnDrawable.setTextPaint(textPaint); if (horizontalMini) { setImageDrawable(turnDrawable, false); } else { @@ -342,8 +343,8 @@ public void updateColors(@NonNull TextState textState) { updateVerticalWidgetColors(textState); } else { super.updateColors(textState); - updateTextColor(topTextView, null, textState.textColor, textState.textShadowColor, - textState.textBold, textState.textShadowRadius); + updateTextColor(topTextView, null, textState.textColor, + textState.textShadowColor, textState.textBold, textState.textShadowRadius); textPaint.set(topTextView.getPaint()); textPaint.setColor(textState.textColor);