Merge branch 'hotfix/1.7.1' into dev

pull/276/head
Alinson S. Xavier 9 years ago
commit e6deb1f281

@ -21,8 +21,8 @@
<manifest <manifest
package="org.isoron.uhabits" package="org.isoron.uhabits"
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="27" android:versionCode="28"
android:versionName="1.7.0"> android:versionName="1.7.1">
<uses-permission android:name="android.permission.VIBRATE"/> <uses-permission android:name="android.permission.VIBRATE"/>

@ -21,10 +21,10 @@ package org.isoron.uhabits;
import android.app.*; import android.app.*;
import android.content.*; import android.content.*;
import android.support.annotation.*;
import com.activeandroid.*; import com.activeandroid.*;
import org.isoron.uhabits.models.sqlite.*;
import org.isoron.uhabits.notifications.*; import org.isoron.uhabits.notifications.*;
import org.isoron.uhabits.preferences.*; import org.isoron.uhabits.preferences.*;
import org.isoron.uhabits.tasks.*; import org.isoron.uhabits.tasks.*;
@ -88,7 +88,16 @@ public class HabitsApplication extends Application
if (db.exists()) db.delete(); 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 = component.getWidgetUpdater();
widgetUpdater.startListening(); widgetUpdater.startListening();

@ -20,9 +20,8 @@
package org.isoron.uhabits.activities.common.views; package org.isoron.uhabits.activities.common.views;
import android.os.*; 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 = public static final Parcelable.Creator<BundleSavedState> CREATOR =
new Parcelable.Creator<BundleSavedState>() new Parcelable.Creator<BundleSavedState>()
@ -51,7 +50,7 @@ public class BundleSavedState extends View.BaseSavedState
public BundleSavedState(Parcel source) public BundleSavedState(Parcel source)
{ {
super(source); super(source);
this.bundle = source.readBundle(); this.bundle = source.readBundle(getClass().getClassLoader());
} }
@Override @Override

