Bimba.git

commit 077344678bcbc072402eb404956c1e7bc5aaa0da

Author: Adam Pioterek <adam.pioterek@protonmail.ch>

Allow selecting other timetable source

%!v(PANIC=String method: strings: negative Repeat count)


diff --git a/.gitignore b/.gitignore
index 83957113cd0e2c9f668217158c710892a728a3fb..6c517bdb02e4158ac3924af5074446f05d2dea04 100644
--- a/.gitignore
+++ b/.gitignore
@@ -35,6 +35,7 @@
 # Intellij
 *.iml
 .idea/workspace.xml
+.idea/*
 
 # Keystore files
 *.jks




diff --git a/.idea/assetWizardSettings.xml b/.idea/assetWizardSettings.xml
deleted file mode 100644
index 3e98d31b2010a19f1e681829d93ff2c472f4acee..0000000000000000000000000000000000000000
--- a/.idea/assetWizardSettings.xml
+++ /dev/null
@@ -1,96 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="WizardSettings">
-    <option name="children">
-      <map>
-        <entry key="imageWizard">
-          <value>
-            <PersistentState>
-              <option name="children">
-                <map>
-                  <entry key="imageAssetPanel">
-                    <value>
-                      <PersistentState>
-                        <option name="children">
-                          <map>
-                            <entry key="launcher">
-                              <value>
-                                <PersistentState>
-                                  <option name="children">
-                                    <map>
-                                      <entry key="foregroundImage">
-                                        <value>
-                                          <PersistentState>
-                                            <option name="values">
-                                              <map>
-                                                <entry key="scalingPercent" value="75" />
-                                                <entry key="trimmed" value="true" />
-                                              </map>
-                                            </option>
-                                          </PersistentState>
-                                        </value>
-                                      </entry>
-                                    </map>
-                                  </option>
-                                  <option name="values">
-                                    <map>
-                                      <entry key="backgroundAssetType" value="COLOR" />
-                                      <entry key="backgroundColor" value="3a3a3b" />
-                                      <entry key="foregroundImage" value="$PROJECT_DIR$/research/localonly/newLogo/Bimba/Logo/#3.svg" />
-                                    </map>
-                                  </option>
-                                </PersistentState>
-                              </value>
-                            </entry>
-                          </map>
-                        </option>
-                      </PersistentState>
-                    </value>
-                  </entry>
-                </map>
-              </option>
-            </PersistentState>
-          </value>
-        </entry>
-        <entry key="vectorWizard">
-          <value>
-            <PersistentState>
-              <option name="children">
-                <map>
-                  <entry key="vectorAssetStep">
-                    <value>
-                      <PersistentState>
-                        <option name="children">
-                          <map>
-                            <entry key="clipartAsset">
-                              <value>
-                                <PersistentState>
-                                  <option name="values">
-                                    <map>
-                                      <entry key="url" value="jar:file:/opt/android-studio/plugins/android/lib/android.jar!/images/material_design_icons/action/ic_accessible_black_24dp.xml" />
-                                    </map>
-                                  </option>
-                                </PersistentState>
-                              </value>
-                            </entry>
-                          </map>
-                        </option>
-                        <option name="values">
-                          <map>
-                            <entry key="assetSourceType" value="FILE" />
-                            <entry key="outputName" value="logo_splash" />
-                            <entry key="sourceFile" value="$PROJECT_DIR$/research/localonly/newLogo/Bimba/Logo/fg.svg" />
-                          </map>
-                        </option>
-                      </PersistentState>
-                    </value>
-                  </entry>
-                </map>
-              </option>
-            </PersistentState>
-          </value>
-        </entry>
-      </map>
-    </option>
-  </component>
-</project>
\ No newline at end of file




diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser
deleted file mode 100644
index 9b0222830be3ca4ce7a0ca94e509a1c5c3e7009a..0000000000000000000000000000000000000000
Binary files a/.idea/caches/build_file_checksums.ser and /dev/null differ




diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
deleted file mode 100644
index 30aa626c23142d59e94cc76327172301f159b618..0000000000000000000000000000000000000000
--- a/.idea/codeStyles/Project.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<component name="ProjectCodeStyleConfiguration">
-  <code_scheme name="Project" version="173">
-    <Objective-C-extensions>
-      <file>
-        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
-        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
-        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
-        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
-        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
-        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
-        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
-        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
-        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
-      </file>
-      <class>
-        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
-        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
-        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
-        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
-        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
-        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
-      </class>
-      <extensions>
-        <pair source="cpp" header="h" fileNamingConvention="NONE" />
-        <pair source="c" header="h" fileNamingConvention="NONE" />
-      </extensions>
-    </Objective-C-extensions>
-  </code_scheme>
-</component>
\ No newline at end of file




diff --git a/.idea/compiler.xml b/.idea/compiler.xml
deleted file mode 100644
index 96cc43efa6a0885098044e976cd780bb42c68a70..0000000000000000000000000000000000000000
--- a/.idea/compiler.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="CompilerConfiguration">
-    <resourceExtensions />
-    <wildcardResourcePatterns>
-      <entry name="!?*.java" />
-      <entry name="!?*.form" />
-      <entry name="!?*.class" />
-      <entry name="!?*.groovy" />
-      <entry name="!?*.scala" />
-      <entry name="!?*.flex" />
-      <entry name="!?*.kt" />
-      <entry name="!?*.clj" />
-      <entry name="!?*.aj" />
-    </wildcardResourcePatterns>
-    <annotationProcessing>
-      <profile default="true" name="Default" enabled="false">
-        <processorPath useClasspath="true" />
-      </profile>
-    </annotationProcessing>
-  </component>
-</project>
\ No newline at end of file




diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
deleted file mode 100644
index e7bedf3377d40335424fd605124d4761390218bb..0000000000000000000000000000000000000000
--- a/.idea/copyright/profiles_settings.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-<component name="CopyrightManager">
-  <settings default="" />
-</component>
\ No newline at end of file




diff --git a/.idea/dictionaries/adam.xml b/.idea/dictionaries/adam.xml
deleted file mode 100644
index 9d09bd12aa6a772411430c5662305f5dda08a2df..0000000000000000000000000000000000000000
--- a/.idea/dictionaries/adam.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<component name="ProjectDictionaryState">
-  <dictionary name="adam">
-    <words>
-      <w>headsign</w>
-      <w>headsigns</w>
-    </words>
-  </dictionary>
-</component>
\ No newline at end of file




diff --git a/.idea/gradle.xml b/.idea/gradle.xml
deleted file mode 100644
index 3cd8408c80959986c8f744fecfdd5e0669d6c1f8..0000000000000000000000000000000000000000
--- a/.idea/gradle.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="GradleSettings">
-    <option name="linkedExternalProjectsSettings">
-      <GradleProjectSettings>
-        <option name="distributionType" value="LOCAL" />
-        <option name="externalProjectPath" value="$PROJECT_DIR$" />
-        <option name="gradleHome" value="$APPLICATION_HOME_DIR$/gradle/gradle-4.1" />
-        <option name="modules">
-          <set>
-            <option value="$PROJECT_DIR$" />
-            <option value="$PROJECT_DIR$/app" />
-          </set>
-        </option>
-        <option name="resolveModulePerSourceSet" value="false" />
-      </GradleProjectSettings>
-    </option>
-  </component>
-</project>
\ No newline at end of file




diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml
deleted file mode 100644
index 91afacf395828414ae1ddd61b05a56bd9d1e305c..0000000000000000000000000000000000000000
--- a/.idea/kotlinc.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="Kotlin2JsCompilerArguments">
-    <option name="sourceMapEmbedSources" />
-    <option name="sourceMapPrefix" />
-  </component>
-  <component name="Kotlin2JvmCompilerArguments">
-    <option name="jvmTarget" value="1.8" />
-  </component>
-</project>
\ No newline at end of file




diff --git a/.idea/misc.xml b/.idea/misc.xml
deleted file mode 100644
index ba7052b8197ddf8ba8756022d905d03055c7ad60..0000000000000000000000000000000000000000
--- a/.idea/misc.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="NullableNotNullManager">
-    <option name="myDefaultNullable" value="android.support.annotation.Nullable" />
-    <option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
-    <option name="myNullables">
-      <value>
-        <list size="4">
-          <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
-          <item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
-          <item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
-          <item index="3" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
-        </list>
-      </value>
-    </option>
-    <option name="myNotNulls">
-      <value>
-        <list size="4">
-          <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
-          <item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
-          <item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
-          <item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
-        </list>
-      </value>
-    </option>
-  </component>
-  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
-    <output url="file://$PROJECT_DIR$/build/classes" />
-  </component>
-  <component name="ProjectType">
-    <option name="id" value="Android" />
-  </component>
-</project>
\ No newline at end of file




diff --git a/.idea/modules.xml b/.idea/modules.xml
deleted file mode 100644
index 0f1d3e3f358c379188ea2707108c50db74a3d77c..0000000000000000000000000000000000000000
--- a/.idea/modules.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="ProjectModuleManager">
-    <modules>
-      <module fileurl="file://$PROJECT_DIR$/Bimba.iml" filepath="$PROJECT_DIR$/Bimba.iml" />
-      <module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
-    </modules>
-  </component>
-</project>
\ No newline at end of file




diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml
deleted file mode 100644
index 7f68460d8b38ac04e3a3224d7c79ef719b1991a9..0000000000000000000000000000000000000000
--- a/.idea/runConfigurations.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="RunConfigurationProducerService">
-    <option name="ignoredProducers">
-      <set>
-        <option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
-        <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
-        <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
-      </set>
-    </option>
-  </component>
-</project>
\ No newline at end of file




diff --git a/.idea/vcs.xml b/.idea/vcs.xml
deleted file mode 100644
index 94a25f7f4cb416c083d265558da75d457237d671..0000000000000000000000000000000000000000
--- a/.idea/vcs.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="VcsDirectoryMappings">
-    <mapping directory="$PROJECT_DIR$" vcs="Git" />
-  </component>
-</project>
\ No newline at end of file




diff --git a/app/build.gradle b/app/build.gradle
index 483d7d29913a693ccfb16388345d6ea591a0a535..65115d99e29efeb3b8e2ab64041880a0c6bf3c8e 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -9,8 +9,8 @@     defaultConfig {
         applicationId "ml.adamsprogs.bimba"
         minSdkVersion 19
         targetSdkVersion 27
-        versionCode 10
-        versionName "2.0-beta2"
+        versionCode 11
+        versionName "2.0-beta2.1"
         testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
         vectorDrawables.useSupportLibrary = true
     }




diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index b3e1c2f517a6689a15b881bf0a648e0a0bf8d6f3..6a24bee526d7074fdaf4245f92ed6ffd4a5a6a58 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -30,6 +30,15 @@         
         <activity android:name=".activities.NoDbActivity" />
         <activity android:name=".activities.EditFavouriteActivity" />
         <activity
+            android:name=".activities.SettingsActivity"
+            android:label="@string/title_activity_settings"
+            android:parentActivityName=".activities.DashActivity"
+            android:theme="@style/AppTheme.ActionBar" >
+            <meta-data
+                android:name="android.support.PARENT_ACTIVITY"
+                android:value="ml.adamsprogs.bimba.activities.DashActivity" />
+        </activity>
+        <activity
             android:name=".activities.HelpActivity"
             android:label="@string/title_activity_help"
             android:theme="@style/AppTheme" />




diff --git a/app/src/main/java/ml/adamsprogs/bimba/activities/AppCompatPreferenceActivity.java b/app/src/main/java/ml/adamsprogs/bimba/activities/AppCompatPreferenceActivity.java
new file mode 100644
index 0000000000000000000000000000000000000000..6e707b84bb48d8df1fabb89d95b2eeea5138d456
--- /dev/null
+++ b/app/src/main/java/ml/adamsprogs/bimba/activities/AppCompatPreferenceActivity.java
@@ -0,0 +1,109 @@
+package ml.adamsprogs.bimba.activities;
+
+import android.content.res.Configuration;
+        import android.os.Bundle;
+        import android.preference.PreferenceActivity;
+        import android.support.annotation.LayoutRes;
+        import android.support.annotation.Nullable;
+        import android.support.v7.app.ActionBar;
+        import android.support.v7.app.AppCompatDelegate;
+        import android.support.v7.widget.Toolbar;
+        import android.view.MenuInflater;
+        import android.view.View;
+        import android.view.ViewGroup;
+
+/**
+ * A {@link android.preference.PreferenceActivity} which implements and proxies the necessary calls
+ * to be used with AppCompat.
+ */
+public abstract class AppCompatPreferenceActivity extends PreferenceActivity {
+
+    private AppCompatDelegate mDelegate;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        getDelegate().installViewFactory();
+        getDelegate().onCreate(savedInstanceState);
+        super.onCreate(savedInstanceState);
+    }
+
+    @Override
+    protected void onPostCreate(Bundle savedInstanceState) {
+        super.onPostCreate(savedInstanceState);
+        getDelegate().onPostCreate(savedInstanceState);
+    }
+
+    public ActionBar getSupportActionBar() {
+        return getDelegate().getSupportActionBar();
+    }
+
+    public void setSupportActionBar(@Nullable Toolbar toolbar) {
+        getDelegate().setSupportActionBar(toolbar);
+    }
+
+    @Override
+    public MenuInflater getMenuInflater() {
+        return getDelegate().getMenuInflater();
+    }
+
+    @Override
+    public void setContentView(@LayoutRes int layoutResID) {
+        getDelegate().setContentView(layoutResID);
+    }
+
+    @Override
+    public void setContentView(View view) {
+        getDelegate().setContentView(view);
+    }
+
+    @Override
+    public void setContentView(View view, ViewGroup.LayoutParams params) {
+        getDelegate().setContentView(view, params);
+    }
+
+    @Override
+    public void addContentView(View view, ViewGroup.LayoutParams params) {
+        getDelegate().addContentView(view, params);
+    }
+
+    @Override
+    protected void onPostResume() {
+        super.onPostResume();
+        getDelegate().onPostResume();
+    }
+
+    @Override
+    protected void onTitleChanged(CharSequence title, int color) {
+        super.onTitleChanged(title, color);
+        getDelegate().setTitle(title);
+    }
+
+    @Override
+    public void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        getDelegate().onConfigurationChanged(newConfig);
+    }
+
+    @Override
+    protected void onStop() {
+        super.onStop();
+        getDelegate().onStop();
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        getDelegate().onDestroy();
+    }
+
+    public void invalidateOptionsMenu() {
+        getDelegate().invalidateOptionsMenu();
+    }
+
+    private AppCompatDelegate getDelegate() {
+        if (mDelegate == null) {
+            mDelegate = AppCompatDelegate.create(this, null);
+        }
+        return mDelegate;
+    }
+}
\ No newline at end of file




