Merge branch 'master' of https://github.com/osmandapp/Osmand into custom_plugins

# Conflicts:
#	OsmAnd/src/net/osmand/plus/helpers/ImportHelper.java
This commit is contained in:
Vitaliy 2020-03-13 18:13:05 +02:00
commit 6cd31957b3
27 changed files with 1198 additions and 459 deletions

View file

@ -0,0 +1,102 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="328dp"
android:height="73dp"
android:viewportWidth="328"
android:viewportHeight="73">
<path
android:pathData="M0,0h328v48h-328z">
<aapt:attr name="android:fillColor">
<gradient
android:startY="24"
android:startX="2.13832E-6"
android:endY="24"
android:endX="328"
android:type="linear">
<item android:offset="0" android:color="#FFFFFFFF"/>
<item android:offset="0.146341" android:color="#FF2EB900"/>
<item android:offset="0.278963" android:color="#FFFFDE02"/>
<item android:offset="0.567073" android:color="#FFFF0101"/>
<item android:offset="0.998611" android:color="#FF8201FF"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M7.068,64.755C7.068,66.236 6.815,67.337 6.31,68.057C5.804,68.777 5.013,69.137 3.938,69.137C2.876,69.137 2.09,68.786 1.579,68.084C1.069,67.378 0.804,66.325 0.786,64.926V63.237C0.786,61.774 1.039,60.688 1.545,59.977C2.051,59.266 2.844,58.91 3.924,58.91C4.995,58.91 5.783,59.254 6.289,59.942C6.795,60.626 7.055,61.683 7.068,63.114V64.755ZM5.804,63.025C5.804,61.954 5.653,61.175 5.353,60.688C5.052,60.195 4.576,59.949 3.924,59.949C3.277,59.949 2.805,60.193 2.509,60.681C2.213,61.168 2.06,61.918 2.051,62.93V64.953C2.051,66.029 2.206,66.824 2.516,67.339C2.83,67.849 3.304,68.104 3.938,68.104C4.562,68.104 5.024,67.863 5.325,67.38C5.631,66.897 5.79,66.136 5.804,65.097V63.025Z"
android:fillColor="#727272"/>
<path
android:pathData="M9.03,60.688C9.03,60.214 9.199,59.799 9.536,59.443C9.878,59.088 10.29,58.91 10.773,58.91C11.247,58.91 11.65,59.088 11.983,59.443C12.32,59.794 12.489,60.209 12.489,60.688C12.489,61.171 12.32,61.583 11.983,61.925C11.65,62.267 11.247,62.438 10.773,62.438C10.295,62.438 9.884,62.267 9.543,61.925C9.201,61.583 9.03,61.171 9.03,60.688ZM10.773,61.563C11.019,61.563 11.227,61.483 11.395,61.323C11.564,61.159 11.648,60.947 11.648,60.688C11.648,60.423 11.564,60.207 11.395,60.038C11.227,59.865 11.019,59.778 10.773,59.778C10.523,59.778 10.311,59.869 10.137,60.052C9.969,60.229 9.884,60.441 9.884,60.688C9.884,60.934 9.969,61.141 10.137,61.31C10.311,61.478 10.523,61.563 10.773,61.563Z"
android:fillColor="#727272"/>
<path
android:pathData="M43.837,63.408H44.787C45.384,63.399 45.854,63.242 46.196,62.937C46.537,62.631 46.708,62.219 46.708,61.699C46.708,60.533 46.127,59.949 44.965,59.949C44.418,59.949 43.981,60.106 43.653,60.421C43.329,60.731 43.167,61.143 43.167,61.658H41.903C41.903,60.87 42.19,60.216 42.764,59.696C43.343,59.172 44.076,58.91 44.965,58.91C45.904,58.91 46.64,59.159 47.173,59.655C47.706,60.152 47.973,60.842 47.973,61.727C47.973,62.16 47.832,62.579 47.549,62.984C47.271,63.39 46.891,63.693 46.408,63.894C46.954,64.067 47.376,64.354 47.672,64.755C47.973,65.156 48.123,65.646 48.123,66.225C48.123,67.118 47.832,67.826 47.248,68.351C46.665,68.875 45.906,69.137 44.972,69.137C44.038,69.137 43.277,68.884 42.689,68.378C42.105,67.872 41.814,67.204 41.814,66.375H43.085C43.085,66.899 43.256,67.318 43.598,67.633C43.94,67.947 44.398,68.104 44.972,68.104C45.583,68.104 46.05,67.945 46.373,67.626C46.697,67.307 46.859,66.849 46.859,66.252C46.859,65.673 46.681,65.229 46.326,64.919C45.97,64.609 45.457,64.45 44.787,64.44H43.837V63.408Z"
android:fillColor="#727272"/>
<path
android:pathData="M50.201,60.688C50.201,60.214 50.37,59.799 50.707,59.443C51.049,59.088 51.461,58.91 51.944,58.91C52.418,58.91 52.822,59.088 53.154,59.443C53.492,59.794 53.66,60.209 53.66,60.688C53.66,61.171 53.492,61.583 53.154,61.925C52.822,62.267 52.418,62.438 51.944,62.438C51.466,62.438 51.056,62.267 50.714,61.925C50.372,61.583 50.201,61.171 50.201,60.688ZM51.944,61.563C52.19,61.563 52.398,61.483 52.566,61.323C52.735,61.159 52.819,60.947 52.819,60.688C52.819,60.423 52.735,60.207 52.566,60.038C52.398,59.865 52.19,59.778 51.944,59.778C51.694,59.778 51.482,59.869 51.309,60.052C51.14,60.229 51.056,60.441 51.056,60.688C51.056,60.934 51.14,61.141 51.309,61.31C51.482,61.478 51.694,61.563 51.944,61.563Z"
android:fillColor="#727272"/>
<path
android:pathData="M89.084,69H87.812V60.571L85.263,61.508V60.359L88.886,58.999H89.084V69Z"
android:fillColor="#727272"/>
<path
android:pathData="M99.31,64.755C99.31,66.236 99.057,67.337 98.551,68.057C98.046,68.777 97.255,69.137 96.179,69.137C95.118,69.137 94.331,68.786 93.821,68.084C93.311,67.378 93.046,66.325 93.028,64.926V63.237C93.028,61.774 93.281,60.688 93.787,59.977C94.293,59.266 95.086,58.91 96.166,58.91C97.237,58.91 98.025,59.254 98.531,59.942C99.037,60.626 99.297,61.683 99.31,63.114V64.755ZM98.046,63.025C98.046,61.954 97.895,61.175 97.594,60.688C97.294,60.195 96.817,59.949 96.166,59.949C95.519,59.949 95.047,60.193 94.751,60.681C94.454,61.168 94.302,61.918 94.293,62.93V64.953C94.293,66.029 94.448,66.824 94.757,67.339C95.072,67.849 95.546,68.104 96.179,68.104C96.804,68.104 97.266,67.863 97.567,67.38C97.872,66.897 98.032,66.136 98.046,65.097V63.025Z"
android:fillColor="#727272"/>
<path
android:pathData="M101.272,60.688C101.272,60.214 101.44,59.799 101.778,59.443C102.119,59.088 102.532,58.91 103.015,58.91C103.489,58.91 103.892,59.088 104.225,59.443C104.562,59.794 104.731,60.209 104.731,60.688C104.731,61.171 104.562,61.583 104.225,61.925C103.892,62.267 103.489,62.438 103.015,62.438C102.536,62.438 102.126,62.267 101.785,61.925C101.443,61.583 101.272,61.171 101.272,60.688ZM103.015,61.563C103.261,61.563 103.468,61.483 103.637,61.323C103.806,61.159 103.89,60.947 103.89,60.688C103.89,60.423 103.806,60.207 103.637,60.038C103.468,59.865 103.261,59.778 103.015,59.778C102.764,59.778 102.552,59.869 102.379,60.052C102.211,60.229 102.126,60.441 102.126,60.688C102.126,60.934 102.211,61.141 102.379,61.31C102.552,61.478 102.764,61.563 103.015,61.563Z"
android:fillColor="#727272"/>
<path
android:pathData="M182.767,63.408H183.717C184.314,63.399 184.783,63.242 185.125,62.937C185.467,62.631 185.638,62.219 185.638,61.699C185.638,60.533 185.057,59.949 183.894,59.949C183.348,59.949 182.91,60.106 182.582,60.421C182.258,60.731 182.097,61.143 182.097,61.658H180.832C180.832,60.87 181.119,60.216 181.693,59.696C182.272,59.172 183.006,58.91 183.894,58.91C184.833,58.91 185.569,59.159 186.102,59.655C186.636,60.152 186.902,60.842 186.902,61.727C186.902,62.16 186.761,62.579 186.478,62.984C186.2,63.39 185.82,63.693 185.337,63.894C185.884,64.067 186.305,64.354 186.601,64.755C186.902,65.156 187.053,65.646 187.053,66.225C187.053,67.118 186.761,67.826 186.178,68.351C185.594,68.875 184.836,69.137 183.901,69.137C182.967,69.137 182.206,68.884 181.618,68.378C181.035,67.872 180.743,67.204 180.743,66.375H182.015C182.015,66.899 182.185,67.318 182.527,67.633C182.869,67.947 183.327,68.104 183.901,68.104C184.512,68.104 184.979,67.945 185.303,67.626C185.626,67.307 185.788,66.849 185.788,66.252C185.788,65.673 185.61,65.229 185.255,64.919C184.899,64.609 184.387,64.45 183.717,64.44H182.767V63.408Z"
android:fillColor="#727272"/>
<path
android:pathData="M195.31,64.755C195.31,66.236 195.057,67.337 194.551,68.057C194.046,68.777 193.255,69.137 192.179,69.137C191.117,69.137 190.331,68.786 189.821,68.084C189.311,67.378 189.046,66.325 189.028,64.926V63.237C189.028,61.774 189.281,60.688 189.787,59.977C190.293,59.266 191.086,58.91 192.166,58.91C193.237,58.91 194.025,59.254 194.531,59.942C195.037,60.626 195.297,61.683 195.31,63.114V64.755ZM194.046,63.025C194.046,61.954 193.895,61.175 193.594,60.688C193.294,60.195 192.817,59.949 192.166,59.949C191.519,59.949 191.047,60.193 190.751,60.681C190.454,61.168 190.302,61.918 190.293,62.93V64.953C190.293,66.029 190.448,66.824 190.757,67.339C191.072,67.849 191.546,68.104 192.179,68.104C192.804,68.104 193.266,67.863 193.567,67.38C193.872,66.897 194.032,66.136 194.046,65.097V63.025Z"
android:fillColor="#727272"/>
<path
android:pathData="M197.272,60.688C197.272,60.214 197.44,59.799 197.778,59.443C198.119,59.088 198.532,58.91 199.015,58.91C199.489,58.91 199.892,59.088 200.225,59.443C200.562,59.794 200.731,60.209 200.731,60.688C200.731,61.171 200.562,61.583 200.225,61.925C199.892,62.267 199.489,62.438 199.015,62.438C198.536,62.438 198.126,62.267 197.785,61.925C197.443,61.583 197.272,61.171 197.272,60.688ZM199.015,61.563C199.261,61.563 199.468,61.483 199.637,61.323C199.806,61.159 199.89,60.947 199.89,60.688C199.89,60.423 199.806,60.207 199.637,60.038C199.468,59.865 199.261,59.778 199.015,59.778C198.764,59.778 198.552,59.869 198.379,60.052C198.211,60.229 198.126,60.441 198.126,60.688C198.126,60.934 198.211,61.141 198.379,61.31C198.552,61.478 198.764,61.563 199.015,61.563Z"
android:fillColor="#727272"/>
<path
android:pathData="M135.449,69H128.928V68.091L132.373,64.263C132.883,63.684 133.234,63.215 133.426,62.854C133.622,62.49 133.72,62.114 133.72,61.727C133.72,61.207 133.562,60.781 133.248,60.448C132.934,60.116 132.514,59.949 131.99,59.949C131.361,59.949 130.871,60.129 130.52,60.489C130.174,60.845 130.001,61.341 130.001,61.979H128.736C128.736,61.063 129.03,60.323 129.618,59.758C130.211,59.193 131.001,58.91 131.99,58.91C132.915,58.91 133.647,59.154 134.184,59.642C134.722,60.125 134.991,60.77 134.991,61.576C134.991,62.556 134.367,63.723 133.118,65.076L130.452,67.968H135.449V69Z"
android:fillColor="#727272"/>
<path
android:pathData="M143.31,64.755C143.31,66.236 143.057,67.337 142.551,68.057C142.046,68.777 141.255,69.137 140.179,69.137C139.117,69.137 138.331,68.786 137.821,68.084C137.311,67.378 137.046,66.325 137.028,64.926V63.237C137.028,61.774 137.281,60.688 137.787,59.977C138.293,59.266 139.086,58.91 140.166,58.91C141.237,58.91 142.025,59.254 142.531,59.942C143.037,60.626 143.297,61.683 143.31,63.114V64.755ZM142.046,63.025C142.046,61.954 141.895,61.175 141.594,60.688C141.294,60.195 140.817,59.949 140.166,59.949C139.519,59.949 139.047,60.193 138.751,60.681C138.454,61.168 138.302,61.918 138.293,62.93V64.953C138.293,66.029 138.448,66.824 138.757,67.339C139.072,67.849 139.546,68.104 140.179,68.104C140.804,68.104 141.266,67.863 141.567,67.38C141.872,66.897 142.032,66.136 142.046,65.097V63.025Z"
android:fillColor="#727272"/>
<path
android:pathData="M145.272,60.688C145.272,60.214 145.44,59.799 145.778,59.443C146.119,59.088 146.532,58.91 147.015,58.91C147.489,58.91 147.892,59.088 148.225,59.443C148.562,59.794 148.731,60.209 148.731,60.688C148.731,61.171 148.562,61.583 148.225,61.925C147.892,62.267 147.489,62.438 147.015,62.438C146.536,62.438 146.126,62.267 145.785,61.925C145.443,61.583 145.272,61.171 145.272,60.688ZM147.015,61.563C147.261,61.563 147.468,61.483 147.637,61.323C147.806,61.159 147.89,60.947 147.89,60.688C147.89,60.423 147.806,60.207 147.637,60.038C147.468,59.865 147.261,59.778 147.015,59.778C146.764,59.778 146.552,59.869 146.379,60.052C146.211,60.229 146.126,60.441 146.126,60.688C146.126,60.934 146.211,61.141 146.379,61.31C146.552,61.478 146.764,61.563 147.015,61.563Z"
android:fillColor="#727272"/>
<path
android:pathData="M243.267,65.657H244.647V66.689H243.267V69H241.995V66.689H237.463V65.944L241.92,59.047H243.267V65.657ZM238.898,65.657H241.995V60.776L241.845,61.05L238.898,65.657Z"
android:fillColor="#727272"/>
<path
android:pathData="M246.65,64.01L247.156,59.047H252.256V60.216H248.229L247.928,62.93C248.416,62.643 248.97,62.499 249.589,62.499C250.496,62.499 251.216,62.8 251.75,63.401C252.283,63.998 252.549,64.807 252.549,65.828C252.549,66.854 252.271,67.662 251.715,68.255C251.164,68.843 250.392,69.137 249.398,69.137C248.519,69.137 247.801,68.893 247.245,68.405C246.689,67.918 246.372,67.243 246.295,66.382H247.491C247.568,66.951 247.771,67.382 248.099,67.674C248.427,67.961 248.86,68.104 249.398,68.104C249.986,68.104 250.446,67.904 250.779,67.503C251.116,67.102 251.285,66.548 251.285,65.842C251.285,65.176 251.103,64.643 250.738,64.242C250.378,63.837 249.897,63.634 249.296,63.634C248.744,63.634 248.311,63.755 247.997,63.996L247.662,64.27L246.65,64.01Z"
android:fillColor="#727272"/>
<path
android:pathData="M254.272,60.688C254.272,60.214 254.44,59.799 254.778,59.443C255.119,59.088 255.532,58.91 256.015,58.91C256.489,58.91 256.892,59.088 257.225,59.443C257.562,59.794 257.731,60.209 257.731,60.688C257.731,61.171 257.562,61.583 257.225,61.925C256.892,62.267 256.489,62.438 256.015,62.438C255.536,62.438 255.126,62.267 254.785,61.925C254.443,61.583 254.272,61.171 254.272,60.688ZM256.015,61.563C256.261,61.563 256.468,61.483 256.637,61.323C256.806,61.159 256.89,60.947 256.89,60.688C256.89,60.423 256.806,60.207 256.637,60.038C256.468,59.865 256.261,59.778 256.015,59.778C255.764,59.778 255.552,59.869 255.379,60.052C255.211,60.229 255.126,60.441 255.126,60.688C255.126,60.934 255.211,61.141 255.379,61.31C255.552,61.478 255.764,61.563 256.015,61.563Z"
android:fillColor="#727272"/>
<path
android:pathData="M311.991,59.04V60.113H311.759C310.774,60.132 309.99,60.423 309.407,60.988C308.824,61.553 308.487,62.349 308.395,63.374C308.919,62.772 309.635,62.472 310.542,62.472C311.408,62.472 312.098,62.777 312.613,63.388C313.133,63.998 313.392,64.787 313.392,65.753C313.392,66.778 313.112,67.599 312.552,68.214C311.996,68.829 311.248,69.137 310.309,69.137C309.357,69.137 308.584,68.772 307.992,68.043C307.4,67.309 307.103,66.366 307.103,65.213V64.728C307.103,62.896 307.493,61.496 308.272,60.53C309.056,59.56 310.221,59.063 311.765,59.04H311.991ZM310.33,63.524C309.897,63.524 309.498,63.654 309.134,63.914C308.769,64.174 308.516,64.5 308.375,64.892V65.356C308.375,66.177 308.559,66.838 308.929,67.339C309.298,67.84 309.758,68.091 310.309,68.091C310.879,68.091 311.326,67.881 311.649,67.462C311.977,67.043 312.141,66.493 312.141,65.814C312.141,65.131 311.975,64.579 311.642,64.16C311.314,63.736 310.877,63.524 310.33,63.524Z"
android:fillColor="#727272"/>
<path
android:pathData="M321.411,64.755C321.411,66.236 321.158,67.337 320.652,68.057C320.146,68.777 319.355,69.137 318.28,69.137C317.218,69.137 316.432,68.786 315.921,68.084C315.411,67.378 315.147,66.325 315.128,64.926V63.237C315.128,61.774 315.381,60.688 315.887,59.977C316.393,59.266 317.186,58.91 318.266,58.91C319.337,58.91 320.126,59.254 320.631,59.942C321.137,60.626 321.397,61.683 321.411,63.114V64.755ZM320.146,63.025C320.146,61.954 319.996,61.175 319.695,60.688C319.394,60.195 318.918,59.949 318.266,59.949C317.619,59.949 317.147,60.193 316.851,60.681C316.555,61.168 316.402,61.918 316.393,62.93V64.953C316.393,66.029 316.548,66.824 316.858,67.339C317.172,67.849 317.646,68.104 318.28,68.104C318.904,68.104 319.367,67.863 319.668,67.38C319.973,66.897 320.132,66.136 320.146,65.097V63.025Z"
android:fillColor="#727272"/>
<path
android:pathData="M323.372,60.688C323.372,60.214 323.541,59.799 323.878,59.443C324.22,59.088 324.632,58.91 325.116,58.91C325.589,58.91 325.993,59.088 326.325,59.443C326.663,59.794 326.831,60.209 326.831,60.688C326.831,61.171 326.663,61.583 326.325,61.925C325.993,62.267 325.589,62.438 325.116,62.438C324.637,62.438 324.227,62.267 323.885,61.925C323.543,61.583 323.372,61.171 323.372,60.688ZM325.116,61.563C325.362,61.563 325.569,61.483 325.738,61.323C325.906,61.159 325.991,60.947 325.991,60.688C325.991,60.423 325.906,60.207 325.738,60.038C325.569,59.865 325.362,59.778 325.116,59.778C324.865,59.778 324.653,59.869 324.48,60.052C324.311,60.229 324.227,60.441 324.227,60.688C324.227,60.934 324.311,61.141 324.48,61.31C324.653,61.478 324.865,61.563 325.116,61.563Z"
android:fillColor="#727272"/>
<path
android:pathData="M0,48H1V54H0V48Z"
android:fillColor="#CBC7D1"/>
<path
android:pathData="M47,48H48V54H47V48Z"
android:fillColor="#CBC7D1"/>
<path
android:pathData="M92,48H93V54H92V48Z"
android:fillColor="#CBC7D1"/>
<path
android:pathData="M186,48H187V54H186V48Z"
android:fillColor="#CBC7D1"/>
<path
android:pathData="M137,48H138V54H137V48Z"
android:fillColor="#CBC7D1"/>
<path
android:pathData="M242,48H243V54H242V48Z"
android:fillColor="#CBC7D1"/>
<path
android:pathData="M327,48H328V54H327V48Z"
android:fillColor="#CBC7D1"/>
</vector>