@ -50,8 +50,6 @@ public class HeaderView extends ScrollableChart
private RectF rect; private RectF rect;
private int maxDataOffset;
public HeaderView(Context context, AttributeSet attrs) public HeaderView(Context context, AttributeSet attrs)
{ {
super(context, attrs); super(context, attrs);
@ -76,7 +74,6 @@ public class HeaderView extends ScrollableChart
Resources res = context.getResources(); Resources res = context.getResources();
setScrollerBucketSize((int) res.getDimension(R.dimen.checkmarkWidth)); setScrollerBucketSize((int) res.getDimension(R.dimen.checkmarkWidth));
setDirection(shouldReverseCheckmarks() ? 1 : -1);
StyledResources sr = new StyledResources(context); StyledResources sr = new StyledResources(context);
paint = new TextPaint(); paint = new TextPaint();
@ -99,7 +96,7 @@ public class HeaderView extends ScrollableChart
@Override @Override
public void onCheckmarkOrderChanged() public void onCheckmarkOrderChanged()
{ {
setDirection(shouldReverseCheckmarks() ? 1 : -1); updateDirection();
postInvalidate(); postInvalidate();
} }
@ -112,11 +109,20 @@ public class HeaderView extends ScrollableChart
@Override @Override
protected void onAttachedToWindow() protected void onAttachedToWindow()
{ {
updateDirection();
super.onAttachedToWindow(); super.onAttachedToWindow();
if (prefs != null) prefs.addListener(this); if (prefs != null) prefs.addListener(this);
if (midnightTimer != null) midnightTimer.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 @Override
protected void onDetachedFromWindow() protected void onDetachedFromWindow()
{ {
@ -145,6 +151,7 @@ public class HeaderView extends ScrollableChart
float width = res.getDimension(R.dimen.checkmarkWidth); float width = res.getDimension(R.dimen.checkmarkWidth);
float height = res.getDimension(R.dimen.checkmarkHeight); float height = res.getDimension(R.dimen.checkmarkHeight);
boolean reverse = shouldReverseCheckmarks(); boolean reverse = shouldReverseCheckmarks();
boolean isRtl = InterfaceUtils.isLayoutRtl(this);
day.add(GregorianCalendar.DAY_OF_MONTH, -getDataOffset()); day.add(GregorianCalendar.DAY_OF_MONTH, -getDataOffset());
float em = paint.measureText("m"); float em = paint.measureText("m");
@ -153,9 +160,13 @@ public class HeaderView extends ScrollableChart
{ {
rect.set(0, 0, width, height); rect.set(0, 0, width, height);
rect.offset(canvas.getWidth(), 0); rect.offset(canvas.getWidth(), 0);
if(reverse) rect.offset(- (i + 1) * width, 0); if(reverse) rect.offset(- (i + 1) * width, 0);
else rect.offset((i - buttonCount) * 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 text = DateUtils.formatHeaderDate(day).toUpperCase();
String[] lines = text.split("\n"); String[] lines = text.split("\n");

@ -19,20 +19,20 @@
package org.isoron.uhabits.io; package org.isoron.uhabits.io;
import android.content.Context; import android.content.*;
import android.database.Cursor; import android.database.*;
import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.*;
import android.support.annotation.NonNull; 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.models.*;
import org.isoron.uhabits.utils.DatabaseUtils; import org.isoron.uhabits.utils.DatabaseUtils;
import org.isoron.uhabits.utils.FileUtils; import org.isoron.uhabits.utils.*;
import java.io.File; import java.io.*;
import java.io.IOException;
import javax.inject.*; import javax.inject.*;
@ -45,7 +45,8 @@ public class LoopDBImporter extends AbstractImporter
private Context context; private Context context;
@Inject @Inject
public LoopDBImporter(@NonNull @AppContext Context context, @NonNull HabitList habits) public LoopDBImporter(@NonNull @AppContext Context context,
@NonNull HabitList habits)
{ {
super(habits); super(habits);
this.context = context; this.context = context;
@ -59,15 +60,29 @@ public class LoopDBImporter extends AbstractImporter
SQLiteDatabase db = SQLiteDatabase.openDatabase(file.getPath(), null, SQLiteDatabase db = SQLiteDatabase.openDatabase(file.getPath(), null,
SQLiteDatabase.OPEN_READONLY); SQLiteDatabase.OPEN_READONLY);
boolean canHandle = true;
Cursor c = db.rawQuery( Cursor c = db.rawQuery(
"select count(*) from SQLITE_MASTER where name=? or name=?", "select count(*) from SQLITE_MASTER where name=? or name=?",
new String[]{"Checkmarks", "Repetitions"}); new String[]{ "Checkmarks", "Repetitions" });
if (!c.moveToFirst() || c.getInt(0) != 2)
{
Log.w("LoopDBImporter", "Cannot handle file: tables not found");
canHandle = false;
}
boolean result = (c.moveToFirst() && c.getInt(0) == 2); 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(); c.close();
db.close(); db.close();
return result; return canHandle;
} }
@Override @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 android.preference.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.models.*;
import javax.inject.*; import javax.inject.*;
@ -48,7 +49,7 @@ public class WidgetPreferences
public long getHabitIdFromWidgetId(int widgetId) public long getHabitIdFromWidgetId(int widgetId)
{ {
Long habitId = prefs.getLong(getHabitIdKey(widgetId), -1); Long habitId = prefs.getLong(getHabitIdKey(widgetId), -1);
if (habitId < 0) throw new RuntimeException("widget not found"); if (habitId < 0) throw new HabitNotFoundException();
return habitId; return habitId;
} }

@ -25,6 +25,7 @@ import android.support.annotation.*;
import com.activeandroid.*; import com.activeandroid.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.models.sqlite.*;
import org.isoron.uhabits.models.sqlite.records.*; import org.isoron.uhabits.models.sqlite.records.*;
import java.io.*; import java.io.*;
@ -76,7 +77,16 @@ public abstract class DatabaseUtils
RepetitionRecord.class, ScoreRecord.class, StreakRecord.class) RepetitionRecord.class, ScoreRecord.class, StreakRecord.class)
.create(); .create();
ActiveAndroid.initialize(dbConfig); try
{
ActiveAndroid.initialize(dbConfig);
}
catch (RuntimeException e)
{
if(e.getMessage().contains("downgrade"))
throw new InvalidDatabaseVersionException();
else throw e;
}
} }
@SuppressWarnings("ResultOfMethodCallIgnored") @SuppressWarnings("ResultOfMethodCallIgnored")

@ -23,6 +23,7 @@ import android.content.*;
import android.content.res.*; import android.content.res.*;
import android.graphics.*; import android.graphics.*;
import android.support.annotation.*; import android.support.annotation.*;
import android.support.v4.view.*;
import android.util.*; import android.util.*;
import android.view.*; import android.view.*;
import android.widget.*; import android.widget.*;
@ -67,5 +68,10 @@ public abstract class InterfaceUtils
if (child instanceof TextView) if (child instanceof TextView)
((TextView) child).setOnEditorActionListener(listener); ((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.support.annotation.*;
import android.widget.*; import android.widget.*;
import com.activeandroid.util.*;
import org.isoron.uhabits.*; import org.isoron.uhabits.*;
import org.isoron.uhabits.models.*; import org.isoron.uhabits.models.*;
import org.isoron.uhabits.preferences.*; import org.isoron.uhabits.preferences.*;
@ -76,8 +78,15 @@ public abstract class BaseWidgetProvider extends AppWidgetProvider
for (int id : ids) for (int id : ids)
{ {
BaseWidget widget = getWidgetFromId(context, id); try
widget.delete(); {
BaseWidget widget = getWidgetFromId(context, id);
widget.delete();
}
catch (HabitNotFoundException e)
{
Log.e("BaseWidgetProvider", e);
}
} }
} }

@ -317,6 +317,10 @@
<TextView <TextView
style="@style/About.Item" style="@style/About.Item"
android:text="Aman Satnami (हिन्दी)"/> android:text="Aman Satnami (हिन्दी)"/>
<TextView
style="@style/About.Item"
android:text="Niraj Yadav (हिन्दी)"/>
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
</ScrollView> </ScrollView>

@ -91,6 +91,7 @@
<string name="interval_2_hour">2 घंटा</string> <string name="interval_2_hour">2 घंटा</string>
<string name="interval_4_hour">4 घंटा</string> <string name="interval_4_hour">4 घंटा</string>
<string name="interval_8_hour">8 घंटा</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_title">टॉगल पुनरावृत्ति हल्का दबाने से</string>
<string name="pref_toggle_description">\" <string name="pref_toggle_description">\"
अधिक सुविधाजनक है, लेकिन आकस्मिक टॉगल हो सकता है ।\"</string> अधिक सुविधाजनक है, लेकिन आकस्मिक टॉगल हो सकता है ।\"</string>
@ -179,7 +180,7 @@ repetitions की संख्या\"</string>
इस फ़ाइल में वापस आयात नहीं किया जा सकता है।\"</string> इस फ़ाइल में वापस आयात नहीं किया जा सकता है।\"</string>
<string name="export_full_backup_summary">ऐसी फाइल्स उत्पन्न करता है जिसमे आपका सारा डेटा रहता है इस फ़ाइल को वापस आयात किया जा सकता है।</string> <string name="export_full_backup_summary">ऐसी फाइल्स उत्पन्न करता है जिसमे आपका सारा डेटा रहता है इस फ़ाइल को वापस आयात किया जा सकता है।</string>
<string name="bug_report_failed">बग रिपोर्ट जनरेट करने मे असफल</string> <string name="bug_report_failed">बग रिपोर्ट जनरेट करने मे असफल</string>
<string name="generate_bug_report">बग रिपोर्ट जनरेट करने मे सफल</string> <string name="generate_bug_report">बग रिपोर्ट जनरेट करें</string>
<string name="troubleshooting">\" <string name="troubleshooting">\"
समस्या निवारण\"</string> समस्या निवारण\"</string>
<string name="help_translate">\" <string name="help_translate">\"
@ -198,15 +199,26 @@ repetitions की संख्या\"</string>
<string name="quarter">तिमाही</string> <string name="quarter">तिमाही</string>
<string name="year">साल</string> <string name="year">साल</string>
<!-- Middle part of the sentence '1 time in xx days' --> <!-- 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">\" <string name="every_x_days">\"
हर %d दिन\"</string> हर %d दिन\"</string>
<string name="every_x_weeks">\" <string name="every_x_weeks">\"
हर %d हफ्ते\"</string> हर %d हफ्ते\"</string>
<string name="every_x_months">\" <string name="every_x_months">\"
हर %d साल\"</string> हर %d महीने\"</string>
<string name="score">स्कोर</string> <string name="score">स्कोर</string>
<string name="reminder_sound">अनुस्मारक ध्वनि</string> <string name="reminder_sound">अनुस्मारक ध्वनि</string>
<string name="none">\" <string name="none">\"
कोई आवाज नहीं\"</string> कोई आवाज नहीं\"</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> </resources>

@ -19,6 +19,7 @@
~ with this program. If not, see <http://www.gnu.org/licenses/>. ~ with this program. If not, see <http://www.gnu.org/licenses/>.
--> -->
<resources> <resources>
<string name="app_name">Loop Habit Tracker</string>
<string name="main_activity_title">Kebiasaan</string> <string name="main_activity_title">Kebiasaan</string>
<string name="action_settings">Pengaturan</string> <string name="action_settings">Pengaturan</string>
<string name="edit">Ubah</string> <string name="edit">Ubah</string>
@ -73,6 +74,7 @@
<string name="interval_2_hour">2 jam</string> <string name="interval_2_hour">2 jam</string>
<string name="interval_4_hour">4 jam</string> <string name="interval_4_hour">4 jam</string>
<string name="interval_8_hour">8 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_title">Tandai dengan cepat.</string>
<string name="pref_toggle_description">Lebih nyaman namun memungkinkan kesalahan.</string> <string name="pref_toggle_description">Lebih nyaman namun memungkinkan kesalahan.</string>
<string name="pref_snooze_interval_title">Durasi tunda sejenak pada pengingat</string> <string name="pref_snooze_interval_title">Durasi tunda sejenak pada pengingat</string>

Loading…
Cancel
Save