diff --git a/app/src/main/java/ml/adamsprogs/bimba/activities/DashActivity.kt b/app/src/main/java/ml/adamsprogs/bimba/activities/DashActivity.kt
index eb6692db50c2b41839ea460551e693504f07a724..59aab9334d2fe0d571c05c6552c5c52e49b682d4 100644
--- a/app/src/main/java/ml/adamsprogs/bimba/activities/DashActivity.kt
+++ b/app/src/main/java/ml/adamsprogs/bimba/activities/DashActivity.kt
@@ -76,6 +76,9 @@                 }
                 R.id.drawer_help -> {
                     startActivity(Intent(context, HelpActivity::class.java))
                 }
+                R.id.drawer_settings -> {
+                    startActivity(Intent(context, SettingsActivity::class.java))
+                }
                 else -> {
                 }
             }




diff --git a/app/src/main/java/ml/adamsprogs/bimba/activities/SettingsActivity.kt b/app/src/main/java/ml/adamsprogs/bimba/activities/SettingsActivity.kt
new file mode 100644
index 0000000000000000000000000000000000000000..90b164cd195ffdb2440443814fc0edc8f801338b
--- /dev/null
+++ b/app/src/main/java/ml/adamsprogs/bimba/activities/SettingsActivity.kt
@@ -0,0 +1,48 @@
+package ml.adamsprogs.bimba.activities
+
+import android.preference.*
+import android.os.Bundle
+
+import ml.adamsprogs.bimba.*
+
+// todo create layout with toolbar and fragment; and put fragment here
+class SettingsActivity: AppCompatPreferenceActivity() {
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        supportActionBar.setDisplayHomeAsUpEnabled(true)
+
+        fragmentManager.beginTransaction().replace(android.R.id.content, MainPreferenceFragment()).commit()
+    }
+
+
+    class MainPreferenceFragment : PreferenceFragment() {
+        override fun onCreate(savedInstanceState: Bundle?) {
+            super.onCreate(savedInstanceState)
+            addPreferencesFromResource(R.xml.pref_main)
+
+            bindPreferenceSummaryToValue(findPreference(getString(R.string.key_timetable_source_url)))
+        }
+
+        private fun bindPreferenceSummaryToValue(preference: Preference) {
+            preference.onPreferenceChangeListener = bindPreferenceSummaryToValueListener
+
+            bindPreferenceSummaryToValueListener.onPreferenceChange(preference,
+                    PreferenceManager
+                            .getDefaultSharedPreferences(preference.context)
+                            .getString(preference.key, ""))
+        }
+
+        private val bindPreferenceSummaryToValueListener = Preference.OnPreferenceChangeListener { preference, newValue ->
+            val stringValue = newValue.toString()
+            if (preference is EditTextPreference) {
+                if (preference.getKey() == getString(R.string.key_timetable_source_url)) {
+                    preference.summary = stringValue
+                }
+            } else {
+                preference.summary = stringValue
+            }
+            true
+        }
+    }
+}
\ No newline at end of file