View file

@ -128,6 +128,16 @@
</com.google.android.material.appbar.CollapsingToolbarLayout> </com.google.android.material.appbar.CollapsingToolbarLayout>
<ProgressBar
android:id="@+id/progress_bar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="true"
android:minHeight="0dp"
android:visibility="gone"
tools:visibility="visible" />
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -0,0 +1,128 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:osmand="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/activity_background_basic">
<androidx.core.widget.NestedScrollView
android:id="@+id/nested_scroll"
android:layout_width="match_parent"
android:layout_height="match_parent"
osmand:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/bg_color"
android:orientation="vertical">
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/description"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingStart="@dimen/content_padding"
android:paddingTop="@dimen/list_header_settings_top_margin"
android:paddingEnd="@dimen/content_padding"
android:paddingBottom="@dimen/list_header_settings_top_margin"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/default_list_text_size"
tools:text="@string/import_complete_description" />
<include
layout="@layout/divider"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/content_padding"
android:layout_marginLeft="@dimen/content_padding" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:paddingBottom="@dimen/bottom_sheet_cancel_button_height" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="?attr/bg_color"
android:orientation="vertical">
<include layout="@layout/divider" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="@dimen/dialog_button_height"
android:layout_marginStart="@dimen/content_padding"
android:layout_marginTop="@dimen/content_padding_small"
android:layout_marginEnd="@dimen/content_padding"
android:layout_marginBottom="@dimen/content_padding_small"
android:background="?attr/dlg_btn_secondary">
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/button_close"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/selectableItemBackground"
android:gravity="center"
android:text="@string/shared_string_close"
android:textColor="?attr/active_color_basic"
android:textSize="@dimen/default_desc_text_size"
osmand:typeface="@string/font_roboto_medium"
tools:text="Button" />
</FrameLayout>
</LinearLayout>
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/toolbar_layout"
android:layout_width="match_parent"
android:layout_height="@dimen/toolbar_height_expanded"
android:background="?attr/colorPrimary"
osmand:collapsedTitleTextAppearance="@style/AppBarTitle"
osmand:expandedTitleGravity="start|bottom"
osmand:expandedTitleTextAppearance="@style/AppBarTitle"
osmand:layout_scrollFlags="scroll|exitUntilCollapsed">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="@dimen/toolbar_height"
android:minHeight="@dimen/toolbar_height"
osmand:layout_collapseMode="pin"
osmand:layout_scrollFlags="scroll|enterAlways|exitUntilCollapsed"
osmand:title="@string/shared_string_import_complete"/>
</com.google.android.material.appbar.CollapsingToolbarLayout>
<ImageView
android:id="@+id/shadowView"
android:layout_width="match_parent"
android:layout_height="@dimen/abp__shadow_height"
android:src="@drawable/preference_activity_action_bar_shadow"
tools:ignore="ContentDescription" />
</com.google.android.material.appbar.AppBarLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -3,6 +3,7 @@
xmlns:osmand="http://schemas.android.com/apk/res-auto" xmlns:osmand="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
android:background="?attr/activity_background_basic"> android:background="?attr/activity_background_basic">
<androidx.core.widget.NestedScrollView <androidx.core.widget.NestedScrollView
@ -128,12 +129,22 @@
osmand:titleMarginStart="0dp" osmand:titleMarginStart="0dp"
osmand:layout_collapseMode="pin" osmand:layout_collapseMode="pin"
osmand:layout_scrollFlags="scroll|enterAlways|exitUntilCollapsed" osmand:layout_scrollFlags="scroll|enterAlways|exitUntilCollapsed"
osmand:title="@string/import_duplicates_title"> tools:title="@string/import_duplicates_title">
</androidx.appcompat.widget.Toolbar> </androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.CollapsingToolbarLayout> </com.google.android.material.appbar.CollapsingToolbarLayout>
<ProgressBar
android:id="@+id/progress_bar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="0dp"
android:indeterminate="true"
android:visibility="gone"
tools:visibility="visible" />
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -7,11 +7,17 @@
android:minHeight="@dimen/setting_list_item_small_height" android:minHeight="@dimen/setting_list_item_small_height"
android:orientation="vertical"> android:orientation="vertical">
<FrameLayout
android:background="?attr/bg_color"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/bg_color" android:background="?attr/selectableItemBackground"
android:gravity="center_vertical"> android:gravity="center_vertical"
android:orientation="horizontal">
<ImageView <ImageView
android:id="@+id/icon" android:id="@+id/icon"
@ -51,6 +57,8 @@
</LinearLayout> </LinearLayout>
</FrameLayout>
<include <include
android:id="@+id/bottom_divider" android:id="@+id/bottom_divider"
layout="@layout/card_bottom_divider" layout="@layout/card_bottom_divider"

View file

@ -16,6 +16,12 @@
<string name="restore_all_profile_settings">Restore all profile settings?</string> <string name="restore_all_profile_settings">Restore all profile settings?</string>
<string name="saving_new_profile">Saving new profile</string> <string name="saving_new_profile">Saving new profile</string>
<string name="profile_backup_failed">Could not back up profile.</string> <string name="profile_backup_failed">Could not back up profile.</string>
<string name="importing_from">Importing data from %1$s</string>
<string name="shared_string_importing">Importing</string>
<string name="checking_for_duplicate_description">OsmAnd check %1$s for duplicates with existing items in the application.\n\nIt may take some time.</string>
<string name="items_added">Items added</string>
<string name="shared_string_import_complete">Import complete</string>
<string name="import_complete_description">All data from the %1$s is imported, you can use buttons below to open needed part of the application to manage it.</string>
<string name="import_rendering_file">Import rendering file</string> <string name="import_rendering_file">Import rendering file</string>
<string name="profile_type_custom_string">Custom profile</string> <string name="profile_type_custom_string">Custom profile</string>
<string name="shared_string_angle_param">Angle: %s°</string> <string name="shared_string_angle_param">Angle: %s°</string>

View file

