mirror of
https://github.com/iSoron/uhabits.git
synced 2025-12-06 01:08:50 -06:00
Merge branch 'hotfix/1.7.1' into dev
This commit is contained in:
@@ -21,8 +21,8 @@
|
||||
<manifest
|
||||
package="org.isoron.uhabits"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:versionCode="27"
|
||||
android:versionName="1.7.0">
|
||||
android:versionCode="28"
|
||||
android:versionName="1.7.1">
|
||||
|
||||
<uses-permission android:name="android.permission.VIBRATE"/>
|
||||
|
||||
|
||||
@@ -21,10 +21,10 @@ package org.isoron.uhabits;
|
||||
|
||||
import android.app.*;
|
||||
import android.content.*;
|
||||
import android.support.annotation.*;
|
||||
|
||||
import com.activeandroid.*;
|
||||
|
||||
import org.isoron.uhabits.models.sqlite.*;
|
||||
import org.isoron.uhabits.notifications.*;
|
||||
import org.isoron.uhabits.preferences.*;
|
||||
import org.isoron.uhabits.tasks.*;
|
||||
@@ -88,7 +88,16 @@ public class HabitsApplication extends Application
|
||||
if (db.exists()) db.delete();
|
||||
}
|
||||
|
||||
DatabaseUtils.initializeActiveAndroid(context);
|
||||
try
|
||||
{
|
||||
DatabaseUtils.initializeActiveAndroid(context);
|
||||
}
|
||||
catch (InvalidDatabaseVersionException e)
|
||||
{
|
||||
File db = DatabaseUtils.getDatabaseFile(context);
|
||||
db.renameTo(new File(db.getAbsolutePath() + ".invalid"));
|
||||
DatabaseUtils.initializeActiveAndroid(context);
|
||||
}
|
||||
|
||||
widgetUpdater = component.getWidgetUpdater();
|
||||
widgetUpdater.startListening();
|
||||
|
||||
@@ -20,9 +20,8 @@
|
||||
package org.isoron.uhabits.activities.common.views;
|
||||
|
||||
import android.os.*;
|
||||
import android.view.*;
|
||||
|
||||
public class BundleSavedState extends View.BaseSavedState
|
||||
public class BundleSavedState extends android.support.v4.view.AbsSavedState
|
||||
{
|
||||
public static final Parcelable.Creator<BundleSavedState> CREATOR =
|
||||
new Parcelable.Creator<BundleSavedState>()
|
||||
@@ -51,7 +50,7 @@ public class BundleSavedState extends View.BaseSavedState
|
||||
public BundleSavedState(Parcel source)
|
||||
{
|
||||
super(source);
|
||||
this.bundle = source.readBundle();
|
||||
this.bundle = source.readBundle(getClass().getClassLoader());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -50,8 +50,6 @@ public class HeaderView extends ScrollableChart
|
||||
|
||||
private RectF rect;
|
||||
|
||||
private int maxDataOffset;
|
||||
|
||||
public HeaderView(Context context, AttributeSet attrs)
|
||||
{
|
||||
super(context, attrs);
|
||||
@@ -76,7 +74,6 @@ public class HeaderView extends ScrollableChart
|
||||
|
||||
Resources res = context.getResources();
|
||||
setScrollerBucketSize((int) res.getDimension(R.dimen.checkmarkWidth));
|
||||
setDirection(shouldReverseCheckmarks() ? 1 : -1);
|
||||
|
||||
StyledResources sr = new StyledResources(context);
|
||||
paint = new TextPaint();
|
||||
@@ -99,7 +96,7 @@ public class HeaderView extends ScrollableChart
|
||||
@Override
|
||||
public void onCheckmarkOrderChanged()
|
||||
{
|
||||
setDirection(shouldReverseCheckmarks() ? 1 : -1);
|
||||
updateDirection();
|
||||
postInvalidate();
|
||||
}
|
||||
|
||||
@@ -112,11 +109,20 @@ public class HeaderView extends ScrollableChart
|
||||
@Override
|
||||
protected void onAttachedToWindow()
|
||||
{
|
||||
updateDirection();
|
||||
super.onAttachedToWindow();
|
||||
if (prefs != null) prefs.addListener(this);
|
||||
if (midnightTimer != null) midnightTimer.addListener(this);
|
||||
}
|
||||
|
||||
private void updateDirection()
|
||||
{
|
||||
int direction = -1;
|
||||
if (shouldReverseCheckmarks()) direction *= -1;
|
||||
if (InterfaceUtils.isLayoutRtl(this)) direction *= -1;
|
||||
setDirection(direction);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow()
|
||||
{
|
||||
@@ -145,6 +151,7 @@ public class HeaderView extends ScrollableChart
|
||||
float width = res.getDimension(R.dimen.checkmarkWidth);
|
||||
float height = res.getDimension(R.dimen.checkmarkHeight);
|
||||
boolean reverse = shouldReverseCheckmarks();
|
||||
boolean isRtl = InterfaceUtils.isLayoutRtl(this);
|
||||
|
||||
day.add(GregorianCalendar.DAY_OF_MONTH, -getDataOffset());
|
||||
float em = paint.measureText("m");
|
||||
@@ -153,9 +160,13 @@ public class HeaderView extends ScrollableChart
|
||||
{
|
||||
rect.set(0, 0, width, height);
|
||||
rect.offset(canvas.getWidth(), 0);
|
||||
|
||||
if(reverse) rect.offset(- (i + 1) * width, 0);
|
||||
else rect.offset((i - buttonCount) * width, 0);
|
||||
|
||||
if (isRtl) rect.set(canvas.getWidth() - rect.right, rect.top,
|
||||
canvas.getWidth() - rect.left, rect.bottom);
|
||||
|
||||
String text = DateUtils.formatHeaderDate(day).toUpperCase();
|
||||
String[] lines = text.split("\n");
|
||||
|
||||
|
||||
@@ -19,20 +19,20 @@
|
||||
|
||||
package org.isoron.uhabits.io;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.content.*;
|
||||
import android.database.*;
|
||||
import android.database.sqlite.*;
|
||||
import android.support.annotation.*;
|
||||
import android.util.*;
|
||||
|
||||
import com.activeandroid.ActiveAndroid;
|
||||
import com.activeandroid.*;
|
||||
|
||||
import org.isoron.uhabits.AppContext;
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.models.*;
|
||||
import org.isoron.uhabits.utils.DatabaseUtils;
|
||||
import org.isoron.uhabits.utils.FileUtils;
|
||||
import org.isoron.uhabits.utils.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.*;
|
||||
|
||||
import javax.inject.*;
|
||||
|
||||
@@ -45,7 +45,8 @@ public class LoopDBImporter extends AbstractImporter
|
||||
private Context context;
|
||||
|
||||
@Inject
|
||||
public LoopDBImporter(@NonNull @AppContext Context context, @NonNull HabitList habits)
|
||||
public LoopDBImporter(@NonNull @AppContext Context context,
|
||||
@NonNull HabitList habits)
|
||||
{
|
||||
super(habits);
|
||||
this.context = context;
|
||||
@@ -59,15 +60,29 @@ public class LoopDBImporter extends AbstractImporter
|
||||
SQLiteDatabase db = SQLiteDatabase.openDatabase(file.getPath(), null,
|
||||
SQLiteDatabase.OPEN_READONLY);
|
||||
|
||||
boolean canHandle = true;
|
||||
|
||||
Cursor c = db.rawQuery(
|
||||
"select count(*) from SQLITE_MASTER where name=? or name=?",
|
||||
new String[]{"Checkmarks", "Repetitions"});
|
||||
new String[]{ "Checkmarks", "Repetitions" });
|
||||
|
||||
boolean result = (c.moveToFirst() && c.getInt(0) == 2);
|
||||
if (!c.moveToFirst() || c.getInt(0) != 2)
|
||||
{
|
||||
Log.w("LoopDBImporter", "Cannot handle file: tables not found");
|
||||
canHandle = false;
|
||||
}
|
||||
|
||||
if (db.getVersion() > BuildConfig.databaseVersion)
|
||||
{
|
||||
Log.w("LoopDBImporter", String.format(
|
||||
"Cannot handle file: incompatible version: %d > %d",
|
||||
db.getVersion(), BuildConfig.databaseVersion));
|
||||
canHandle = false;
|
||||
}
|
||||
|
||||
c.close();
|
||||
db.close();
|
||||
return result;
|
||||
return canHandle;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
|
||||
*
|
||||
* This file is part of Loop Habit Tracker.
|
||||
*
|
||||
* Loop Habit Tracker is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* Loop Habit Tracker is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.isoron.uhabits.models.sqlite;
|
||||
|
||||
public class InvalidDatabaseVersionException extends RuntimeException
|
||||
{
|
||||
}
|
||||
@@ -23,6 +23,7 @@ import android.content.*;
|
||||
import android.preference.*;
|
||||
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.models.*;
|
||||
|
||||
import javax.inject.*;
|
||||
|
||||
@@ -48,7 +49,7 @@ public class WidgetPreferences
|
||||
public long getHabitIdFromWidgetId(int widgetId)
|
||||
{
|
||||
Long habitId = prefs.getLong(getHabitIdKey(widgetId), -1);
|
||||
if (habitId < 0) throw new RuntimeException("widget not found");
|
||||
if (habitId < 0) throw new HabitNotFoundException();
|
||||
|
||||
return habitId;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import android.support.annotation.*;
|
||||
import com.activeandroid.*;
|
||||
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.models.sqlite.*;
|
||||
import org.isoron.uhabits.models.sqlite.records.*;
|
||||
|
||||
import java.io.*;
|
||||
@@ -76,7 +77,16 @@ public abstract class DatabaseUtils
|
||||
RepetitionRecord.class, ScoreRecord.class, StreakRecord.class)
|
||||
.create();
|
||||
|
||||
ActiveAndroid.initialize(dbConfig);
|
||||
try
|
||||
{
|
||||
ActiveAndroid.initialize(dbConfig);
|
||||
}
|
||||
catch (RuntimeException e)
|
||||
{
|
||||
if(e.getMessage().contains("downgrade"))
|
||||
throw new InvalidDatabaseVersionException();
|
||||
else throw e;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("ResultOfMethodCallIgnored")
|
||||
|
||||
@@ -23,6 +23,7 @@ import android.content.*;
|
||||
import android.content.res.*;
|
||||
import android.graphics.*;
|
||||
import android.support.annotation.*;
|
||||
import android.support.v4.view.*;
|
||||
import android.util.*;
|
||||
import android.view.*;
|
||||
import android.widget.*;
|
||||
@@ -67,5 +68,10 @@ public abstract class InterfaceUtils
|
||||
if (child instanceof TextView)
|
||||
((TextView) child).setOnEditorActionListener(listener);
|
||||
}
|
||||
|
||||
public static boolean isLayoutRtl(View view)
|
||||
{
|
||||
return ViewCompat.getLayoutDirection(view) ==
|
||||
ViewCompat.LAYOUT_DIRECTION_RTL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,8 @@ import android.os.*;
|
||||
import android.support.annotation.*;
|
||||
import android.widget.*;
|
||||
|
||||
import com.activeandroid.util.*;
|
||||
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.models.*;
|
||||
import org.isoron.uhabits.preferences.*;
|
||||
@@ -76,8 +78,15 @@ public abstract class BaseWidgetProvider extends AppWidgetProvider
|
||||
|
||||
for (int id : ids)
|
||||
{
|
||||
BaseWidget widget = getWidgetFromId(context, id);
|
||||
widget.delete();
|
||||
try
|
||||
{
|
||||
BaseWidget widget = getWidgetFromId(context, id);
|
||||
widget.delete();
|
||||
}
|
||||
catch (HabitNotFoundException e)
|
||||
{
|
||||
Log.e("BaseWidgetProvider", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -317,6 +317,10 @@
|
||||
<TextView
|
||||
style="@style/About.Item"
|
||||
android:text="Aman Satnami (हिन्दी)"/>
|
||||
|
||||
<TextView
|
||||
style="@style/About.Item"
|
||||
android:text="Niraj Yadav (हिन्दी)"/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
|
||||
@@ -91,6 +91,7 @@
|
||||
<string name="interval_2_hour">2 घंटा</string>
|
||||
<string name="interval_4_hour">4 घंटा</string>
|
||||
<string name="interval_8_hour">8 घंटा</string>
|
||||
<string name="interval_24_hour">24 घंटे</string>
|
||||
<string name="pref_toggle_title">टॉगल पुनरावृत्ति हल्का दबाने से</string>
|
||||
<string name="pref_toggle_description">\"
|
||||
अधिक सुविधाजनक है, लेकिन आकस्मिक टॉगल हो सकता है ।\"</string>
|
||||
@@ -179,7 +180,7 @@ repetitions की संख्या\"</string>
|
||||
इस फ़ाइल में वापस आयात नहीं किया जा सकता है।\"</string>
|
||||
<string name="export_full_backup_summary">ऐसी फाइल्स उत्पन्न करता है जिसमे आपका सारा डेटा रहता है इस फ़ाइल को वापस आयात किया जा सकता है।</string>
|
||||
<string name="bug_report_failed">बग रिपोर्ट जनरेट करने मे असफल</string>
|
||||
<string name="generate_bug_report">बग रिपोर्ट जनरेट करने मे सफल</string>
|
||||
<string name="generate_bug_report">बग रिपोर्ट जनरेट करें</string>
|
||||
<string name="troubleshooting">\"
|
||||
समस्या निवारण\"</string>
|
||||
<string name="help_translate">\"
|
||||
@@ -198,15 +199,26 @@ repetitions की संख्या\"</string>
|
||||
<string name="quarter">तिमाही</string>
|
||||
<string name="year">साल</string>
|
||||
<!-- Middle part of the sentence '1 time in xx days' -->
|
||||
<string name="time_every">समय शुरू</string>
|
||||
<string name="time_every">समय में</string>
|
||||
<string name="every_x_days">\"
|
||||
हर %d दिन\"</string>
|
||||
<string name="every_x_weeks">\"
|
||||
हर %d हफ्ते\"</string>
|
||||
<string name="every_x_months">\"
|
||||
हर %d साल\"</string>
|
||||
हर %d महीने\"</string>
|
||||
<string name="score">स्कोर</string>
|
||||
<string name="reminder_sound">अनुस्मारक ध्वनि</string>
|
||||
<string name="none">\"
|
||||
कोई आवाज नहीं\"</string>
|
||||
<string name="filter">फिल्टर</string>
|
||||
<string name="repair_database">डेटाबेस को रिपेयर करें</string>
|
||||
<string name="database_repaired">डेटाबेस रिपेयर सफल</string>
|
||||
<string name="habit">आदत</string>
|
||||
<string name="sort">सॉर्ट करें</string>
|
||||
<string name="manually">मैन्यूअली</string>
|
||||
<string name="by_name">नाम द्वारा</string>
|
||||
<string name="by_color">रंग द्वारा</string>
|
||||
<string name="by_score">स्कोर से</string>
|
||||
<string name="download">डाउनलोड</string>
|
||||
<string name="export">एक्सपोर्ट करे</string>
|
||||
</resources>
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
~ with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<resources>
|
||||
<string name="app_name">Loop Habit Tracker</string>
|
||||
<string name="main_activity_title">Kebiasaan</string>
|
||||
<string name="action_settings">Pengaturan</string>
|
||||
<string name="edit">Ubah</string>
|
||||
@@ -73,6 +74,7 @@
|
||||
<string name="interval_2_hour">2 jam</string>
|
||||
<string name="interval_4_hour">4 jam</string>
|
||||
<string name="interval_8_hour">8 jam</string>
|
||||
<string name="interval_24_hour">24 jam</string>
|
||||
<string name="pref_toggle_title">Tandai dengan cepat.</string>
|
||||
<string name="pref_toggle_description">Lebih nyaman namun memungkinkan kesalahan.</string>
|
||||
<string name="pref_snooze_interval_title">Durasi tunda sejenak pada pengingat</string>
|
||||
|
||||
Reference in New Issue
Block a user