diff --git a/app/src/main/java/ml/adamsprogs/bimba/datasources/TimetableDownloader.kt b/app/src/main/java/ml/adamsprogs/bimba/datasources/TimetableDownloader.kt
index 46e05f2a8bc7c1fde6b1a96c31d1ea21e6dc41a3..1e90a23b1acc8a3901d25ef6981299ad1079ee91 100644
--- a/app/src/main/java/ml/adamsprogs/bimba/datasources/TimetableDownloader.kt
+++ b/app/src/main/java/ml/adamsprogs/bimba/datasources/TimetableDownloader.kt
@@ -6,6 +6,7 @@ import android.content.*
 import android.support.v4.app.NotificationCompat
 import java.io.*
 import android.os.Build
+import android.preference.PreferenceManager.getDefaultSharedPreferences
 import ml.adamsprogs.bimba.*
 import java.net.*
 import java.util.zip.GZIPInputStream
@@ -39,15 +40,18 @@             val localETag = prefs.getString("etag", "")
 
             var httpCon: HttpURLConnection
             try {
+                val sourceUrl = getDefaultSharedPreferences(this).getString(getString(R.string.key_timetable_source_url), getString(R.string.timetable_source_url))
                 try {
-                    val url = URL("https://adamsprogs.tk/gtfs")
+                    if (!sourceUrl.matches(Regex("^https://.*$")))
+                        throw SSLException("Not https address")
+                    val url = URL(sourceUrl)
                     httpCon = url.openConnection() as HttpsURLConnection
                     httpCon.addRequestProperty("If-None-Match", localETag)
                     httpCon.connect()
-                } catch (e:SSLException) {
-                    val url = URL("http://adamsprogs.tk/gtfs")
+                } catch (e: SSLException) {
+                    val url = URL(sourceUrl.replace("https://", "http://"))
                     httpCon = url.openConnection() as HttpURLConnection
-                    httpCon.addRequestProperty("ETag", localETag)
+                    httpCon.addRequestProperty("If-None-Match", localETag)
                     httpCon.connect()
                 }
                 if (httpCon.responseCode == HttpsURLConnection.HTTP_NOT_MODIFIED) {
@@ -91,7 +95,7 @@             prefsEditor.putString("etag", newETag)
             prefsEditor.apply()
 
             val oldDb = File(getSecondaryExternalFilesDir(), "timetable.db")
-            gtfsDb.renameTo(oldDb) // todo delete old before downloading (may require stopping VmClient)
+            gtfsDb.renameTo(oldDb) // todo<p:1> delete old before downloading (may require stopping VmClient), and mutex with VmClient
 
             cancelNotification()
 
@@ -110,7 +114,7 @@
     private fun notify(progress: Int, titleId: Int, messageId: Int, sizeCompressed: Int, sizeUncompressed: Int) {
         /*val quotient = sizeCompressed.toFloat() / sizeUncompressed.toFloat()
         val message = getString(messageId, Math.max(progress * quotient, sizeCompressed.toFloat()),
-                sizeCompressed, ((progress.toFloat() / sizeUncompressed.toFloat()) * 100)) fixme format error*/
+                sizeCompressed, ((progress.toFloat() / sizeUncompressed.toFloat()) * 100)) fixme<p:2> format error*/
         val message = ""
         val title = getString(titleId)
         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O)




diff --git a/app/src/main/res/drawable/ic_settings.xml b/app/src/main/res/drawable/ic_settings.xml
new file mode 100644
index 0000000000000000000000000000000000000000..bb988c1e7b6e67ca36b9e4bea05d1b0a54188b96
--- /dev/null
+++ b/app/src/main/res/drawable/ic_settings.xml
@@ -0,0 +1,10 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:autoMirrored="true"
+    android:viewportHeight="24.0"
+    android:viewportWidth="24.0">
+    <path
+        android:fillColor="@color/textDark"
+        android:pathData="M19.43,12.98c0.04,-0.32 0.07,-0.64 0.07,-0.98s-0.03,-0.66 -0.07,-0.98l2.11,-1.65c0.19,-0.15 0.24,-0.42 0.12,-0.64l-2,-3.46c-0.12,-0.22 -0.39,-0.3 -0.61,-0.22l-2.49,1c-0.52,-0.4 -1.08,-0.73 -1.69,-0.98l-0.38,-2.65C14.46,2.18 14.25,2 14,2h-4c-0.25,0 -0.46,0.18 -0.49,0.42l-0.38,2.65c-0.61,0.25 -1.17,0.59 -1.69,0.98l-2.49,-1c-0.23,-0.09 -0.49,0 -0.61,0.22l-2,3.46c-0.13,0.22 -0.07,0.49 0.12,0.64l2.11,1.65c-0.04,0.32 -0.07,0.65 -0.07,0.98s0.03,0.66 0.07,0.98l-2.11,1.65c-0.19,0.15 -0.24,0.42 -0.12,0.64l2,3.46c0.12,0.22 0.39,0.3 0.61,0.22l2.49,-1c0.52,0.4 1.08,0.73 1.69,0.98l0.38,2.65c0.03,0.24 0.24,0.42 0.49,0.42h4c0.25,0 0.46,-0.18 0.49,-0.42l0.38,-2.65c0.61,-0.25 1.17,-0.59 1.69,-0.98l2.49,1c0.23,0.09 0.49,0 0.61,-0.22l2,-3.46c0.12,-0.22 0.07,-0.49 -0.12,-0.64l-2.11,-1.65zM12,15.5c-1.93,0 -3.5,-1.57 -3.5,-3.5s1.57,-3.5 3.5,-3.5 3.5,1.57 3.5,3.5 -1.57,3.5 -3.5,3.5z" />
+</vector>




diff --git a/app/src/main/res/menu/menu_drawer.xml b/app/src/main/res/menu/menu_drawer.xml
index a1d293088df728c10d1eb40562e52de72ad04000..b100a34f1b78517244b39dfb665156dc5f7a6b4d 100644
--- a/app/src/main/res/menu/menu_drawer.xml
+++ b/app/src/main/res/menu/menu_drawer.xml
@@ -15,6 +15,11 @@                      android:id="@+id/drawer_help"
             android:icon="@drawable/ic_help"
             android:title="@string/help" />
+        <item
+            android:id="@+id/drawer_settings"
+            android:icon="@drawable/ic_settings"
+            android:title="@string/settings"
+            />
     </group>
     <group
         android:id="@+id/drawer_group_validity"




diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index aa1cb3affb568fb5d32ae10dbfa9f9f08ccaa026..9c139ca27b5819a8a45720dac6414ea95bab8fd7 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -12,4 +12,4 @@     #ffc107
 
     <color name="tram">#00adef</color>
     <color name="bus">#c4212a</color>
-</resources>
\ No newline at end of file
+</resources>




diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index c090016ba09ac0e818afaee6b27ade8cdfbe1b5b..e3a8b50047e42052f159d3529e703a103518d6a0 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -82,4 +82,11 @@     Timetable validity has ended. Connect to the Internet to download a new one in order to continue.
     <string name="timetable_validity_today">Timetable validity ends today.</string>
     <string name="timetable_validity_tomorrow">Timetable validity ends tomorrow.</string>
     <string name="just_departed">Just departed</string>
+    <string name="validity_offline_unavailable">Offline timetable unavailable</string>
+    <string name="pref_category_timetable">Timetable</string>
+    <string name="timetable_source_url" translatable="false">http://bimba.tk/gtfs</string>
+    <string name="key_timetable_source_url" translatable="false">key_timetable_source_url</string>
+    <string name="title_timetable_source_url">Timetable source</string>
+    <string name="title_activity_settings">Settings</string>
+    <string name="settings">Settings</string>
 </resources>




diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index f81e3321cf093b655c12c7d0605194b703a0a485..6e8b3469a57e5c647a8154d464cee71d51fd504d 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -7,6 +7,12 @@         @color/colorPrimaryDark
         <item name="colorAccent">@color/colorAccent</item>
     </style>
 
+    <style name="AppTheme.ActionBar" parent="Theme.AppCompat.DayNight">
+        <item name="colorPrimary">@color/colorPrimary</item>
+        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
+        <item name="colorAccent">@color/colorAccent</item>
+    </style>
+
     <style name="SplashTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
         <item name="colorPrimary">@color/colorPrimary</item>
         <item name="colorPrimaryDark">@color/colorPrimaryDark</item>




diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index af0a316c6057bf036684aa31dd002920e984bda2..7fb73d0a01547683f4570520d350ab9d7ae9fcf4 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -68,4 +68,9 @@     Die Gültigkeit des Zeitplans ist beendet. Verbind mit dem Internet, um eine neue herunterzuladen und um fortzufahren.
     <string name="timetable_validity_tomorrow">Fahrplan gilt nur bis morgen.</string>
     <string name="just_departed">Gerade gegangen</string>
     <string name="timetable_uncompressing">%1$d/%2$d, dekompression: %3$f%</string>
+    <string name="validity_offline_unavailable">Offline-Fahrplan ist nicht verfügbar</string>
+    <string name="pref_category_timetable">Fahrplan</string>
+    <string name="title_timetable_source_url">Quelle des Fahrplans</string>
+    <string name="title_activity_settings">Einstellungen</string>
+    <string name="settings">Einstellungen</string>
 </resources>




diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index 849bea7c79e6de3c456e7748808b36499f1ceff6..1a1526712f99734b218ab768630570b5db20e6d1 100644
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -66,4 +66,9 @@     "La validità dell’orario è terminata. Connetti a Internet per scaricarne uno nuovo e continuare. "
     <string name="timetable_validity_tomorrow">L’orario è valido solo fino a domani.</string>
     <string name="just_departed">Appena partito</string>
     <string name="timetable_uncompressing">%1$d/%2$d, decompressione: %3$f%</string>
+    <string name="validity_offline_unavailable">L’orario offline non è disponibile</string>
+    <string name="pref_category_timetable">Orario</string>
+    <string name="title_timetable_source_url">Fonte dell’Orario</string>
+    <string name="title_activity_settings">Impostazioni</string>
+    <string name="settings">Impostazioni</string>
 </resources>




diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml
index e5d158f293b69a694f26ae86c78356c368fdb827..6cd7cb5405c52d4986e2135442f806bf588ba6ff 100644
--- a/app/src/main/res/values-nl/strings.xml
+++ b/app/src/main/res/values-nl/strings.xml
@@ -69,4 +69,9 @@     De dienstregeling is verlopen. Maak verbinding met het internet om een nieuwe te downloaden.
     <string name="timetable_validity_today">De dienstregeling verloopt vandaag.</string>
     <string name="timetable_validity_tomorrow">De dienstregeling verloopt morgen.</string>
     <string name="just_departed">Zojuist vertrokken</string>
+    <string name="validity_offline_unavailable">Offline dienstregeling is niet beschikbaar</string>
+    <string name="pref_category_timetable">Dienstregeling</string>
+    <string name="title_timetable_source_url">Bron van de dienstregeling</string>
+    <string name="title_activity_settings">Instellingen</string>
+    <string name="settings">Instellingen</string>
 </resources>




diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml
index 8b6a33d9399e0878f949d1e5542c24b44d6f68c0..ed5b2634c76a2f74ad1ec86a3dd1e467a81c0922 100644
--- a/app/src/main/res/values-pl/strings.xml
+++ b/app/src/main/res/values-pl/strings.xml
@@ -68,4 +68,9 @@     Rozkład przestał obowiązywać. Połącz się z Internetem, aby pobrać nowy i kontynuować.
     <string name="timetable_validity_tomorrow">Rozkład obowiązuje tylko do jutra.</string>
     <string name="just_departed">Właśnie odjechał</string>
     <string name="timetable_uncompressing">%1$d/%2$d, dekompresja: %3$f%</string>
+    <string name="validity_offline_unavailable">Rozkład offline jest niedostępny</string>
+    <string name="pref_category_timetable">Rozkład</string>
+    <string name="title_timetable_source_url">Źródło rozkładu</string>
+    <string name="title_activity_settings">Ustawienia</string>
+    <string name="settings">Ustawienia</string>
 </resources>
\ No newline at end of file




diff --git a/app/src/main/res/xml/pref_main.xml b/app/src/main/res/xml/pref_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..1c3647edb4ef835066979a1174d44dbd79359557
--- /dev/null
+++ b/app/src/main/res/xml/pref_main.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
+    <PreferenceCategory android:title="@string/pref_category_timetable">
+        <EditTextPreference
+            android:defaultValue="@string/timetable_source_url"
+            android:key="@string/key_timetable_source_url"
+            android:summary="@string/timetable_source_url"
+            android:title="@string/title_timetable_source_url" />
+
+        <!-- todo intent get file (import) -->
+        <!-- todo reset source -->
+    </PreferenceCategory>
+</PreferenceScreen>




diff --git a/build.gradle b/build.gradle
index f7dc8977568630d236b494ed8f2f4f6e2b9efcd2..098acc4f97a71d2164c9e7cff8395e12fb7e2c54 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,7 +1,7 @@
 // Top-level build file where you can add configuration options common to all sub-projects/modules.
 
 buildscript {
-    ext.kotlin_version = '1.2.31'
+    ext.kotlin_version = '1.2.41'
     repositories {
         jcenter()
         maven { url 'https://maven.google.com' }
@@ -9,7 +9,7 @@         //maven { url 'https://dl.bintray.com/guardian/android' } // TooLargeTool
         google()
     }
     dependencies {
-        classpath 'com.android.tools.build:gradle:3.1.0'
+        classpath 'com.android.tools.build:gradle:3.1.2'
         classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
 
         // NOTE: Do not place your application dependencies here; they belong




diff --git a/research/datasources.md b/research/datasources.md
index 036bb5a1103d736d9aaae601923ed6ccc9bb46b3..4478128f46d30bd0dc7877eeaaf4f2fd11d824a8 100644
--- a/research/datasources.md
+++ b/research/datasources.md
@@ -6,6 +6,4 @@ * car park automats: http://egov.psnc.pl/node/29#parkomaty
 * real-time timetable: http://egov.psnc.pl/node/29#przystanki
 * wireless: http://egov.psnc.pl/node/29#wireless_poznan
 * tourism: http://egov.psnc.pl/node/29#turystyka
-
-# Tube drawing
-* https://github.com/johnwalley/d3-tube-map
+* P&R: https://www.peka.poznan.pl/SOP/parkings/getAvailableSpaces.jspb