@ -126,9 +126,9 @@ public class SQLiteTileSource implements ITileSource {
db = ctx.getSQLiteAPI().getOrCreateDatabase( db = ctx.getSQLiteAPI().getOrCreateDatabase(
ctx.getAppPath(TILES_INDEX_DIR).getAbsolutePath() + "/" + name + SQLITE_EXT, true); ctx.getAppPath(TILES_INDEX_DIR).getAbsolutePath() + "/" + name + SQLITE_EXT, true);
db.execSQL("CREATE TABLE tiles (x int, y int, z int, s int, image blob, time long, PRIMARY KEY (x,y,z,s))"); db.execSQL("CREATE TABLE IF NOT EXISTS tiles (x int, y int, z int, s int, image blob, time long, PRIMARY KEY (x,y,z,s))");
db.execSQL("CREATE INDEX IND on tiles (x,y,z,s)"); db.execSQL("CREATE INDEX IF NOT EXISTS IND on tiles (x,y,z,s)");
db.execSQL("CREATE TABLE info(tilenumbering,minzoom,maxzoom)"); db.execSQL("CREATE TABLE IF NOT EXISTS info(tilenumbering,minzoom,maxzoom)");
db.execSQL("INSERT INTO info (tilenumbering,minzoom,maxzoom) VALUES ('simple','" + minZoom + "','" + maxZoom + "');"); db.execSQL("INSERT INTO info (tilenumbering,minzoom,maxzoom) VALUES ('simple','" + minZoom + "','" + maxZoom + "');");
addInfoColumn(URL, urlTemplate); addInfoColumn(URL, urlTemplate);

View file

@ -1,13 +1,11 @@
package net.osmand.plus; package net.osmand.plus;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.os.AsyncTask; import android.os.AsyncTask;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken; import com.google.gson.reflect.TypeToken;
@ -96,16 +94,20 @@ public class SettingsHelper {
private static final int BUFFER = 1024; private static final int BUFFER = 1024;
private OsmandApplication app; private OsmandApplication app;
private Activity activity;
private boolean importing;
private boolean importSuspended;
private boolean collectOnly;
private ImportAsyncTask importTask; private ImportAsyncTask importTask;
private Map<File, ExportAsyncTask> exportAsyncTasks = new HashMap<>(); private Map<File, ExportAsyncTask> exportAsyncTasks = new HashMap<>();
public interface SettingsImportListener { public interface SettingsImportListener {
void onSettingsImportFinished(boolean succeed, boolean empty, @NonNull List<SettingsItem> items); void onSettingsImportFinished(boolean succeed, @NonNull List<SettingsItem> items);
}
public interface SettingsCollectListener {
void onSettingsCollectFinished(boolean succeed, boolean empty, @NonNull List<SettingsItem> items);
}
public interface CheckDuplicatesListener {
void onDuplicatesChecked(@NonNull List<Object> duplicates, List<SettingsItem> items);
} }
public interface SettingsExportListener { public interface SettingsExportListener {
@ -116,31 +118,6 @@ public class SettingsHelper {
this.app = app; this.app = app;
} }
public Activity getActivity() {
return activity;
}
public void setActivity(Activity activity) {
this.activity = activity;
if (importing && !collectOnly) {
importTask.processNextItem();
}
}
public void resetActivity(Activity activity) {
if (this.activity == activity) {
if (importing) {
importTask.suspendImport();
importSuspended = true;
}
this.activity = null;
}
}
public boolean isImporting() {
return importing;
}
public enum SettingsItemType { public enum SettingsItemType {
GLOBAL, GLOBAL,
PROFILE, PROFILE,
@ -336,6 +313,11 @@ public class SettingsHelper {
return items; return items;
} }
@NonNull
public List<T> getDuplicateItems() {
return duplicateItems;
}
@NonNull @NonNull
public List<T> excludeDuplicateItems() { public List<T> excludeDuplicateItems() {
if (!items.isEmpty()) { if (!items.isEmpty()) {
@ -1897,51 +1879,65 @@ public class SettingsHelper {
} }
@SuppressLint("StaticFieldLeak") @SuppressLint("StaticFieldLeak")
private class ImportAsyncTask extends AsyncTask<Void, Void, List<SettingsItem>> { public class ImportAsyncTask extends AsyncTask<Void, Void, List<SettingsItem>> {
private File file; private File file;
private String latestChanges; private String latestChanges;
private int version; private int version;
private SettingsImportListener listener; private SettingsImportListener importListener;
private SettingsCollectListener collectListener;
private CheckDuplicatesListener duplicatesListener;
private SettingsImporter importer; private SettingsImporter importer;
private List<SettingsItem> items = new ArrayList<>();
private List<SettingsItem> processedItems = new ArrayList<>();
private SettingsItem currentItem;
private AlertDialog dialog;
ImportAsyncTask(@NonNull File settingsFile, String latestChanges, int version, @Nullable SettingsImportListener listener) { private List<SettingsItem> items = new ArrayList<>();
this.file = settingsFile; private List<SettingsItem> selectedItems = new ArrayList<>();
this.listener = listener; private List<Object> duplicates;
private ImportType importType;
private boolean importDone;
ImportAsyncTask(@NonNull File file, String latestChanges, int version, @Nullable SettingsCollectListener collectListener) {
this.file = file;
this.collectListener = collectListener;
this.latestChanges = latestChanges; this.latestChanges = latestChanges;
this.version = version; this.version = version;
importer = new SettingsImporter(app); importer = new SettingsImporter(app);
collectOnly = true; importType = ImportType.COLLECT;
} }
ImportAsyncTask(@NonNull File settingsFile, @NonNull List<SettingsItem> items, String latestChanges, int version, @Nullable SettingsImportListener listener) { ImportAsyncTask(@NonNull File file, @NonNull List<SettingsItem> items, String latestChanges, int version, @Nullable SettingsImportListener importListener) {
this.file = settingsFile; this.file = file;
this.listener = listener; this.importListener = importListener;
this.items = items; this.items = items;
this.latestChanges = latestChanges; this.latestChanges = latestChanges;
this.version = version; this.version = version;
importer = new SettingsImporter(app); importer = new SettingsImporter(app);
collectOnly = false; importType = ImportType.IMPORT;
}
ImportAsyncTask(@NonNull File file, @NonNull List<SettingsItem> items, @NonNull List<SettingsItem> selectedItems, @Nullable CheckDuplicatesListener duplicatesListener) {
this.file = file;
this.items = items;
this.duplicatesListener = duplicatesListener;
this.selectedItems = selectedItems;
importer = new SettingsImporter(app);
importType = ImportType.CHECK_DUPLICATES;
} }
@Override @Override
protected void onPreExecute() { protected void onPreExecute() {
if (importing) { ImportAsyncTask importTask = SettingsHelper.this.importTask;
finishImport(listener, false, false, items); if (importTask != null && !importTask.importDone) {
finishImport(importListener, false, items);
} }
importing = true; SettingsHelper.this.importTask = this;
importSuspended = false;
importTask = this;
} }
@Override @Override
protected List<SettingsItem> doInBackground(Void... voids) { protected List<SettingsItem> doInBackground(Void... voids) {
if (collectOnly) { switch (importType) {
case COLLECT:
try { try {
return importer.collectItems(file); return importer.collectItems(file);
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
@ -1949,83 +1945,113 @@ public class SettingsHelper {
} catch (IOException e) { } catch (IOException e) {
LOG.error("Failed to collect items from: " + file.getName(), e); LOG.error("Failed to collect items from: " + file.getName(), e);
} }
} else { break;
return this.items; case CHECK_DUPLICATES:
this.duplicates = getDuplicatesData(selectedItems);
return selectedItems;
case IMPORT:
return items;
} }
return null; return null;
} }
@Override @Override
protected void onPostExecute(@Nullable List<SettingsItem> items) { protected void onPostExecute(@Nullable List<SettingsItem> items) {
if (items != null) { if (items != null && importType != ImportType.CHECK_DUPLICATES) {
this.items = items; this.items = items;
}
if (collectOnly) {
listener.onSettingsImportFinished(true, false, this.items);
} else if (items != null && items.size() > 0) {
processNextItem();
}
}
private void processNextItem() {
if (activity == null) {
return;
}
if (items.size() == 0 && !importSuspended) {
if (processedItems.size() > 0) {
new ImportItemsAsyncTask(file, listener, processedItems).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else { } else {
finishImport(listener, false, true, items); selectedItems = items;
} }
return; switch (importType) {
case COLLECT:
importDone = true;
collectListener.onSettingsCollectFinished(true, false, this.items);
break;
case CHECK_DUPLICATES:
importDone = true;
if (duplicatesListener != null) {
duplicatesListener.onDuplicatesChecked(duplicates, selectedItems);
} }
final SettingsItem item; break;
if (importSuspended && currentItem != null) { case IMPORT:
item = currentItem; if (items != null && items.size() > 0) {
} else if (items.size() > 0) { for (SettingsItem item : items) {
item = items.remove(0);
currentItem = item;
} else {
item = null;
}
importSuspended = false;
if (item != null) {
acceptItem(item);
} else {
processNextItem();
}
}
private void suspendImport() {
if (dialog != null) {
dialog.dismiss();
dialog = null;
}
}
private void acceptItem(SettingsItem item) {
item.apply(); item.apply();
processedItems.add(item); }
processNextItem(); new ImportItemsAsyncTask(file, importListener, items).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
break;
}
} }
public List<SettingsItem> getItems() { public List<SettingsItem> getItems() {
return this.items; return items;
} }
public File getFile() { public File getFile() {
return this.file; return file;
}
public void setImportListener(SettingsImportListener importListener) {
this.importListener = importListener;
}
public void setDuplicatesListener(CheckDuplicatesListener duplicatesListener) {
this.duplicatesListener = duplicatesListener;
}
ImportType getImportType() {
return importType;
}
boolean isImportDone() {
return importDone;
}
public List<Object> getDuplicates() {
return duplicates;
}
public List<SettingsItem> getSelectedItems() {
return selectedItems;
}
private List<Object> getDuplicatesData(List<SettingsItem> items) {
List<Object> duplicateItems = new ArrayList<>();
for (SettingsItem item : items) {
if (item instanceof ProfileSettingsItem) {
if (item.exists()) {
duplicateItems.add(((ProfileSettingsItem) item).getModeBean());
}
} else if (item instanceof CollectionSettingsItem) {
List duplicates = ((CollectionSettingsItem) item).excludeDuplicateItems();
if (!duplicates.isEmpty()) {
duplicateItems.addAll(duplicates);
}
} else if (item instanceof FileSettingsItem) {
if (item.exists()) {
duplicateItems.add(((FileSettingsItem) item).getFile());
}
}
}
return duplicateItems;
} }
} }
@Nullable @Nullable
public List<SettingsItem> getSettingsItems() { public ImportAsyncTask getImportTask() {
return this.importTask.getItems(); return importTask;
} }
@Nullable @Nullable
public File getSettingsFile() { public ImportType getImportTaskType() {
return this.importTask.getFile(); ImportAsyncTask importTask = this.importTask;
return importTask != null ? importTask.getImportType() : null;
}
public boolean isImportDone() {
ImportAsyncTask importTask = this.importTask;
return importTask == null || importTask.isImportDone();
} }
public boolean isFileExporting(File file) { public boolean isFileExporting(File file) {
@ -2071,16 +2097,14 @@ public class SettingsHelper {
@Override @Override
protected void onPostExecute(Boolean success) { protected void onPostExecute(Boolean success) {
finishImport(listener, success, false, items); finishImport(listener, success, items);
} }
} }
private void finishImport(@Nullable SettingsImportListener listener, boolean success, boolean empty, @NonNull List<SettingsItem> items) { private void finishImport(@Nullable SettingsImportListener listener, boolean success, @NonNull List<SettingsItem> items) {
importing = false;
importSuspended = false;
importTask = null; importTask = null;
if (listener != null) { if (listener != null) {
listener.onSettingsImportFinished(success, empty, items); listener.onSettingsImportFinished(success, items);
} }
} }
@ -2124,10 +2148,15 @@ public class SettingsHelper {
} }
} }
public void importSettings(@NonNull File settingsFile, String latestChanges, int version, @Nullable SettingsImportListener listener) { public void collectSettings(@NonNull File settingsFile, String latestChanges, int version,
@Nullable SettingsCollectListener listener) {
new ImportAsyncTask(settingsFile, latestChanges, version, listener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); new ImportAsyncTask(settingsFile, latestChanges, version, listener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} }
public void checkDuplicates(@NonNull File file, @NonNull List<SettingsItem> items, @NonNull List<SettingsItem> selectedItems, CheckDuplicatesListener listener) {
new ImportAsyncTask(file, items, selectedItems, listener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
public void importSettings(@NonNull File settingsFile, @NonNull List<SettingsItem> items, String latestChanges, int version, @Nullable SettingsImportListener listener) { public void importSettings(@NonNull File settingsFile, @NonNull List<SettingsItem> items, String latestChanges, int version, @Nullable SettingsImportListener listener) {
new ImportAsyncTask(settingsFile, items, latestChanges, version, listener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); new ImportAsyncTask(settingsFile, items, latestChanges, version, listener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} }
@ -2143,4 +2172,10 @@ public class SettingsHelper {
@NonNull SettingsItem... items) { @NonNull SettingsItem... items) {
exportSettings(fileDir, fileName, listener, new ArrayList<>(Arrays.asList(items))); exportSettings(fileDir, fileName, listener, new ArrayList<>(Arrays.asList(items)));
} }
public enum ImportType {
COLLECT,
CHECK_DUPLICATES,
IMPORT
}
} }

View file

@ -4,6 +4,7 @@ import android.content.Context;
import android.content.res.ColorStateList; import android.content.res.ColorStateList;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.PorterDuff; import android.graphics.PorterDuff;
import android.graphics.Typeface;
import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable; import android.graphics.drawable.LayerDrawable;
@ -11,6 +12,9 @@ import android.graphics.drawable.RippleDrawable;
import android.hardware.Sensor; import android.hardware.Sensor;
import android.hardware.SensorManager; import android.hardware.SensorManager;
import android.os.Build; import android.os.Build;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.style.StyleSpan;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -36,14 +40,21 @@ import com.google.android.material.snackbar.Snackbar;
import net.osmand.AndroidUtils; import net.osmand.AndroidUtils;
import net.osmand.Location; import net.osmand.Location;
import net.osmand.PlatformUtil;
import net.osmand.data.LatLon; import net.osmand.data.LatLon;
import net.osmand.plus.views.DirectionDrawable; import net.osmand.plus.views.DirectionDrawable;
import net.osmand.plus.widgets.TextViewEx; import net.osmand.plus.widgets.TextViewEx;
import org.apache.commons.logging.Log;
import java.util.Locale;
import gnu.trove.map.hash.TLongObjectHashMap; import gnu.trove.map.hash.TLongObjectHashMap;
public class UiUtilities { public class UiUtilities {
private static final Log LOG = PlatformUtil.getLog(UiUtilities.class);
private TLongObjectHashMap<Drawable> drawableCache = new TLongObjectHashMap<>(); private TLongObjectHashMap<Drawable> drawableCache = new TLongObjectHashMap<>();
private OsmandApplication app; private OsmandApplication app;
private static final int ORIENTATION_0 = 0; private static final int ORIENTATION_0 = 0;
@ -554,4 +565,20 @@ public class UiUtilities {
v.requestLayout(); v.requestLayout();
} }
} }
public static SpannableString createSpannableString(@NonNull String text, @NonNull String textToStyle, @NonNull StyleSpan styleSpan) {
SpannableString spannable = new SpannableString(text);
try {
int startIndex = text.indexOf(textToStyle);
spannable.setSpan(
styleSpan,
startIndex,
startIndex + textToStyle.length(),
Spanned.SPAN_INCLUSIVE_INCLUSIVE);
return spannable;
} catch (RuntimeException e) {
LOG.error("Error trying to find index of " + textToStyle + " " + e);
return spannable;
}
}
} }

View file

@ -33,6 +33,7 @@ import androidx.core.content.ContextCompat;
import androidx.core.view.ViewCompat; import androidx.core.view.ViewCompat;
import androidx.fragment.app.DialogFragment; import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import net.osmand.AndroidUtils; import net.osmand.AndroidUtils;
import net.osmand.access.AccessibilityAssistant; import net.osmand.access.AccessibilityAssistant;
@ -221,7 +222,10 @@ public class FavoritesSearchFragment extends DialogFragment {
public void onDismiss(DialogInterface dialog) { public void onDismiss(DialogInterface dialog) {
Activity activity = getActivity(); Activity activity = getActivity();
if (activity != null) { if (activity != null) {
getChildFragmentManager().popBackStack(); FragmentManager fragmentManager = getChildFragmentManager();
if (!fragmentManager.isStateSaved()) {
fragmentManager.popBackStack();
}
} }
super.onDismiss(dialog); super.onDismiss(dialog);
} }

View file

@ -136,6 +136,7 @@ import net.osmand.plus.settings.BaseSettingsFragment;
import net.osmand.plus.settings.BaseSettingsFragment.SettingsScreenType; import net.osmand.plus.settings.BaseSettingsFragment.SettingsScreenType;
import net.osmand.plus.settings.ConfigureProfileFragment; import net.osmand.plus.settings.ConfigureProfileFragment;
import net.osmand.plus.settings.DataStorageFragment; import net.osmand.plus.settings.DataStorageFragment;
import net.osmand.plus.settings.ImportCompleteFragment;
import net.osmand.plus.settings.ImportSettingsFragment; import net.osmand.plus.settings.ImportSettingsFragment;
import net.osmand.plus.settings.ProfileAppearanceFragment; import net.osmand.plus.settings.ProfileAppearanceFragment;
import net.osmand.plus.views.AddGpxPointBottomSheetHelper.NewGpxPoint; import net.osmand.plus.views.AddGpxPointBottomSheetHelper.NewGpxPoint;
@ -734,6 +735,11 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
importSettingsFragment.showExitDialog(); importSettingsFragment.showExitDialog();
return; return;
} }
ImportCompleteFragment importCompleteFragment = getImportCompleteFragment();
if (importCompleteFragment != null) {
importCompleteFragment.dismissFragment();
return;
}
super.onBackPressed(); super.onBackPressed();
} }
@ -903,7 +909,6 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
} }
app.getDownloadThread().setUiActivity(this); app.getDownloadThread().setUiActivity(this);
app.getSettingsHelper().setActivity(this);
boolean routeWasFinished = routingHelper.isRouteWasFinished(); boolean routeWasFinished = routingHelper.isRouteWasFinished();
if (routeWasFinished && !DestinationReachedMenu.wasShown()) { if (routeWasFinished && !DestinationReachedMenu.wasShown()) {
@ -1128,10 +1133,9 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
} }
public void dismissCardDialog() { public void dismissCardDialog() {
try { FragmentManager fragmentManager = getSupportFragmentManager();
getSupportFragmentManager().popBackStack(ContextMenuCardDialogFragment.TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE); if (!fragmentManager.isStateSaved()) {
} catch (Exception e) { fragmentManager.popBackStack(ContextMenuCardDialogFragment.TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE);
e.printStackTrace();
} }
} }
@ -1504,7 +1508,6 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
app.getMapMarkersHelper().removeListener(this); app.getMapMarkersHelper().removeListener(this);
app.getRoutingHelper().removeListener(this); app.getRoutingHelper().removeListener(this);
app.getDownloadThread().resetUiActivity(this); app.getDownloadThread().resetUiActivity(this);
app.getSettingsHelper().resetActivity(this);
if (atlasMapRendererView != null) { if (atlasMapRendererView != null) {
atlasMapRendererView.handleOnPause(); atlasMapRendererView.handleOnPause();
} }
@ -2166,10 +2169,9 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
} }
public void dismissSettingsScreens() { public void dismissSettingsScreens() {
try { FragmentManager fragmentManager = getSupportFragmentManager();
getSupportFragmentManager().popBackStack(DRAWER_SETTINGS_ID + ".new", FragmentManager.POP_BACK_STACK_INCLUSIVE); if (!fragmentManager.isStateSaved()) {
} catch (Exception e) { fragmentManager.popBackStack(DRAWER_SETTINGS_ID + ".new", FragmentManager.POP_BACK_STACK_INCLUSIVE);
e.printStackTrace();
} }
} }
@ -2453,10 +2455,14 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
return getFragment(ImportSettingsFragment.TAG); return getFragment(ImportSettingsFragment.TAG);
} }
public ImportCompleteFragment getImportCompleteFragment() {
return getFragment(ImportCompleteFragment.TAG);
}
public void backToConfigureProfileFragment() { public void backToConfigureProfileFragment() {
FragmentManager fragmentManager = getSupportFragmentManager(); FragmentManager fragmentManager = getSupportFragmentManager();
int backStackEntryCount = fragmentManager.getBackStackEntryCount(); int backStackEntryCount = fragmentManager.getBackStackEntryCount();
if (backStackEntryCount > 0) { if (backStackEntryCount > 0 && !fragmentManager.isStateSaved()) {
BackStackEntry entry = fragmentManager.getBackStackEntryAt(backStackEntryCount - 1); BackStackEntry entry = fragmentManager.getBackStackEntryAt(backStackEntryCount - 1);
if (ConfigureProfileFragment.TAG.equals(entry.getName())) { if (ConfigureProfileFragment.TAG.equals(entry.getName())) {
fragmentManager.popBackStack(); fragmentManager.popBackStack();

View file

@ -8,6 +8,7 @@ import android.view.WindowManager;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager;
import net.osmand.plus.R; import net.osmand.plus.R;
@ -59,6 +60,12 @@ public class AudioVideoNoteRecordingMenuFullScreenFragment extends Fragment {
public void dismiss() { public void dismiss() {
dismissing = true; dismissing = true;
getActivity().getSupportFragmentManager().popBackStack(); FragmentActivity activity = getActivity();
if (activity != null) {
FragmentManager fragmentManager = activity.getSupportFragmentManager();
if (!fragmentManager.isStateSaved()) {
fragmentManager.popBackStack();
}
}
} }
} }

View file

@ -937,11 +937,9 @@ public abstract class ContextMenuFragment extends BaseOsmAndFragment {
if (isSingleFragment()) { if (isSingleFragment()) {
FragmentActivity activity = getActivity(); FragmentActivity activity = getActivity();
if (activity != null) { if (activity != null) {
try { FragmentManager fragmentManager = activity.getSupportFragmentManager();
activity.getSupportFragmentManager().popBackStack(getFragmentTag(), if (!fragmentManager.isStateSaved()) {
FragmentManager.POP_BACK_STACK_INCLUSIVE); fragmentManager.popBackStack(getFragmentTag(), FragmentManager.POP_BACK_STACK_INCLUSIVE);
} catch (Exception e) {
//
} }
} }
} }

View file

@ -48,6 +48,7 @@ import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin; import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.SettingsHelper; import net.osmand.plus.SettingsHelper;
import net.osmand.plus.SettingsHelper.SettingsCollectListener;
import net.osmand.plus.SettingsHelper.SettingsImportListener; import net.osmand.plus.SettingsHelper.SettingsImportListener;
import net.osmand.plus.UiUtilities; import net.osmand.plus.UiUtilities;
import net.osmand.plus.activities.ActivityResultListener; import net.osmand.plus.activities.ActivityResultListener;
@ -341,10 +342,11 @@ public class ImportHelper {
@Override @Override
protected void onPreExecute() { protected void onPreExecute() {
progress = ProgressDialog if (AndroidUtils.isActivityNotDestroyed(activity)) {
.show(activity, app.getString(R.string.loading_smth, ""), progress = ProgressDialog.show(activity, app.getString(R.string.loading_smth, ""),
app.getString(R.string.loading_data)); app.getString(R.string.loading_data));
} }
}
@Override @Override
protected GPXFile doInBackground(Void... nothing) { protected GPXFile doInBackground(Void... nothing) {
@ -362,7 +364,7 @@ public class ImportHelper {
@Override @Override
protected void onPostExecute(GPXFile result) { protected void onPostExecute(GPXFile result) {
if (AndroidUtils.isActivityNotDestroyed(activity)) { if (progress != null && AndroidUtils.isActivityNotDestroyed(activity)) {
progress.dismiss(); progress.dismiss();
} }
Toast.makeText(activity, R.string.fav_imported_sucessfully, Toast.LENGTH_LONG) Toast.makeText(activity, R.string.fav_imported_sucessfully, Toast.LENGTH_LONG)
@ -679,7 +681,9 @@ public class ImportHelper {
@Override @Override
protected void onPreExecute() { protected void onPreExecute() {
if (AndroidUtils.isActivityNotDestroyed(activity)) {
progress = ProgressDialog.show(activity, app.getString(R.string.loading_smth, ""), app.getString(R.string.loading_data)); progress = ProgressDialog.show(activity, app.getString(R.string.loading_smth, ""), app.getString(R.string.loading_data));
}
mFileName = fileName; mFileName = fileName;
} }
@ -705,7 +709,7 @@ public class ImportHelper {
loadRoutingFiles(app, new AppInitializer.LoadRoutingFilesCallback() { loadRoutingFiles(app, new AppInitializer.LoadRoutingFilesCallback() {
@Override @Override
public void onRoutingFilesLoaded() { public void onRoutingFilesLoaded() {
if (AndroidUtils.isActivityNotDestroyed(activity)) { if (progress != null && AndroidUtils.isActivityNotDestroyed(activity)) {
progress.dismiss(); progress.dismiss();
} }
RoutingConfiguration.Builder builder = app.getCustomRoutingConfig(mFileName); RoutingConfiguration.Builder builder = app.getCustomRoutingConfig(mFileName);
@ -720,7 +724,7 @@ public class ImportHelper {
} }
}); });
} else { } else {
if (AndroidUtils.isActivityNotDestroyed(activity)) { if (progress != null && AndroidUtils.isActivityNotDestroyed(activity)) {
progress.dismiss(); progress.dismiss();
} }
app.showShortToastMessage(app.getString(R.string.file_import_error, mFileName, error)); app.showShortToastMessage(app.getString(R.string.file_import_error, mFileName, error));
@ -762,8 +766,10 @@ public class ImportHelper {
@Override @Override
protected void onPreExecute() { protected void onPreExecute() {
if (AndroidUtils.isActivityNotDestroyed(activity)) {
progress = ProgressDialog.show(activity, app.getString(R.string.loading_smth, ""), app.getString(R.string.loading_data)); progress = ProgressDialog.show(activity, app.getString(R.string.loading_smth, ""), app.getString(R.string.loading_data));
} }
}
@Override @Override
protected String doInBackground(Void... voids) { protected String doInBackground(Void... voids) {
@ -780,10 +786,10 @@ public class ImportHelper {
File tempDir = app.getAppPath(IndexConstants.TEMP_DIR); File tempDir = app.getAppPath(IndexConstants.TEMP_DIR);
final File file = new File(tempDir, name); final File file = new File(tempDir, name);
if (error == null && file.exists()) { if (error == null && file.exists()) {
app.getSettingsHelper().importSettings(file, latestChanges, version, new SettingsImportListener() { app.getSettingsHelper().collectSettings(file, latestChanges, version, new SettingsCollectListener() {
@Override @Override
public void onSettingsImportFinished(boolean succeed, boolean empty, @NonNull List<SettingsHelper.SettingsItem> items) { public void onSettingsCollectFinished(boolean succeed, boolean empty, @NonNull List<SettingsHelper.SettingsItem> items) {
if (AndroidUtils.isActivityNotDestroyed(activity)) { if (progress != null && AndroidUtils.isActivityNotDestroyed(activity)) {
progress.dismiss(); progress.dismiss();
} }
if (succeed) { if (succeed) {
@ -819,7 +825,7 @@ public class ImportHelper {
} }
}); });
} else { } else {
if (AndroidUtils.isActivityNotDestroyed(activity)) { if (progress != null && AndroidUtils.isActivityNotDestroyed(activity)) {
progress.dismiss(); progress.dismiss();
} }
app.showShortToastMessage(app.getString(R.string.file_import_error, name, error)); app.showShortToastMessage(app.getString(R.string.file_import_error, name, error));
@ -911,7 +917,9 @@ public class ImportHelper {
@Override @Override
protected void onPreExecute() { protected void onPreExecute() {
if (AndroidUtils.isActivityNotDestroyed(activity)) {
progress = ProgressDialog.show(activity, app.getString(R.string.loading_smth, ""), app.getString(R.string.loading_data)); progress = ProgressDialog.show(activity, app.getString(R.string.loading_smth, ""), app.getString(R.string.loading_data));
}
mFileName = fileName; mFileName = fileName;
} }
@ -938,7 +946,7 @@ public class ImportHelper {
} else { } else {
app.showShortToastMessage(app.getString(R.string.file_import_error, mFileName, error)); app.showShortToastMessage(app.getString(R.string.file_import_error, mFileName, error));
} }
if (AndroidUtils.isActivityNotDestroyed(activity)) { if (progress != null && AndroidUtils.isActivityNotDestroyed(activity)) {
progress.dismiss(); progress.dismiss();
} }
} }

View file

@ -2120,9 +2120,9 @@ public class MapContextMenuFragment extends BaseOsmAndFragment implements Downlo
public void dismissMenu() { public void dismissMenu() {
FragmentActivity activity = getActivity(); FragmentActivity activity = getActivity();
if (activity != null) { if (activity != null) {
try { FragmentManager fragmentManager = activity.getSupportFragmentManager();
activity.getSupportFragmentManager().popBackStack(TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE); if (!fragmentManager.isStateSaved()) {
} catch (Exception e) { fragmentManager.popBackStack(TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE);
} }
} }
} }

View file

@ -134,11 +134,9 @@ public class ContextMenuCardDialogFragment extends BaseOsmAndFragment {
public void dismiss() { public void dismiss() {
MapActivity activity = dialog.getMapActivity(); MapActivity activity = dialog.getMapActivity();
if (activity != null) { if (activity != null) {
try { FragmentManager fragmentManager = activity.getSupportFragmentManager();
activity.getSupportFragmentManager().popBackStack(TAG, if (!fragmentManager.isStateSaved()) {
FragmentManager.POP_BACK_STACK_INCLUSIVE); fragmentManager.popBackStack(TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE);
} catch (Exception e) {
e.printStackTrace();
} }
} }
} }

View file

@ -1,37 +0,0 @@
package net.osmand.plus.profiles;
import java.util.List;
public class AdditionalDataWrapper {
private Type type;
private List<?> items;
public AdditionalDataWrapper(Type type, List<?> items) {
this.type = type;
this.items = items;
}
public Type getType() {
return type;
}
public void setType(Type type) {
this.type = type;
}
public List<?> getItems() {
return items;
}
public enum Type {
PROFILE,
QUICK_ACTIONS,
POI_TYPES,
MAP_SOURCES,
CUSTOM_RENDER_STYLE,
CUSTOM_ROUTING,
AVOID_ROADS
}
}

View file

@ -1023,7 +1023,10 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC
hideToolbar(); hideToolbar();
mapActivity.updateStatusBarColor(); mapActivity.updateStatusBarColor();
mapActivity.refreshMap(); mapActivity.refreshMap();
getChildFragmentManager().popBackStack(); FragmentManager fragmentManager = getChildFragmentManager();
if (!fragmentManager.isStateSaved()) {
fragmentManager.popBackStack();
}
} }
super.onDismiss(dialog); super.onDismiss(dialog);
} }

View file

@ -585,7 +585,10 @@ public abstract class BaseSettingsFragment extends PreferenceFragmentCompat impl
public void dismiss() { public void dismiss() {
FragmentActivity activity = getActivity(); FragmentActivity activity = getActivity();
if (activity != null) { if (activity != null) {
activity.getSupportFragmentManager().popBackStack(); FragmentManager fragmentManager = activity.getSupportFragmentManager();
if (!fragmentManager.isStateSaved()) {
fragmentManager.popBackStack();
}
} }
} }

View file

@ -36,6 +36,7 @@ import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin; import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.SettingsHelper; import net.osmand.plus.SettingsHelper;
import net.osmand.plus.SettingsHelper.SettingsCollectListener;
import net.osmand.plus.UiUtilities; import net.osmand.plus.UiUtilities;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.helpers.AndroidUiHelper;
@ -182,9 +183,9 @@ public class ConfigureProfileFragment extends BaseSettingsFragment implements Co
} }
private void restoreCustomModeFromFile(final File file) { private void restoreCustomModeFromFile(final File file) {
app.getSettingsHelper().importSettings(file, "", 1, new SettingsHelper.SettingsImportListener() { app.getSettingsHelper().collectSettings(file, "", 1, new SettingsCollectListener() {
@Override @Override
public void onSettingsImportFinished(boolean succeed, boolean empty, @NonNull List<SettingsHelper.SettingsItem> items) { public void onSettingsCollectFinished(boolean succeed, boolean empty, @NonNull List<SettingsHelper.SettingsItem> items) {
if (succeed) { if (succeed) {
for (SettingsHelper.SettingsItem item : items) { for (SettingsHelper.SettingsItem item : items) {
item.setShouldReplace(true); item.setShouldReplace(true);
@ -198,7 +199,7 @@ public class ConfigureProfileFragment extends BaseSettingsFragment implements Co
private void importBackupSettingsItems(File file, List<SettingsHelper.SettingsItem> items) { private void importBackupSettingsItems(File file, List<SettingsHelper.SettingsItem> items) {
app.getSettingsHelper().importSettings(file, items, "", 1, new SettingsHelper.SettingsImportListener() { app.getSettingsHelper().importSettings(file, items, "", 1, new SettingsHelper.SettingsImportListener() {
@Override @Override
public void onSettingsImportFinished(boolean succeed, boolean empty, @NonNull List<SettingsHelper.SettingsItem> items) { public void onSettingsImportFinished(boolean succeed, @NonNull List<SettingsHelper.SettingsItem> items) {
app.showToastMessage(R.string.profile_prefs_reset_successful); app.showToastMessage(R.string.profile_prefs_reset_successful);
updateCopiedOrResetPrefs(); updateCopiedOrResetPrefs();
} }

View file

@ -10,6 +10,7 @@ import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import net.osmand.AndroidUtils; import net.osmand.AndroidUtils;
import net.osmand.IndexConstants;
import net.osmand.map.ITileSource; import net.osmand.map.ITileSource;
import net.osmand.plus.ApplicationMode; import net.osmand.plus.ApplicationMode;
import net.osmand.plus.ApplicationMode.ApplicationModeBean; import net.osmand.plus.ApplicationMode.ApplicationModeBean;
@ -111,12 +112,12 @@ public class DuplicatesSettingsAdapter extends RecyclerView.Adapter<RecyclerView
} else if (currentItem instanceof File) { } else if (currentItem instanceof File) {
File file = (File) currentItem; File file = (File) currentItem;
itemHolder.title.setText(file.getName()); itemHolder.title.setText(file.getName());
if (file.getName().contains("/rendering/")) { if (file.getName().contains(IndexConstants.RENDERERS_DIR)) {
itemHolder.icon.setImageDrawable(uiUtilities.getIcon(R.drawable.ic_action_map_style, nightMode)); itemHolder.icon.setImageDrawable(uiUtilities.getIcon(R.drawable.ic_action_map_style, nightMode));
itemHolder.icon.setVisibility(View.VISIBLE); itemHolder.icon.setVisibility(View.VISIBLE);
} else { } else if (file.getName().contains(IndexConstants.ROUTING_PROFILES_DIR)) {
itemHolder.icon.setImageResource(R.drawable.ic_action_info_dark); itemHolder.icon.setImageDrawable(uiUtilities.getIcon(R.drawable.ic_action_route_distance, nightMode));
itemHolder.icon.setVisibility(View.INVISIBLE); itemHolder.icon.setVisibility(View.VISIBLE);
} }
itemHolder.subTitle.setVisibility(View.GONE); itemHolder.subTitle.setVisibility(View.GONE);
} else if (currentItem instanceof AvoidRoadInfo) { } else if (currentItem instanceof AvoidRoadInfo) {

View file

@ -13,6 +13,7 @@ import androidx.core.content.ContextCompat;
import androidx.core.widget.CompoundButtonCompat; import androidx.core.widget.CompoundButtonCompat;
import net.osmand.AndroidUtils; import net.osmand.AndroidUtils;
import net.osmand.IndexConstants;
import net.osmand.map.ITileSource; import net.osmand.map.ITileSource;
import net.osmand.plus.ApplicationMode; import net.osmand.plus.ApplicationMode;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
@ -21,7 +22,6 @@ import net.osmand.plus.UiUtilities;
import net.osmand.plus.activities.OsmandBaseExpandableListAdapter; import net.osmand.plus.activities.OsmandBaseExpandableListAdapter;
import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo; import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo;
import net.osmand.plus.poi.PoiUIFilter; import net.osmand.plus.poi.PoiUIFilter;
import net.osmand.plus.profiles.AdditionalDataWrapper;
import net.osmand.plus.profiles.ProfileIconColors; import net.osmand.plus.profiles.ProfileIconColors;
import net.osmand.plus.quickaction.QuickAction; import net.osmand.plus.quickaction.QuickAction;
import net.osmand.plus.render.RenderingIcons; import net.osmand.plus.render.RenderingIcons;
@ -30,7 +30,10 @@ import net.osmand.view.ThreeStateCheckbox;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import static net.osmand.view.ThreeStateCheckbox.State.CHECKED; import static net.osmand.view.ThreeStateCheckbox.State.CHECKED;
import static net.osmand.view.ThreeStateCheckbox.State.MISC; import static net.osmand.view.ThreeStateCheckbox.State.MISC;
@ -40,24 +43,18 @@ class ExportImportSettingsAdapter extends OsmandBaseExpandableListAdapter {
private OsmandApplication app; private OsmandApplication app;
private List<? super Object> dataToOperate; private List<? super Object> dataToOperate;
private List<AdditionalDataWrapper> dataList; private Map<Type, List<?>> itemsMap;
private List<Type> itemsTypes;
private boolean nightMode; private boolean nightMode;
private boolean importState; private boolean importState;
private int profileColor; private int profileColor;
ExportImportSettingsAdapter(OsmandApplication app, List<AdditionalDataWrapper> dataList, boolean nightMode, boolean importState) { ExportImportSettingsAdapter(OsmandApplication app, boolean nightMode, boolean importState) {
this.app = app; this.app = app;
this.dataList = dataList;
this.nightMode = nightMode; this.nightMode = nightMode;
this.importState = importState; this.importState = importState;
this.dataToOperate = new ArrayList<>(); this.itemsMap = new HashMap<>();
this.profileColor = app.getSettings().getApplicationMode().getIconColorInfo().getColor(nightMode); this.itemsTypes = new ArrayList<>();
}
ExportImportSettingsAdapter(OsmandApplication app, boolean nightMode) {
this.app = app;
this.nightMode = nightMode;
this.dataList = new ArrayList<>();
this.dataToOperate = new ArrayList<>(); this.dataToOperate = new ArrayList<>();
this.profileColor = app.getSettings().getApplicationMode().getIconColorInfo().getColor(nightMode); this.profileColor = app.getSettings().getApplicationMode().getIconColorInfo().getColor(nightMode);
} }
@ -71,7 +68,7 @@ class ExportImportSettingsAdapter extends OsmandBaseExpandableListAdapter {
} }
boolean isLastGroup = groupPosition == getGroupCount() - 1; boolean isLastGroup = groupPosition == getGroupCount() - 1;
final AdditionalDataWrapper.Type type = dataList.get(groupPosition).getType(); final Type type = itemsTypes.get(groupPosition);
TextView titleTv = group.findViewById(R.id.title_tv); TextView titleTv = group.findViewById(R.id.title_tv);
TextView subTextTv = group.findViewById(R.id.sub_text_tv); TextView subTextTv = group.findViewById(R.id.sub_text_tv);
@ -88,7 +85,7 @@ class ExportImportSettingsAdapter extends OsmandBaseExpandableListAdapter {
cardBottomDivider.setVisibility(importState && !isExpanded ? View.VISIBLE : View.GONE); cardBottomDivider.setVisibility(importState && !isExpanded ? View.VISIBLE : View.GONE);
CompoundButtonCompat.setButtonTintList(checkBox, ColorStateList.valueOf(ContextCompat.getColor(app, profileColor))); CompoundButtonCompat.setButtonTintList(checkBox, ColorStateList.valueOf(ContextCompat.getColor(app, profileColor)));
final List<?> listItems = dataList.get(groupPosition).getItems(); final List<?> listItems = itemsMap.get(type);
subTextTv.setText(String.valueOf(listItems.size())); subTextTv.setText(String.valueOf(listItems.size()));
if (dataToOperate.containsAll(listItems)) { if (dataToOperate.containsAll(listItems)) {
@ -119,7 +116,7 @@ class ExportImportSettingsAdapter extends OsmandBaseExpandableListAdapter {
notifyDataSetChanged(); notifyDataSetChanged();
} }
}); });
adjustIndicator(app, groupPosition, isExpanded, group, true); adjustIndicator(app, groupPosition, isExpanded, group, nightMode);
return group; return group;
} }
@ -130,10 +127,10 @@ class ExportImportSettingsAdapter extends OsmandBaseExpandableListAdapter {
LayoutInflater inflater = UiUtilities.getInflater(app, nightMode); LayoutInflater inflater = UiUtilities.getInflater(app, nightMode);
child = inflater.inflate(R.layout.profile_data_list_item_child, parent, false); child = inflater.inflate(R.layout.profile_data_list_item_child, parent, false);
} }
final Object currentItem = dataList.get(groupPosition).getItems().get(childPosition); final Object currentItem = itemsMap.get(itemsTypes.get(groupPosition)).get(childPosition);
boolean isLastGroup = groupPosition == getGroupCount() - 1; boolean isLastGroup = groupPosition == getGroupCount() - 1;
final AdditionalDataWrapper.Type type = dataList.get(groupPosition).getType(); final Type type = itemsTypes.get(groupPosition);
TextView title = child.findViewById(R.id.title_tv); TextView title = child.findViewById(R.id.title_tv);
TextView subText = child.findViewById(R.id.sub_title_tv); TextView subText = child.findViewById(R.id.sub_title_tv);
@ -204,17 +201,17 @@ class ExportImportSettingsAdapter extends OsmandBaseExpandableListAdapter {
break; break;
case CUSTOM_RENDER_STYLE: case CUSTOM_RENDER_STYLE:
String renderName = ((File) currentItem).getName(); String renderName = ((File) currentItem).getName();
renderName = renderName.replace('_', ' ').replaceAll(".render.xml", ""); renderName = renderName.replace('_', ' ').replaceAll(IndexConstants.RENDERER_INDEX_EXT, "");
title.setText(renderName); title.setText(renderName);
icon.setImageResource(R.drawable.ic_action_info_dark); icon.setImageDrawable(app.getUIUtilities().getIcon(R.drawable.ic_action_map_style, nightMode));
icon.setVisibility(View.INVISIBLE); icon.setVisibility(View.VISIBLE);
subText.setVisibility(View.GONE); subText.setVisibility(View.GONE);
break; break;
case CUSTOM_ROUTING: case CUSTOM_ROUTING:
String routingName = ((File) currentItem).getName(); String routingName = ((File) currentItem).getName();
routingName = routingName.replace('_', ' ').replaceAll(".xml", ""); routingName = routingName.replace('_', ' ').replaceAll(".xml", "");
title.setText(routingName); title.setText(routingName);
icon.setImageResource(R.drawable.ic_action_map_style); icon.setImageDrawable(app.getUIUtilities().getIcon(R.drawable.ic_action_route_distance, nightMode));
icon.setVisibility(View.VISIBLE); icon.setVisibility(View.VISIBLE);
subText.setVisibility(View.GONE); subText.setVisibility(View.GONE);
break; break;
@ -233,22 +230,22 @@ class ExportImportSettingsAdapter extends OsmandBaseExpandableListAdapter {
@Override @Override
public int getGroupCount() { public int getGroupCount() {
return dataList.size(); return itemsTypes.size();
} }
@Override @Override
public int getChildrenCount(int i) { public int getChildrenCount(int i) {
return dataList.get(i).getItems().size(); return itemsMap.get(itemsTypes.get(i)).size();
} }
@Override @Override
public Object getGroup(int i) { public Object getGroup(int i) {
return dataList.get(i); return itemsMap.get(itemsTypes.get(i));
} }
@Override @Override
public Object getChild(int groupPosition, int childPosition) { public Object getChild(int groupPosition, int childPosition) {
return dataList.get(groupPosition).getItems().get(childPosition); return itemsMap.get(itemsTypes.get(groupPosition)).get(childPosition);
} }
@Override @Override
@ -271,7 +268,7 @@ class ExportImportSettingsAdapter extends OsmandBaseExpandableListAdapter {
return true; return true;
} }
private int getGroupTitle(AdditionalDataWrapper.Type type) { private int getGroupTitle(Type type) {
switch (type) { switch (type) {
case PROFILE: case PROFILE:
return R.string.shared_string_profiles; return R.string.shared_string_profiles;
@ -292,21 +289,24 @@ class ExportImportSettingsAdapter extends OsmandBaseExpandableListAdapter {
} }
} }
public void updateSettingsList(List<AdditionalDataWrapper> settingsList) { public void updateSettingsList(Map<Type, List<?>> itemsMap) {
this.dataList = settingsList; this.itemsMap = itemsMap;
this.itemsTypes = new ArrayList<>(itemsMap.keySet());
Collections.sort(itemsTypes);
notifyDataSetChanged(); notifyDataSetChanged();
} }
public void clearSettingsList() { public void clearSettingsList() {
this.dataList.clear(); this.itemsMap.clear();
this.itemsTypes.clear();
notifyDataSetChanged(); notifyDataSetChanged();
} }
public void selectAll(boolean selectAll) { public void selectAll(boolean selectAll) {
dataToOperate.clear(); dataToOperate.clear();
if (selectAll) { if (selectAll) {
for (AdditionalDataWrapper item : dataList) { for (List<?> values : itemsMap.values()) {
dataToOperate.addAll(item.getItems()); dataToOperate.addAll(values);
} }
} }
notifyDataSetChanged(); notifyDataSetChanged();
@ -315,4 +315,14 @@ class ExportImportSettingsAdapter extends OsmandBaseExpandableListAdapter {
List<? super Object> getDataToOperate() { List<? super Object> getDataToOperate() {
return this.dataToOperate; return this.dataToOperate;
} }
public enum Type {
PROFILE,
QUICK_ACTIONS,
POI_TYPES,
MAP_SOURCES,
CUSTOM_RENDER_STYLE,
CUSTOM_ROUTING,
AVOID_ROADS
}
} }

View file

@ -38,16 +38,17 @@ import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem;
import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem; import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem;
import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo; import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo;
import net.osmand.plus.poi.PoiUIFilter; import net.osmand.plus.poi.PoiUIFilter;
import net.osmand.plus.profiles.AdditionalDataWrapper;
import net.osmand.plus.quickaction.QuickAction; import net.osmand.plus.quickaction.QuickAction;
import net.osmand.plus.quickaction.QuickActionFactory; import net.osmand.plus.quickaction.QuickActionFactory;
import net.osmand.plus.settings.bottomsheets.BasePreferenceBottomSheet; import net.osmand.plus.settings.bottomsheets.BasePreferenceBottomSheet;
import net.osmand.plus.settings.ExportImportSettingsAdapter.Type;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -63,7 +64,7 @@ public class ExportProfileBottomSheet extends BasePreferenceBottomSheet {
private OsmandApplication app; private OsmandApplication app;
private ApplicationMode profile; private ApplicationMode profile;
private List<AdditionalDataWrapper> dataList = new ArrayList<>(); private Map<Type, List<?>> dataList = new HashMap<>();
private ExportImportSettingsAdapter adapter; private ExportImportSettingsAdapter adapter;
private SettingsHelper.SettingsExportListener exportListener; private SettingsHelper.SettingsExportListener exportListener;
@ -122,7 +123,7 @@ public class ExportProfileBottomSheet extends BasePreferenceBottomSheet {
if (!dataList.isEmpty()) { if (!dataList.isEmpty()) {
final View additionalDataView = inflater.inflate(R.layout.bottom_sheet_item_additional_data, null); final View additionalDataView = inflater.inflate(R.layout.bottom_sheet_item_additional_data, null);
ExpandableListView listView = additionalDataView.findViewById(R.id.list); ExpandableListView listView = additionalDataView.findViewById(R.id.list);
adapter = new ExportImportSettingsAdapter(app, nightMode); adapter = new ExportImportSettingsAdapter(app, nightMode, false);
View listHeader = inflater.inflate(R.layout.item_header_export_expand_list, null); View listHeader = inflater.inflate(R.layout.item_header_export_expand_list, null);
final View topSwitchDivider = listHeader.findViewById(R.id.topSwitchDivider); final View topSwitchDivider = listHeader.findViewById(R.id.topSwitchDivider);
final View bottomSwitchDivider = listHeader.findViewById(R.id.bottomSwitchDivider); final View bottomSwitchDivider = listHeader.findViewById(R.id.bottomSwitchDivider);
@ -214,22 +215,18 @@ public class ExportProfileBottomSheet extends BasePreferenceBottomSheet {
} }
} }
private List<AdditionalDataWrapper> getAdditionalData() { private Map<Type, List<?>> getAdditionalData() {
List<AdditionalDataWrapper> dataList = new ArrayList<>(); Map<Type, List<?>> dataList = new HashMap<>();
QuickActionFactory factory = new QuickActionFactory(); QuickActionFactory factory = new QuickActionFactory();
List<QuickAction> actionsList = factory.parseActiveActionsList(app.getSettings().QUICK_ACTION_LIST.get()); List<QuickAction> actionsList = factory.parseActiveActionsList(app.getSettings().QUICK_ACTION_LIST.get());
if (!actionsList.isEmpty()) { if (!actionsList.isEmpty()) {
dataList.add(new AdditionalDataWrapper( dataList.put(Type.QUICK_ACTIONS, actionsList);
AdditionalDataWrapper.Type.QUICK_ACTIONS, actionsList));
} }
List<PoiUIFilter> poiList = app.getPoiFilters().getUserDefinedPoiFilters(false); List<PoiUIFilter> poiList = app.getPoiFilters().getUserDefinedPoiFilters(false);
if (!poiList.isEmpty()) { if (!poiList.isEmpty()) {
dataList.add(new AdditionalDataWrapper( dataList.put(Type.POI_TYPES, poiList);
AdditionalDataWrapper.Type.POI_TYPES,
poiList
));
} }
List<ITileSource> iTileSources = new ArrayList<>(); List<ITileSource> iTileSources = new ArrayList<>();
@ -249,37 +246,25 @@ public class ExportProfileBottomSheet extends BasePreferenceBottomSheet {
} }
} }
if (!iTileSources.isEmpty()) { if (!iTileSources.isEmpty()) {
dataList.add(new AdditionalDataWrapper( dataList.put(Type.MAP_SOURCES, iTileSources);
AdditionalDataWrapper.Type.MAP_SOURCES,
iTileSources
));
} }
Map<String, File> externalRenderers = app.getRendererRegistry().getExternalRenderers(); Map<String, File> externalRenderers = app.getRendererRegistry().getExternalRenderers();
if (!externalRenderers.isEmpty()) { if (!externalRenderers.isEmpty()) {
dataList.add(new AdditionalDataWrapper( dataList.put(Type.CUSTOM_RENDER_STYLE, new ArrayList<>(externalRenderers.values()));
AdditionalDataWrapper.Type.CUSTOM_RENDER_STYLE,
new ArrayList<>(externalRenderers.values())
));
} }
File routingProfilesFolder = app.getAppPath(IndexConstants.ROUTING_PROFILES_DIR); File routingProfilesFolder = app.getAppPath(IndexConstants.ROUTING_PROFILES_DIR);
if (routingProfilesFolder.exists() && routingProfilesFolder.isDirectory()) { if (routingProfilesFolder.exists() && routingProfilesFolder.isDirectory()) {
File[] fl = routingProfilesFolder.listFiles(); File[] fl = routingProfilesFolder.listFiles();
if (fl != null && fl.length > 0) { if (fl != null && fl.length > 0) {
dataList.add(new AdditionalDataWrapper( dataList.put(Type.CUSTOM_ROUTING, Arrays.asList(fl));
AdditionalDataWrapper.Type.CUSTOM_ROUTING,
Arrays.asList(fl)
));
} }
} }
Map<LatLon, AvoidRoadInfo> impassableRoads = app.getAvoidSpecificRoads().getImpassableRoads(); Map<LatLon, AvoidRoadInfo> impassableRoads = app.getAvoidSpecificRoads().getImpassableRoads();
if (!impassableRoads.isEmpty()) { if (!impassableRoads.isEmpty()) {
dataList.add(new AdditionalDataWrapper( dataList.put(Type.AVOID_ROADS, new ArrayList<>(impassableRoads.values()));
AdditionalDataWrapper.Type.AVOID_ROADS,
new ArrayList<>(impassableRoads.values())
));
} }
return dataList; return dataList;
} }

View file

@ -0,0 +1,184 @@
package net.osmand.plus.settings;
import android.app.Activity;
import android.graphics.Typeface;
import android.os.Build;
import android.os.Bundle;
import android.text.style.StyleSpan;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.FragmentManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import net.osmand.AndroidUtils;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.SettingsHelper.SettingsItem;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.base.BaseOsmAndFragment;
import net.osmand.plus.dashboard.DashboardOnMap;
import net.osmand.plus.dialogs.SelectMapStyleBottomSheetDialogFragment;
import net.osmand.plus.quickaction.QuickActionListFragment;
import net.osmand.plus.routepreparationmenu.AvoidRoadsBottomSheetDialogFragment;
import net.osmand.plus.search.QuickSearchDialogFragment;
import net.osmand.plus.settings.ExportImportSettingsAdapter.Type;
import java.util.List;
import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_SETTINGS_ID;
import static net.osmand.plus.settings.ImportSettingsFragment.IMPORT_SETTINGS_TAG;
import static net.osmand.plus.settings.ImportSettingsFragment.getSettingsToOperate;
public class ImportCompleteFragment extends BaseOsmAndFragment {
public static final String TAG = ImportCompleteFragment.class.getSimpleName();
private OsmandApplication app;
private RecyclerView recyclerView;
private List<SettingsItem> settingsItems;
private String fileName;
private boolean nightMode;
public static void showInstance(FragmentManager fm, @NonNull List<SettingsItem> settingsItems,
@NonNull String fileName) {
ImportCompleteFragment fragment = new ImportCompleteFragment();
fragment.setSettingsItems(settingsItems);
fragment.setFileName(fileName);
fragment.setRetainInstance(true);
fm.beginTransaction()
.replace(R.id.fragmentContainer, fragment, TAG)
.addToBackStack(IMPORT_SETTINGS_TAG)
.commitAllowingStateLoss();
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
app = requireMyApplication();
nightMode = !app.getSettings().isLightContent();
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
inflater = UiUtilities.getInflater(app, nightMode);
View root = inflater.inflate(R.layout.fragment_import_complete, container, false);
TextView description = root.findViewById(R.id.description);
TextView btnClose = root.findViewById(R.id.button_close);
recyclerView = root.findViewById(R.id.list);
description.setText(UiUtilities.createSpannableString(
String.format(getString(R.string.import_complete_description), fileName),
fileName,
new StyleSpan(Typeface.BOLD)
));
btnClose.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
dismissFragment();
}
});
if (Build.VERSION.SDK_INT >= 21) {
AndroidUtils.addStatusBarPadding21v(app, root);
}
return root;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
if (settingsItems != null) {
ImportedSettingsItemsAdapter adapter = new ImportedSettingsItemsAdapter(
app,
getSettingsToOperate(settingsItems),
nightMode,
new ImportedSettingsItemsAdapter.OnItemClickListener() {
@Override
public void onItemClick(Type type) {
navigateTo(type);
}
});
recyclerView.setLayoutManager(new LinearLayoutManager(getMyApplication()));
recyclerView.setAdapter(adapter);
}
}
public void dismissFragment() {
FragmentManager fm = getFragmentManager();
if (fm != null && !fm.isStateSaved()) {
fm.popBackStack(IMPORT_SETTINGS_TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
}
private void navigateTo(Type type) {
FragmentManager fm = getFragmentManager();
Activity activity = requireActivity();
if (fm == null || fm.isStateSaved()) {
return;
}
dismissFragment();
fm.popBackStack(DRAWER_SETTINGS_ID + ".new", FragmentManager.POP_BACK_STACK_INCLUSIVE);
switch (type) {
case CUSTOM_ROUTING:
case PROFILE:
BaseSettingsFragment.showInstance(
requireActivity(),
BaseSettingsFragment.SettingsScreenType.MAIN_SETTINGS
);
break;
case QUICK_ACTIONS:
fm.beginTransaction()
.add(R.id.fragmentContainer, new QuickActionListFragment(), QuickActionListFragment.TAG)
.addToBackStack(QuickActionListFragment.TAG).commit();
break;
case POI_TYPES:
if (activity instanceof MapActivity) {
QuickSearchDialogFragment.showInstance(
(MapActivity) activity,
"",
null,
QuickSearchDialogFragment.QuickSearchType.REGULAR,
QuickSearchDialogFragment.QuickSearchTab.CATEGORIES,
null
);
}
break;
case MAP_SOURCES:
if (activity instanceof MapActivity) {
((MapActivity) activity).getDashboard()
.setDashboardVisibility(
true,
DashboardOnMap.DashboardType.CONFIGURE_MAP,
null
);
}
break;
case CUSTOM_RENDER_STYLE:
new SelectMapStyleBottomSheetDialogFragment().show(fm, SelectMapStyleBottomSheetDialogFragment.TAG);
break;
case AVOID_ROADS:
new AvoidRoadsBottomSheetDialogFragment().show(fm, AvoidRoadsBottomSheetDialogFragment.TAG);
break;
default:
break;
}
}
@Override
public int getStatusBarColorId() {
return nightMode ? R.color.status_bar_color_dark : R.color.status_bar_color_light;
}
public void setSettingsItems(List<SettingsItem> settingsItems) {
this.settingsItems = settingsItems;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
}

View file

@ -1,23 +1,27 @@
package net.osmand.plus.settings; package net.osmand.plus.settings;
import android.graphics.drawable.Drawable; import android.graphics.Typeface;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.text.style.StyleSpan;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.ViewTreeObserver; import android.view.ViewTreeObserver;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import androidx.core.widget.NestedScrollView; import androidx.core.widget.NestedScrollView;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.appbar.CollapsingToolbarLayout;
import net.osmand.AndroidUtils; import net.osmand.AndroidUtils;
import net.osmand.map.ITileSource; import net.osmand.map.ITileSource;
import net.osmand.plus.AppInitializer; import net.osmand.plus.AppInitializer;
@ -25,6 +29,8 @@ import net.osmand.plus.ApplicationMode;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.SettingsHelper; import net.osmand.plus.SettingsHelper;
import net.osmand.plus.SettingsHelper.ImportAsyncTask;
import net.osmand.plus.SettingsHelper.ImportType;
import net.osmand.plus.SettingsHelper.SettingsItem; import net.osmand.plus.SettingsHelper.SettingsItem;
import net.osmand.plus.UiUtilities; import net.osmand.plus.UiUtilities;
import net.osmand.plus.base.BaseOsmAndFragment; import net.osmand.plus.base.BaseOsmAndFragment;
@ -37,7 +43,7 @@ import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import static net.osmand.plus.settings.ImportSettingsFragment.getDuplicatesData; import static net.osmand.plus.settings.ImportSettingsFragment.IMPORT_SETTINGS_TAG;
public class ImportDuplicatesFragment extends BaseOsmAndFragment implements View.OnClickListener { public class ImportDuplicatesFragment extends BaseOsmAndFragment implements View.OnClickListener {
@ -51,6 +57,10 @@ public class ImportDuplicatesFragment extends BaseOsmAndFragment implements View
private List<SettingsItem> settingsItems; private List<SettingsItem> settingsItems;
private File file; private File file;
private boolean nightMode; private boolean nightMode;
private ProgressBar progressBar;
private CollapsingToolbarLayout toolbarLayout;
private TextView description;
private SettingsHelper settingsHelper;
public static void showInstance(@NonNull FragmentManager fm, List<? super Object> duplicatesList, public static void showInstance(@NonNull FragmentManager fm, List<? super Object> duplicatesList,
List<SettingsItem> settingsItems, File file) { List<SettingsItem> settingsItems, File file) {
@ -58,20 +68,30 @@ public class ImportDuplicatesFragment extends BaseOsmAndFragment implements View
fragment.setDuplicatesList(duplicatesList); fragment.setDuplicatesList(duplicatesList);
fragment.setSettingsItems(settingsItems); fragment.setSettingsItems(settingsItems);
fragment.setFile(file); fragment.setFile(file);
fm.beginTransaction().replace(R.id.fragmentContainer, fragment, TAG).addToBackStack(null).commit(); fm.beginTransaction()
.replace(R.id.fragmentContainer, fragment, TAG)
.addToBackStack(IMPORT_SETTINGS_TAG)
.commitAllowingStateLoss();
} }
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
app = requireMyApplication(); app = requireMyApplication();
settingsHelper = app.getSettingsHelper();
nightMode = !app.getSettings().isLightContent(); nightMode = !app.getSettings().isLightContent();
ImportAsyncTask importTask = settingsHelper.getImportTask();
if (importTask != null) {
if (settingsItems == null) { if (settingsItems == null) {
settingsItems = app.getSettingsHelper().getSettingsItems(); settingsItems = importTask.getSelectedItems();
duplicatesList = getDuplicatesData(settingsItems); }
if (duplicatesList == null) {
duplicatesList = importTask.getDuplicates();
} }
if (file == null) { if (file == null) {
file = app.getSettingsHelper().getSettingsFile(); file = importTask.getFile();
}
importTask.setImportListener(getImportListener());
} }
} }
@ -80,11 +100,15 @@ public class ImportDuplicatesFragment extends BaseOsmAndFragment implements View
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
inflater = UiUtilities.getInflater(app, nightMode); inflater = UiUtilities.getInflater(app, nightMode);
View root = inflater.inflate(R.layout.fragment_import_duplicates, container, false); View root = inflater.inflate(R.layout.fragment_import_duplicates, container, false);
setupToolbar((Toolbar) root.findViewById(R.id.toolbar)); Toolbar toolbar = root.findViewById(R.id.toolbar);
setupToolbar(toolbar);
ComplexButton replaceAllBtn = root.findViewById(R.id.replace_all_btn); ComplexButton replaceAllBtn = root.findViewById(R.id.replace_all_btn);
ComplexButton keepBothBtn = root.findViewById(R.id.keep_both_btn); ComplexButton keepBothBtn = root.findViewById(R.id.keep_both_btn);
buttonsContainer = root.findViewById(R.id.buttons_container); buttonsContainer = root.findViewById(R.id.buttons_container);
nestedScroll = root.findViewById(R.id.nested_scroll); nestedScroll = root.findViewById(R.id.nested_scroll);
description = root.findViewById(R.id.description);
progressBar = root.findViewById(R.id.progress_bar);
toolbarLayout = root.findViewById(R.id.toolbar_layout);
keepBothBtn.setIcon(getPaintedContentIcon(R.drawable.ic_action_keep_both, keepBothBtn.setIcon(getPaintedContentIcon(R.drawable.ic_action_keep_both,
nightMode nightMode
? getResources().getColor(R.color.icon_color_active_dark) ? getResources().getColor(R.color.icon_color_active_dark)
@ -121,16 +145,23 @@ public class ImportDuplicatesFragment extends BaseOsmAndFragment implements View
return root; return root;
} }
@Override @Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState); super.onActivityCreated(savedInstanceState);
DuplicatesSettingsAdapter adapter = new DuplicatesSettingsAdapter(app, prepareDuplicates(), nightMode); if (duplicatesList != null) {
DuplicatesSettingsAdapter adapter = new DuplicatesSettingsAdapter(app, prepareDuplicates(duplicatesList), nightMode);
list.setLayoutManager(new LinearLayoutManager(getMyApplication())); list.setLayoutManager(new LinearLayoutManager(getMyApplication()));
list.setAdapter(adapter); list.setAdapter(adapter);
} }
if (settingsHelper.getImportTaskType() == ImportType.IMPORT) {
setupImportingUi();
} else {
toolbarLayout.setTitle(getString(R.string.import_duplicates_title));
}
toolbarLayout.setTitle(getString(R.string.import_duplicates_title));
}
private List<Object> prepareDuplicates() { private List<Object> prepareDuplicates(List<? super Object> duplicatesList) {
List<? super Object> duplicates = new ArrayList<>(); List<? super Object> duplicates = new ArrayList<>();
List<ApplicationMode.ApplicationModeBean> profiles = new ArrayList<>(); List<ApplicationMode.ApplicationModeBean> profiles = new ArrayList<>();
List<QuickAction> actions = new ArrayList<>(); List<QuickAction> actions = new ArrayList<>();
@ -211,50 +242,60 @@ public class ImportDuplicatesFragment extends BaseOsmAndFragment implements View
} }
private void importItems(boolean shouldReplace) { private void importItems(boolean shouldReplace) {
if (settingsItems != null && file != null) {
setupImportingUi();
for (SettingsItem item : settingsItems) { for (SettingsItem item : settingsItems) {
item.setShouldReplace(shouldReplace); item.setShouldReplace(shouldReplace);
} }
app.getSettingsHelper().importSettings(file, settingsItems, "", 1, new SettingsHelper.SettingsImportListener() { settingsHelper.importSettings(file, settingsItems, "", 1, getImportListener());
}
}
private void setupImportingUi() {
toolbarLayout.setTitle(getString(R.string.shared_string_importing));
description.setText(UiUtilities.createSpannableString(
String.format(getString(R.string.importing_from), file.getName()),
file.getName(),
new StyleSpan(Typeface.BOLD)
));
progressBar.setVisibility(View.VISIBLE);
list.setVisibility(View.GONE);
buttonsContainer.setVisibility(View.GONE);
}
private SettingsHelper.SettingsImportListener getImportListener() {
return new SettingsHelper.SettingsImportListener() {
@Override @Override
public void onSettingsImportFinished(boolean succeed, boolean empty, @NonNull List<SettingsHelper.SettingsItem> items) { public void onSettingsImportFinished(boolean succeed, @NonNull List<SettingsItem> items) {
if (succeed) { if (succeed) {
app.showShortToastMessage(app.getString(R.string.file_imported_successfully, file.getName()));
app.getRendererRegistry().updateExternalRenderers(); app.getRendererRegistry().updateExternalRenderers();
AppInitializer.loadRoutingFiles(app, new AppInitializer.LoadRoutingFilesCallback() { AppInitializer.loadRoutingFiles(app, new AppInitializer.LoadRoutingFilesCallback() {
@Override @Override
public void onRoutingFilesLoaded() { public void onRoutingFilesLoaded() {
} }
}); });
} else if (empty) {
app.showShortToastMessage(app.getString(R.string.file_import_error, file.getName(), app.getString(R.string.shared_string_unexpected_error)));
}
}
});
FragmentManager fm = getFragmentManager(); FragmentManager fm = getFragmentManager();
if (fm != null) { if (fm != null && file != null) {
fm.popBackStackImmediate(); ImportCompleteFragment.showInstance(fm, items, file.getName());
Fragment fragment = fm.findFragmentByTag(ImportSettingsFragment.TAG);
if (fragment != null) {
fm.beginTransaction().remove(fragment).commit();
fm.popBackStackImmediate();
} }
} }
} }
};
}
private void setupToolbar(Toolbar toolbar) { private void setupToolbar(Toolbar toolbar) {
Drawable icBack = getPaintedContentIcon(AndroidUtils.getNavigationIconResId(getContext()), toolbar.setTitle(R.string.import_duplicates_title);
toolbar.setNavigationIcon(getPaintedContentIcon(R.drawable.ic_arrow_back,
nightMode nightMode
? getResources().getColor(R.color.active_buttons_and_links_text_dark) ? getResources().getColor(R.color.active_buttons_and_links_text_dark)
: getResources().getColor(R.color.active_buttons_and_links_text_light)); : getResources().getColor(R.color.active_buttons_and_links_text_light)));
toolbar.setNavigationIcon(icBack);
toolbar.setNavigationContentDescription(R.string.access_shared_string_navigate_up); toolbar.setNavigationContentDescription(R.string.access_shared_string_navigate_up);
toolbar.setNavigationOnClickListener(new View.OnClickListener() { toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
FragmentManager fm = getFragmentManager(); FragmentManager fm = getFragmentManager();
if (fm != null) { if (fm != null && !fm.isStateSaved()) {
fm.popBackStackImmediate(); fm.popBackStackImmediate();
ImportSettingsFragment.showInstance(fm, null, file);
} }
} }
}); });

View file

@ -2,12 +2,16 @@ package net.osmand.plus.settings;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.graphics.Typeface;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.text.style.StyleSpan;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ExpandableListView; import android.widget.ExpandableListView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@ -17,7 +21,11 @@ import androidx.appcompat.widget.Toolbar;
import androidx.core.view.ViewCompat; import androidx.core.view.ViewCompat;
import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager;
import com.google.android.material.appbar.CollapsingToolbarLayout;
import net.osmand.AndroidUtils; import net.osmand.AndroidUtils;
import net.osmand.IndexConstants;
import net.osmand.PlatformUtil;
import net.osmand.map.ITileSource; import net.osmand.map.ITileSource;
import net.osmand.map.TileSourceManager; import net.osmand.map.TileSourceManager;
import net.osmand.plus.AppInitializer; import net.osmand.plus.AppInitializer;
@ -26,50 +34,66 @@ import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.SQLiteTileSource; import net.osmand.plus.SQLiteTileSource;
import net.osmand.plus.SettingsHelper; import net.osmand.plus.SettingsHelper;
import net.osmand.plus.SettingsHelper.SettingsItem; import net.osmand.plus.SettingsHelper.*;
import net.osmand.plus.UiUtilities; import net.osmand.plus.UiUtilities;
import net.osmand.plus.base.BaseOsmAndFragment; import net.osmand.plus.base.BaseOsmAndFragment;
import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo; import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo;
import net.osmand.plus.poi.PoiUIFilter; import net.osmand.plus.poi.PoiUIFilter;
import net.osmand.plus.profiles.AdditionalDataWrapper;
import net.osmand.plus.quickaction.QuickAction; import net.osmand.plus.quickaction.QuickAction;
import net.osmand.plus.widgets.TextViewEx; import net.osmand.plus.widgets.TextViewEx;
import net.osmand.plus.settings.ExportImportSettingsAdapter.Type;
import org.apache.commons.logging.Log;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
public class ImportSettingsFragment extends BaseOsmAndFragment public class ImportSettingsFragment extends BaseOsmAndFragment
implements View.OnClickListener { implements View.OnClickListener {
public static final String TAG = ImportSettingsFragment.class.getSimpleName(); public static final String TAG = ImportSettingsFragment.class.getSimpleName();
public static final Log LOG = PlatformUtil.getLog(ImportSettingsFragment.class.getSimpleName());
private static final String DUPLICATES_START_TIME_KEY = "duplicates_start_time";
private static final long MIN_DELAY_TIME_MS = 500;
static final String IMPORT_SETTINGS_TAG = "import_settings_tag";
private OsmandApplication app; private OsmandApplication app;
private ExportImportSettingsAdapter adapter; private ExportImportSettingsAdapter adapter;
private ExpandableListView expandableList; private ExpandableListView expandableList;
private TextViewEx selectBtn; private TextViewEx selectBtn;
private TextView description;
private List<SettingsItem> settingsItems; private List<SettingsItem> settingsItems;
private File file; private File file;
private boolean allSelected; private boolean allSelected;
private boolean nightMode; private boolean nightMode;
private LinearLayout buttonsContainer;
private ProgressBar progressBar;
private CollapsingToolbarLayout toolbarLayout;
private SettingsHelper settingsHelper;
private long duplicateStartTime;
public static void showInstance(@NonNull FragmentManager fm, List<SettingsItem> settingsItems, @NonNull File file) { public static void showInstance(@NonNull FragmentManager fm, @NonNull List<SettingsItem> settingsItems, @NonNull File file) {
ImportSettingsFragment fragment = new ImportSettingsFragment(); ImportSettingsFragment fragment = new ImportSettingsFragment();
fragment.setSettingsItems(settingsItems); fragment.setSettingsItems(settingsItems);
fragment.setFile(file); fragment.setFile(file);
fm.beginTransaction().replace(R.id.fragmentContainer, fragment, TAG).addToBackStack(null).commit(); fm.beginTransaction().
replace(R.id.fragmentContainer, fragment, TAG)
.addToBackStack(IMPORT_SETTINGS_TAG)
.commitAllowingStateLoss();
} }
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
duplicateStartTime = savedInstanceState.getLong(DUPLICATES_START_TIME_KEY);
}
app = requireMyApplication(); app = requireMyApplication();
settingsHelper = app.getSettingsHelper();
nightMode = !app.getSettings().isLightContent(); nightMode = !app.getSettings().isLightContent();
if (settingsItems == null) {
settingsItems = app.getSettingsHelper().getSettingsItems();
}
if (file == null) {
file = app.getSettingsHelper().getSettingsFile();
}
} }
@Nullable @Nullable
@ -77,13 +101,17 @@ public class ImportSettingsFragment extends BaseOsmAndFragment
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
inflater = UiUtilities.getInflater(app, nightMode); inflater = UiUtilities.getInflater(app, nightMode);
View root = inflater.inflate(R.layout.fragment_import, container, false); View root = inflater.inflate(R.layout.fragment_import, container, false);
setupToolbar((Toolbar) root.findViewById(R.id.toolbar)); Toolbar toolbar = root.findViewById(R.id.toolbar);
TextViewEx continueBtn = root.findViewById(R.id.continue_button); TextViewEx continueBtn = root.findViewById(R.id.continue_button);
toolbarLayout = root.findViewById(R.id.toolbar_layout);
selectBtn = root.findViewById(R.id.select_button); selectBtn = root.findViewById(R.id.select_button);
expandableList = root.findViewById(R.id.list); expandableList = root.findViewById(R.id.list);
buttonsContainer = root.findViewById(R.id.buttons_container);
progressBar = root.findViewById(R.id.progress_bar);
setupToolbar(toolbar);
ViewCompat.setNestedScrollingEnabled(expandableList, true); ViewCompat.setNestedScrollingEnabled(expandableList, true);
View header = inflater.inflate(R.layout.list_item_description_header, null); View header = inflater.inflate(R.layout.list_item_description_header, null);
TextView description = header.findViewById(R.id.description); description = header.findViewById(R.id.description);
description.setText(R.string.select_data_to_import); description.setText(R.string.select_data_to_import);
expandableList.addHeaderView(header); expandableList.addHeaderView(header);
continueBtn.setOnClickListener(this); continueBtn.setOnClickListener(this);
@ -95,10 +123,48 @@ public class ImportSettingsFragment extends BaseOsmAndFragment
} }
@Override @Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState); super.onActivityCreated(savedInstanceState);
adapter = new ExportImportSettingsAdapter(app, getSettingsToOperate(), nightMode, true); ImportAsyncTask importTask = settingsHelper.getImportTask();
if (importTask != null) {
if (settingsItems == null) {
settingsItems = importTask.getItems();
}
if (file == null) {
file = importTask.getFile();
}
List<Object> duplicates = importTask.getDuplicates();
List<SettingsItem> selectedItems = importTask.getSelectedItems();
if (duplicates == null) {
importTask.setDuplicatesListener(getDuplicatesListener());
} else if (duplicates.isEmpty()) {
if (selectedItems != null && file != null) {
settingsHelper.importSettings(file, selectedItems, "", 1, getImportListener());
}
}
}
adapter = new ExportImportSettingsAdapter(app, nightMode, true);
if (settingsItems != null) {
adapter.updateSettingsList(getSettingsToOperate(settingsItems));
}
expandableList.setAdapter(adapter); expandableList.setAdapter(adapter);
toolbarLayout.setTitle(getString(R.string.shared_string_import));
ImportType importTaskType = settingsHelper.getImportTaskType();
if (importTaskType == ImportType.CHECK_DUPLICATES && !settingsHelper.isImportDone()) {
updateUi(R.string.shared_string_preparing, R.string.checking_for_duplicate_description);
} else if (importTaskType == ImportType.IMPORT) {
updateUi(R.string.shared_string_importing, R.string.importing_from);
} else {
toolbarLayout.setTitle(getString(R.string.shared_string_import));
}
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putLong(DUPLICATES_START_TIME_KEY, duplicateStartTime);
} }
@Override @Override
@ -121,69 +187,89 @@ public class ImportSettingsFragment extends BaseOsmAndFragment
} }
} }
private void updateUi(int toolbarTitleRes, int descriptionRes) {
if (file != null) {
String fileName = file.getName();
toolbarLayout.setTitle(getString(toolbarTitleRes));
description.setText(UiUtilities.createSpannableString(
String.format(getString(descriptionRes), fileName),
fileName,
new StyleSpan(Typeface.BOLD)
));
buttonsContainer.setVisibility(View.GONE);
progressBar.setVisibility(View.VISIBLE);
adapter.clearSettingsList();
}
}
private void importItems() { private void importItems() {
List<SettingsItem> settingsItems = getSettingsItemsFromData(adapter.getDataToOperate()); updateUi(R.string.shared_string_preparing, R.string.checking_for_duplicate_description);
List<Object> duplicateItems = getDuplicatesData(settingsItems); List<SettingsItem> selectedItems = getSettingsItemsFromData(adapter.getDataToOperate());
if (duplicateItems.isEmpty()) { if (file != null && settingsItems != null) {
app.getSettingsHelper().importSettings(file, settingsItems, "", 1, new SettingsHelper.SettingsImportListener() { duplicateStartTime = System.currentTimeMillis();
settingsHelper.checkDuplicates(file, settingsItems, selectedItems, getDuplicatesListener());
}
}
private SettingsHelper.SettingsImportListener getImportListener() {
return new SettingsHelper.SettingsImportListener() {
@Override @Override
public void onSettingsImportFinished(boolean succeed, boolean empty, @NonNull List<SettingsHelper.SettingsItem> items) { public void onSettingsImportFinished(boolean succeed, @NonNull List<SettingsItem> items) {
FragmentManager fm = getFragmentManager();
if (succeed) { if (succeed) {
app.showShortToastMessage(app.getString(R.string.file_imported_successfully, file.getName()));
app.getRendererRegistry().updateExternalRenderers(); app.getRendererRegistry().updateExternalRenderers();
AppInitializer.loadRoutingFiles(app, new AppInitializer.LoadRoutingFilesCallback() { AppInitializer.loadRoutingFiles(app, new AppInitializer.LoadRoutingFilesCallback() {
@Override @Override
public void onRoutingFilesLoaded() { public void onRoutingFilesLoaded() {
} }
}); });
} else if (empty) { if (fm != null && file != null) {
app.showShortToastMessage(app.getString(R.string.file_import_error, file.getName(), app.getString(R.string.shared_string_unexpected_error))); ImportCompleteFragment.showInstance(fm, items, file.getName());
} }
} }
});
FragmentManager fm = getFragmentManager();
if (fm != null) {
fm.popBackStackImmediate();
} }
};
}
private SettingsHelper.CheckDuplicatesListener getDuplicatesListener() {
return new SettingsHelper.CheckDuplicatesListener() {
@Override
public void onDuplicatesChecked(@NonNull final List<Object> duplicates, final List<SettingsItem> items) {
long spentTime = System.currentTimeMillis() - duplicateStartTime;
if (spentTime < MIN_DELAY_TIME_MS) {
long delay = MIN_DELAY_TIME_MS - spentTime;
app.runInUIThread(new Runnable() {
@Override
public void run() {
processDuplicates(duplicates, items);
}
}, delay);
} else { } else {
ImportDuplicatesFragment.showInstance(requireActivity().getSupportFragmentManager(), duplicateItems, settingsItems, file); processDuplicates(duplicates, items);
}
}
};
}
private void processDuplicates(List<Object> duplicates, List<SettingsItem> items) {
FragmentManager fm = getFragmentManager();
if (file != null) {
if (duplicates.isEmpty()) {
if (isAdded()) {
updateUi(R.string.shared_string_importing, R.string.importing_from);
}
settingsHelper.importSettings(file, items, "", 1, getImportListener());
} else if (fm != null && !isStateSaved()) {
ImportDuplicatesFragment.showInstance(fm, duplicates, items, file);
}
} }
} }
public static List<Object> getDuplicatesData(List<SettingsItem> items) { private void dismissFragment() {
List<Object> duplicateItems = new ArrayList<>(); FragmentManager fm = getFragmentManager();
for (SettingsItem item : items) { if (fm != null && !fm.isStateSaved()) {
if (item instanceof SettingsHelper.ProfileSettingsItem) { getFragmentManager().popBackStack(IMPORT_SETTINGS_TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE);
if (item.exists()) {
duplicateItems.add(((SettingsHelper.ProfileSettingsItem) item).getModeBean());
} }
} else if (item instanceof SettingsHelper.QuickActionSettingsItem) {
List<QuickAction> duplicates = ((SettingsHelper.QuickActionSettingsItem) item).excludeDuplicateItems();
if (!duplicates.isEmpty()) {
duplicateItems.addAll(duplicates);
}
} else if (item instanceof SettingsHelper.PoiUiFilterSettingsItem) {
List<PoiUIFilter> duplicates = ((SettingsHelper.PoiUiFilterSettingsItem) item).excludeDuplicateItems();
if (!duplicates.isEmpty()) {
duplicateItems.addAll(duplicates);
}
} else if (item instanceof SettingsHelper.MapSourcesSettingsItem) {
List<ITileSource> duplicates = ((SettingsHelper.MapSourcesSettingsItem) item).excludeDuplicateItems();
if (!duplicates.isEmpty()) {
duplicateItems.addAll(duplicates);
}
} else if (item instanceof SettingsHelper.FileSettingsItem) {
if (item.exists()) {
duplicateItems.add(((SettingsHelper.FileSettingsItem) item).getFile());
}
} else if (item instanceof SettingsHelper.AvoidRoadsSettingsItem) {
List<AvoidRoadInfo> avoidRoads = ((SettingsHelper.AvoidRoadsSettingsItem) item).excludeDuplicateItems();
if (!avoidRoads.isEmpty()) {
duplicateItems.addAll(avoidRoads);
}
}
}
return duplicateItems;
} }
public void setSettingsItems(List<SettingsItem> settingsItems) { public void setSettingsItems(List<SettingsItem> settingsItems) {
@ -228,8 +314,8 @@ public class ImportSettingsFragment extends BaseOsmAndFragment
return settingsItems; return settingsItems;
} }
private List<AdditionalDataWrapper> getSettingsToOperate() { public static Map<Type, List<?>> getSettingsToOperate(List<SettingsItem> settingsItems) {
List<AdditionalDataWrapper> settingsToOperate = new ArrayList<>(); Map<Type, List<?>> settingsToOperate = new HashMap<>();
List<ApplicationMode.ApplicationModeBean> profiles = new ArrayList<>(); List<ApplicationMode.ApplicationModeBean> profiles = new ArrayList<>();
List<QuickAction> quickActions = new ArrayList<>(); List<QuickAction> quickActions = new ArrayList<>();
List<PoiUIFilter> poiUIFilters = new ArrayList<>(); List<PoiUIFilter> poiUIFilters = new ArrayList<>();
@ -238,64 +324,50 @@ public class ImportSettingsFragment extends BaseOsmAndFragment
List<File> renderFilesList = new ArrayList<>(); List<File> renderFilesList = new ArrayList<>();
List<AvoidRoadInfo> avoidRoads = new ArrayList<>(); List<AvoidRoadInfo> avoidRoads = new ArrayList<>();
for (SettingsHelper.SettingsItem item : settingsItems) { for (SettingsItem item : settingsItems) {
if (item.getType().equals(SettingsHelper.SettingsItemType.PROFILE)) { if (item.getType().equals(SettingsItemType.PROFILE)) {
profiles.add(((SettingsHelper.ProfileSettingsItem) item).getModeBean()); profiles.add(((ProfileSettingsItem) item).getModeBean());
} else if (item.getType().equals(SettingsHelper.SettingsItemType.QUICK_ACTION)) { } else if (item.getType().equals(SettingsItemType.QUICK_ACTION)) {
quickActions.addAll(((SettingsHelper.QuickActionSettingsItem) item).getItems()); quickActions.addAll(((QuickActionSettingsItem) item).getItems());
} else if (item.getType().equals(SettingsHelper.SettingsItemType.POI_UI_FILTERS)) { quickActions.addAll(((QuickActionSettingsItem) item).getDuplicateItems());
poiUIFilters.addAll(((SettingsHelper.PoiUiFilterSettingsItem) item).getItems()); } else if (item.getType().equals(SettingsItemType.POI_UI_FILTERS)) {
} else if (item.getType().equals(SettingsHelper.SettingsItemType.MAP_SOURCES)) { poiUIFilters.addAll(((PoiUiFilterSettingsItem) item).getItems());
tileSourceTemplates.addAll(((SettingsHelper.MapSourcesSettingsItem) item).getItems()); poiUIFilters.addAll(((PoiUiFilterSettingsItem) item).getDuplicateItems());
} else if (item.getType().equals(SettingsHelper.SettingsItemType.FILE)) { } else if (item.getType().equals(SettingsItemType.MAP_SOURCES)) {
if (item.getName().startsWith("/rendering/")) { tileSourceTemplates.addAll(((MapSourcesSettingsItem) item).getItems());
renderFilesList.add(((SettingsHelper.FileSettingsItem) item).getFile()); tileSourceTemplates.addAll(((MapSourcesSettingsItem) item).getDuplicateItems());
} else if (item.getName().startsWith("/routing/")) { } else if (item.getType().equals(SettingsItemType.FILE)) {
routingFilesList.add(((SettingsHelper.FileSettingsItem) item).getFile()); if (item.getName().contains(IndexConstants.RENDERERS_DIR)) {
renderFilesList.add(((FileSettingsItem) item).getFile());
} else if (item.getName().contains(IndexConstants.ROUTING_PROFILES_DIR)) {
routingFilesList.add(((FileSettingsItem) item).getFile());
} }
} else if (item.getType().equals(SettingsHelper.SettingsItemType.AVOID_ROADS)) { } else if (item.getType().equals(SettingsItemType.AVOID_ROADS)) {
avoidRoads.addAll(((SettingsHelper.AvoidRoadsSettingsItem) item).getItems()); avoidRoads.addAll(((AvoidRoadsSettingsItem) item).getItems());
avoidRoads.addAll(((AvoidRoadsSettingsItem) item).getDuplicateItems());
} }
} }
if (!profiles.isEmpty()) { if (!profiles.isEmpty()) {
settingsToOperate.add(new AdditionalDataWrapper( settingsToOperate.put(Type.PROFILE, profiles);
AdditionalDataWrapper.Type.PROFILE,
profiles));
} }
if (!quickActions.isEmpty()) { if (!quickActions.isEmpty()) {
settingsToOperate.add(new AdditionalDataWrapper( settingsToOperate.put(Type.QUICK_ACTIONS, quickActions);
AdditionalDataWrapper.Type.QUICK_ACTIONS,
quickActions));
} }
if (!poiUIFilters.isEmpty()) { if (!poiUIFilters.isEmpty()) {
settingsToOperate.add(new AdditionalDataWrapper( settingsToOperate.put(Type.POI_TYPES, poiUIFilters);
AdditionalDataWrapper.Type.POI_TYPES,
poiUIFilters));
} }
if (!tileSourceTemplates.isEmpty()) { if (!tileSourceTemplates.isEmpty()) {
settingsToOperate.add(new AdditionalDataWrapper( settingsToOperate.put(Type.MAP_SOURCES, tileSourceTemplates);
AdditionalDataWrapper.Type.MAP_SOURCES,
tileSourceTemplates
));
} }
if (!renderFilesList.isEmpty()) { if (!renderFilesList.isEmpty()) {
settingsToOperate.add(new AdditionalDataWrapper( settingsToOperate.put(Type.CUSTOM_RENDER_STYLE, renderFilesList);
AdditionalDataWrapper.Type.CUSTOM_RENDER_STYLE,
renderFilesList
));
} }
if (!routingFilesList.isEmpty()) { if (!routingFilesList.isEmpty()) {
settingsToOperate.add(new AdditionalDataWrapper( settingsToOperate.put(Type.CUSTOM_ROUTING, routingFilesList);
AdditionalDataWrapper.Type.CUSTOM_ROUTING,
routingFilesList
));
} }
if (!avoidRoads.isEmpty()) { if (!avoidRoads.isEmpty()) {
settingsToOperate.add(new AdditionalDataWrapper( settingsToOperate.put(Type.AVOID_ROADS, avoidRoads);
AdditionalDataWrapper.Type.AVOID_ROADS,
avoidRoads
));
} }
return settingsToOperate; return settingsToOperate;
} }
@ -314,10 +386,7 @@ public class ImportSettingsFragment extends BaseOsmAndFragment
dismissDialog.setPositiveButton(R.string.shared_string_exit, new DialogInterface.OnClickListener() { dismissDialog.setPositiveButton(R.string.shared_string_exit, new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
FragmentManager fm = getFragmentManager(); dismissFragment();
if (fm != null) {
fm.popBackStackImmediate();
}
} }
}); });
dismissDialog.show(); dismissDialog.show();

View file

@ -0,0 +1,131 @@
package net.osmand.plus.settings;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import net.osmand.AndroidUtils;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.settings.ExportImportSettingsAdapter.Type;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
public class ImportedSettingsItemsAdapter extends
RecyclerView.Adapter<ImportedSettingsItemsAdapter.ItemViewHolder> {
private Map<Type, List<?>> itemsMap;
private List<Type> itemsTypes;
private UiUtilities uiUtils;
private OsmandApplication app;
private boolean nightMode;
private OnItemClickListener listener;
ImportedSettingsItemsAdapter(@NonNull OsmandApplication app, Map<Type, List<?>> itemsMap,
boolean nightMode, OnItemClickListener listener) {
this.app = app;
this.itemsMap = itemsMap;
this.nightMode = nightMode;
this.listener = listener;
uiUtils = app.getUIUtilities();
itemsTypes = new ArrayList<>(itemsMap.keySet());
Collections.sort(itemsTypes);
}
@NonNull
@Override
public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = UiUtilities.getInflater(app, nightMode);
View view = inflater.inflate(R.layout.list_item_import, parent, false);
return new ItemViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) {
final Type currentItemType = itemsTypes.get(position);
boolean isLastItem = itemsTypes.size() - 1 == position;
int activeColorRes = nightMode
? R.color.active_color_primary_dark
: R.color.active_color_primary_light;
holder.icon.setPadding(0, 0, AndroidUtils.dpToPx(app, 16), 0);
holder.title.setTextColor(app.getResources().getColor(activeColorRes));
holder.divider.setVisibility(isLastItem ? View.VISIBLE : View.GONE);
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
listener.onItemClick(currentItemType);
}
});
holder.subTitle.setText(String.format(
app.getString(R.string.ltr_or_rtl_combine_via_colon),
app.getString(R.string.items_added),
String.valueOf(itemsMap.get(currentItemType).size()))
);
switch (currentItemType) {
case PROFILE:
holder.icon.setImageDrawable(uiUtils.getIcon(R.drawable.map_action_settings, activeColorRes));
holder.title.setText(R.string.shared_string_settings);
break;
case QUICK_ACTIONS:
holder.icon.setImageDrawable(uiUtils.getIcon(R.drawable.map_quick_action, activeColorRes));
holder.title.setText(R.string.configure_screen_quick_action);
break;
case POI_TYPES:
holder.icon.setImageDrawable(uiUtils.getIcon(R.drawable.ic_action_search_dark, activeColorRes));
holder.title.setText(R.string.search_activity);
break;
case MAP_SOURCES:
holder.icon.setImageDrawable(uiUtils.getIcon(R.drawable.ic_action_layers, activeColorRes));
holder.title.setText(R.string.configure_map);
break;
case CUSTOM_RENDER_STYLE:
holder.icon.setImageDrawable(uiUtils.getIcon(R.drawable.ic_action_map_style, activeColorRes));
holder.title.setText(R.string.shared_string_rendering_style);
break;
case CUSTOM_ROUTING:
holder.icon.setImageDrawable(uiUtils.getIcon(R.drawable.ic_action_route_distance, activeColorRes));
holder.title.setText(R.string.shared_string_routing);
break;
case AVOID_ROADS:
holder.icon.setImageDrawable(uiUtils.getIcon(R.drawable.ic_action_alert, activeColorRes));
holder.title.setText(R.string.avoid_road);
break;
}
}
@Override
public int getItemCount() {
return itemsMap.keySet().size();
}
public static class ItemViewHolder extends RecyclerView.ViewHolder {
ImageView icon;
TextView title;
TextView subTitle;
View divider;
ItemViewHolder(View itemView) {
super(itemView);
title = itemView.findViewById(R.id.title);
subTitle = itemView.findViewById(R.id.sub_title);
icon = itemView.findViewById(R.id.icon);
divider = itemView.findViewById(R.id.bottom_divider);
}
}
interface OnItemClickListener {
void onItemClick(Type type);
}
}