- * To use the component, simply add it to your view hierarchy. Then in your
- * {@link android.app.Activity} or {@link android.support.v4.app.Fragment} call
- * {@link #setViewPager(ViewPager)} providing it the ViewPager this layout is being used for.
- *
- * The colors can be customized in two ways. The first and simplest is to provide an array of colors
- * via {@link #setSelectedIndicatorColors(int...)}. The
- * alternative is via the {@link TabColorizer} interface which provides you complete control over
- * which color is used for any individual position.
- *
- * The views used as tabs can be customized by calling {@link #setCustomTabView(int, int)},
- * providing the layout ID of your custom layout.
- */
-public class SlidingTabLayout extends HorizontalScrollView {
- /**
- * Allows complete control over the colors drawn in the tab layout. Set with
- * {@link #setCustomTabColorizer(TabColorizer)}.
- */
- public interface TabColorizer {
-
- /**
- * @return return the color of the indicator used when {@code position} is selected.
- */
- int getIndicatorColor(int position);
-
- }
-
- private static final int TITLE_OFFSET_DIPS = 24;
- private static final int TAB_VIEW_PADDING_DIPS = 16;
- private static final int TAB_VIEW_TEXT_SIZE_SP = 12;
-
- private int mTitleOffset;
-
- private int mTabViewLayoutId;
- private int mTabViewTextViewId;
- private boolean mDistributeEvenly;
-
- private ViewPager mViewPager;
- private SparseArray mContentDescriptions = new SparseArray();
- private ViewPager.OnPageChangeListener mViewPagerPageChangeListener;
-
- private final SlidingTabStrip mTabStrip;
-
- public SlidingTabLayout(Context context) {
- this(context, null);
- }
-
- public SlidingTabLayout(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public SlidingTabLayout(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
-
- // Disable the Scroll Bar
- setHorizontalScrollBarEnabled(false);
- // Make sure that the Tab Strips fills this View
- setFillViewport(true);
-
- mTitleOffset = (int) (TITLE_OFFSET_DIPS * getResources().getDisplayMetrics().density);
-
- mTabStrip = new SlidingTabStrip(context);
- addView(mTabStrip, LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
- }
-
- /**
- * Set the custom {@link TabColorizer} to be used.
- *
- * If you only require simple custmisation then you can use
- * {@link #setSelectedIndicatorColors(int...)} to achieve
- * similar effects.
- */
- public void setCustomTabColorizer(TabColorizer tabColorizer) {
- mTabStrip.setCustomTabColorizer(tabColorizer);
- }
-
- public void setDistributeEvenly(boolean distributeEvenly) {
- mDistributeEvenly = distributeEvenly;
- }
-
- /**
- * Sets the colors to be used for indicating the selected tab. These colors are treated as a
- * circular array. Providing one color will mean that all tabs are indicated with the same color.
- */
- public void setSelectedIndicatorColors(int... colors) {
- mTabStrip.setSelectedIndicatorColors(colors);
- }
-
- /**
- * Set the {@link ViewPager.OnPageChangeListener}. When using {@link SlidingTabLayout} you are
- * required to set any {@link ViewPager.OnPageChangeListener} through this method. This is so
- * that the layout can update it's scroll position correctly.
- *
- * @see ViewPager#setOnPageChangeListener(ViewPager.OnPageChangeListener)
- */
- public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener) {
- mViewPagerPageChangeListener = listener;
- }
-
- /**
- * Set the custom layout to be inflated for the tab views.
- *
- * @param layoutResId Layout id to be inflated
- * @param textViewId id of the {@link TextView} in the inflated view
- */
- public void setCustomTabView(int layoutResId, int textViewId) {
- mTabViewLayoutId = layoutResId;
- mTabViewTextViewId = textViewId;
- }
-
- /**
- * Sets the associated view pager. Note that the assumption here is that the pager content
- * (number of tabs and tab titles) does not change after this call has been made.
- */
- public void setViewPager(ViewPager viewPager) {
- mTabStrip.removeAllViews();
-
- mViewPager = viewPager;
- if (viewPager != null) {
- viewPager.setOnPageChangeListener(new InternalViewPagerListener());
- populateTabStrip();
- }
- }
-
- /**
- * Create a default view to be used for tabs. This is called if a custom tab view is not set via
- * {@link #setCustomTabView(int, int)}.
- */
- protected TextView createDefaultTabView(Context context) {
- TextView textView = new TextView(context);
- textView.setGravity(Gravity.CENTER);
- textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, TAB_VIEW_TEXT_SIZE_SP);
- textView.setTypeface(Typeface.DEFAULT_BOLD);
- textView.setLayoutParams(new LinearLayout.LayoutParams(
- ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
-
- TypedValue outValue = new TypedValue();
- getContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground,
- outValue, true);
- textView.setBackgroundResource(outValue.resourceId);
- textView.setAllCaps(true);
-
- int padding = (int) (TAB_VIEW_PADDING_DIPS * getResources().getDisplayMetrics().density);
- textView.setPadding(padding, padding, padding, padding);
-
- return textView;
- }
-
- private void populateTabStrip() {
- final PagerAdapter adapter = mViewPager.getAdapter();
- final View.OnClickListener tabClickListener = new TabClickListener();
-
- for (int i = 0; i < adapter.getCount(); i++) {
- View tabView = null;
- TextView tabTitleView = null;
-
- if (mTabViewLayoutId != 0) {
- // If there is a custom tab view layout id set, try and inflate it
- tabView = LayoutInflater.from(getContext()).inflate(mTabViewLayoutId, mTabStrip,
- false);
- tabTitleView = (TextView) tabView.findViewById(mTabViewTextViewId);
- }
-
- if (tabView == null) {
- tabView = createDefaultTabView(getContext());
- }
-
- if (tabTitleView == null && TextView.class.isInstance(tabView)) {
- tabTitleView = (TextView) tabView;
- }
-
- if (mDistributeEvenly) {
- LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) tabView.getLayoutParams();
- lp.width = 0;
- lp.weight = 1;
- }
-
- tabTitleView.setText(adapter.getPageTitle(i));
- tabView.setOnClickListener(tabClickListener);
- String desc = mContentDescriptions.get(i, null);
- if (desc != null) {
- tabView.setContentDescription(desc);
- }
-
- mTabStrip.addView(tabView);
- if (i == mViewPager.getCurrentItem()) {
- tabView.setSelected(true);
- }
- }
- }
-
- public void setContentDescription(int i, String desc) {
- mContentDescriptions.put(i, desc);
- }
-
- @Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
-
- if (mViewPager != null) {
- scrollToTab(mViewPager.getCurrentItem(), 0);
- }
- }
-
- private void scrollToTab(int tabIndex, int positionOffset) {
- final int tabStripChildCount = mTabStrip.getChildCount();
- if (tabStripChildCount == 0 || tabIndex < 0 || tabIndex >= tabStripChildCount) {
- return;
- }
-
- View selectedChild = mTabStrip.getChildAt(tabIndex);
- if (selectedChild != null) {
- int targetScrollX = selectedChild.getLeft() + positionOffset;
-
- if (tabIndex > 0 || positionOffset > 0) {
- // If we're not at the first child and are mid-scroll, make sure we obey the offset
- targetScrollX -= mTitleOffset;
- }
-
- scrollTo(targetScrollX, 0);
- }
- }
-
- private class InternalViewPagerListener implements ViewPager.OnPageChangeListener {
- private int mScrollState;
-
- @Override
- public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
- int tabStripChildCount = mTabStrip.getChildCount();
- if ((tabStripChildCount == 0) || (position < 0) || (position >= tabStripChildCount)) {
- return;
- }
-
- mTabStrip.onViewPagerPageChanged(position, positionOffset);
-
- View selectedTitle = mTabStrip.getChildAt(position);
- int extraOffset = (selectedTitle != null)
- ? (int) (positionOffset * selectedTitle.getWidth())
- : 0;
- scrollToTab(position, extraOffset);
-
- if (mViewPagerPageChangeListener != null) {
- mViewPagerPageChangeListener.onPageScrolled(position, positionOffset,
- positionOffsetPixels);
- }
- }
-
- @Override
- public void onPageScrollStateChanged(int state) {
- mScrollState = state;
-
- if (mViewPagerPageChangeListener != null) {
- mViewPagerPageChangeListener.onPageScrollStateChanged(state);
- }
- }
-
- @Override
- public void onPageSelected(int position) {
- if (mScrollState == ViewPager.SCROLL_STATE_IDLE) {
- mTabStrip.onViewPagerPageChanged(position, 0f);
- scrollToTab(position, 0);
- }
- for (int i = 0; i < mTabStrip.getChildCount(); i++) {
- mTabStrip.getChildAt(i).setSelected(position == i);
- }
- if (mViewPagerPageChangeListener != null) {
- mViewPagerPageChangeListener.onPageSelected(position);
- }
- }
-
- }
-
- private class TabClickListener implements View.OnClickListener {
- @Override
- public void onClick(View v) {
- for (int i = 0; i < mTabStrip.getChildCount(); i++) {
- if (v == mTabStrip.getChildAt(i)) {
- mViewPager.setCurrentItem(i);
- return;
- }
- }
- }
- }
-
-}
\ No newline at end of file
diff --git a/Alkitab/src/main/java/com/google/samples/apps/iosched/ui/widget/SlidingTabStrip.java b/Alkitab/src/main/java/com/google/samples/apps/iosched/ui/widget/SlidingTabStrip.java
deleted file mode 100644
index c391593b3..000000000
--- a/Alkitab/src/main/java/com/google/samples/apps/iosched/ui/widget/SlidingTabStrip.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright 2014 Google Inc. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.samples.apps.iosched.ui.widget;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.util.AttributeSet;
-import android.util.TypedValue;
-import android.view.View;
-import android.widget.LinearLayout;
-
-class SlidingTabStrip extends LinearLayout {
-
- private static final int DEFAULT_BOTTOM_BORDER_THICKNESS_DIPS = 0;
- private static final byte DEFAULT_BOTTOM_BORDER_COLOR_ALPHA = 0x26;
- private static final int SELECTED_INDICATOR_THICKNESS_DIPS = 3;
- private static final int DEFAULT_SELECTED_INDICATOR_COLOR = 0xFF33B5E5;
-
- private final int mBottomBorderThickness;
- private final Paint mBottomBorderPaint;
-
- private final int mSelectedIndicatorThickness;
- private final Paint mSelectedIndicatorPaint;
-
- private final int mDefaultBottomBorderColor;
-
- private int mSelectedPosition;
- private float mSelectionOffset;
-
- private SlidingTabLayout.TabColorizer mCustomTabColorizer;
- private final SimpleTabColorizer mDefaultTabColorizer;
-
- SlidingTabStrip(Context context) {
- this(context, null);
- }
-
- SlidingTabStrip(Context context, AttributeSet attrs) {
- super(context, attrs);
- setWillNotDraw(false);
-
- final float density = getResources().getDisplayMetrics().density;
-
- TypedValue outValue = new TypedValue();
- context.getTheme().resolveAttribute(android.R.attr.colorForeground, outValue, true);
- final int themeForegroundColor = outValue.data;
-
- mDefaultBottomBorderColor = setColorAlpha(themeForegroundColor,
- DEFAULT_BOTTOM_BORDER_COLOR_ALPHA);
-
- mDefaultTabColorizer = new SimpleTabColorizer();
- mDefaultTabColorizer.setIndicatorColors(DEFAULT_SELECTED_INDICATOR_COLOR);
-
- mBottomBorderThickness = (int) (DEFAULT_BOTTOM_BORDER_THICKNESS_DIPS * density);
- mBottomBorderPaint = new Paint();
- mBottomBorderPaint.setColor(mDefaultBottomBorderColor);
-
- mSelectedIndicatorThickness = (int) (SELECTED_INDICATOR_THICKNESS_DIPS * density);
- mSelectedIndicatorPaint = new Paint();
- }
-
- void setCustomTabColorizer(SlidingTabLayout.TabColorizer customTabColorizer) {
- mCustomTabColorizer = customTabColorizer;
- invalidate();
- }
-
- void setSelectedIndicatorColors(int... colors) {
- // Make sure that the custom colorizer is removed
- mCustomTabColorizer = null;
- mDefaultTabColorizer.setIndicatorColors(colors);
- invalidate();
- }
-
- void onViewPagerPageChanged(int position, float positionOffset) {
- mSelectedPosition = position;
- mSelectionOffset = positionOffset;
- invalidate();
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- final int height = getHeight();
- final int childCount = getChildCount();
- final SlidingTabLayout.TabColorizer tabColorizer = mCustomTabColorizer != null
- ? mCustomTabColorizer
- : mDefaultTabColorizer;
-
- // Thick colored underline below the current selection
- if (childCount > 0) {
- View selectedTitle = getChildAt(mSelectedPosition);
- int left = selectedTitle.getLeft();
- int right = selectedTitle.getRight();
- int color = tabColorizer.getIndicatorColor(mSelectedPosition);
-
- if (mSelectionOffset > 0f && mSelectedPosition < (getChildCount() - 1)) {
- int nextColor = tabColorizer.getIndicatorColor(mSelectedPosition + 1);
- if (color != nextColor) {
- color = blendColors(nextColor, color, mSelectionOffset);
- }
-
- // Draw the selection partway between the tabs
- View nextTitle = getChildAt(mSelectedPosition + 1);
- left = (int) (mSelectionOffset * nextTitle.getLeft() +
- (1.0f - mSelectionOffset) * left);
- right = (int) (mSelectionOffset * nextTitle.getRight() +
- (1.0f - mSelectionOffset) * right);
- }
-
- mSelectedIndicatorPaint.setColor(color);
-
- canvas.drawRect(left, height - mSelectedIndicatorThickness, right,
- height, mSelectedIndicatorPaint);
- }
-
- // Thin underline along the entire bottom edge
- canvas.drawRect(0, height - mBottomBorderThickness, getWidth(), height, mBottomBorderPaint);
- }
-
- /**
- * Set the alpha value of the {@code color} to be the given {@code alpha} value.
- */
- private static int setColorAlpha(int color, byte alpha) {
- return Color.argb(alpha, Color.red(color), Color.green(color), Color.blue(color));
- }
-
- /**
- * Blend {@code color1} and {@code color2} using the given ratio.
- *
- * @param ratio of which to blend. 1.0 will return {@code color1}, 0.5 will give an even blend,
- * 0.0 will return {@code color2}.
- */
- private static int blendColors(int color1, int color2, float ratio) {
- final float inverseRation = 1f - ratio;
- float r = (Color.red(color1) * ratio) + (Color.red(color2) * inverseRation);
- float g = (Color.green(color1) * ratio) + (Color.green(color2) * inverseRation);
- float b = (Color.blue(color1) * ratio) + (Color.blue(color2) * inverseRation);
- return Color.rgb((int) r, (int) g, (int) b);
- }
-
- private static class SimpleTabColorizer implements SlidingTabLayout.TabColorizer {
- private int[] mIndicatorColors;
-
- @Override
- public final int getIndicatorColor(int position) {
- return mIndicatorColors[position % mIndicatorColors.length];
- }
-
- void setIndicatorColors(int... colors) {
- mIndicatorColors = colors;
- }
- }
-}
\ No newline at end of file
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/App.java b/Alkitab/src/main/java/yuku/alkitab/base/App.java
index c122569e6..d09dcdabf 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/App.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/App.java
@@ -3,9 +3,9 @@
import android.content.Context;
import android.content.res.Configuration;
import android.os.Build;
-import android.preference.PreferenceManager;
import android.support.multidex.MultiDex;
import android.support.v4.content.LocalBroadcastManager;
+import android.support.v7.preference.PreferenceManager;
import android.util.Log;
import android.view.ViewConfiguration;
import com.google.android.gms.analytics.GoogleAnalytics;
@@ -14,8 +14,10 @@
import com.google.gson.Gson;
import com.squareup.leakcanary.LeakCanary;
import com.squareup.okhttp.Call;
+import com.squareup.okhttp.Interceptor;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
+import com.squareup.okhttp.internal.Version;
import yuku.afw.storage.Preferences;
import yuku.alkitab.base.model.SyncShadow;
import yuku.alkitab.base.model.VersionImpl;
@@ -27,6 +29,7 @@
import yuku.alkitabfeedback.FeedbackSender;
import yuku.alkitabintegration.display.Launcher;
import yuku.kirimfidbek.CrashReporter;
+import yuku.stethoshim.StethoShim;
import java.io.IOException;
import java.lang.reflect.Field;
@@ -48,10 +51,29 @@ enum OkHttpClientWrapper {
OkHttpClient longTimeoutClient = new OkHttpClient();
{
+ final Interceptor userAgent = chain -> {
+ final Request originalRequest = chain.request();
+ final Request requestWithUserAgent = originalRequest.newBuilder()
+ .removeHeader("User-Agent")
+ .addHeader("User-Agent", Version.userAgent() + " " + App.context.getPackageName() + "/" + App.getVersionName())
+ .build();
+ return chain.proceed(requestWithUserAgent);
+ };
+
+ defaultClient.networkInterceptors().add(userAgent);
+ longTimeoutClient.networkInterceptors().add(userAgent);
+ }
+
+ { // init longTimeoutClient
longTimeoutClient.setConnectTimeout(300, TimeUnit.SECONDS);
longTimeoutClient.setReadTimeout(300, TimeUnit.SECONDS);
longTimeoutClient.setWriteTimeout(600, TimeUnit.SECONDS);
}
+
+ { // init stetho interceptor
+ StethoShim.addNetworkInterceptor(defaultClient);
+ StethoShim.addNetworkInterceptor(longTimeoutClient);
+ }
}
enum GsonWrapper {
@@ -98,6 +120,10 @@ public static OkHttpClient getLongTimeoutOkHttpClient() {
{ // LeakCanary, also we need the Application instance.
LeakCanary.install(this);
}
+
+ { // Stetho call through proxy
+ StethoShim.initializeWithDefaults(this);
+ }
}
public synchronized static void staticInit() {
@@ -111,10 +137,15 @@ public synchronized static void staticInit() {
final FeedbackSender fs = FeedbackSender.getInstance(context);
fs.trySend();
- PreferenceManager.setDefaultValues(context, R.xml.settings_display, false);
- PreferenceManager.setDefaultValues(context, R.xml.settings_usage, false);
- PreferenceManager.setDefaultValues(context, R.xml.secret_settings, false);
- PreferenceManager.setDefaultValues(context, R.xml.sync_settings, false);
+ for (final int preferenceResId : new int[]{
+ R.xml.settings_display,
+ R.xml.settings_usage,
+ R.xml.settings_copy_share,
+ R.xml.secret_settings,
+ R.xml.sync_settings,
+ }) {
+ PreferenceManager.setDefaultValues(context, preferenceResId, false);
+ }
updateConfigurationWithPreferencesLocale();
@@ -187,7 +218,7 @@ private static Locale getLocaleFromPreferences() {
@Override public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
- Log.d(TAG, "@@onConfigurationChanged: config changed to: " + newConfig); //$NON-NLS-1$
+ Log.d(TAG, "@@onConfigurationChanged: config changed to: " + newConfig);
updateConfigurationWithPreferencesLocale();
}
@@ -195,7 +226,7 @@ public static void updateConfigurationWithPreferencesLocale() {
final Configuration config = context.getResources().getConfiguration();
final Locale locale = getLocaleFromPreferences();
if (!U.equals(config.locale.getLanguage(), locale.getLanguage()) || !U.equals(config.locale.getCountry(), locale.getCountry())) {
- Log.d(TAG, "@@updateConfigurationWithPreferencesLocale: locale will be updated to: " + locale); //$NON-NLS-1$
+ Log.d(TAG, "@@updateConfigurationWithPreferencesLocale: locale will be updated to: " + locale);
config.locale = locale;
context.getResources().updateConfiguration(config, null);
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/IsiActivity.java b/Alkitab/src/main/java/yuku/alkitab/base/IsiActivity.java
index 33e698fc6..a0a669879 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/IsiActivity.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/IsiActivity.java
@@ -11,6 +11,7 @@
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.database.Cursor;
+import android.graphics.Point;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.nfc.NdefMessage;
@@ -18,7 +19,6 @@
import android.nfc.NfcAdapter;
import android.os.Build;
import android.os.Bundle;
-import android.os.Environment;
import android.os.Parcelable;
import android.support.design.widget.Snackbar;
import android.support.v4.app.FragmentManager;
@@ -38,13 +38,13 @@
import android.text.style.URLSpan;
import android.util.Log;
import android.util.SparseBooleanArray;
-import android.util.TypedValue;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.ImageButton;
@@ -67,7 +67,6 @@
import yuku.alkitab.base.ac.SearchActivity;
import yuku.alkitab.base.ac.SettingsActivity;
import yuku.alkitab.base.ac.ShareActivity;
-import yuku.alkitab.base.ac.YukuAlkitabImportOfferActivity;
import yuku.alkitab.base.ac.base.BaseLeftDrawerActivity;
import yuku.alkitab.base.config.AppConfig;
import yuku.alkitab.base.dialog.ProgressMarkListDialog;
@@ -106,6 +105,7 @@
import yuku.alkitab.base.widget.VerseInlineLinkSpan;
import yuku.alkitab.base.widget.VerseRenderer;
import yuku.alkitab.base.widget.VersesView;
+import yuku.alkitab.debug.BuildConfig;
import yuku.alkitab.debug.R;
import yuku.alkitab.model.Book;
import yuku.alkitab.model.FootnoteEntry;
@@ -119,14 +119,11 @@
import yuku.alkitab.util.IntArrayList;
import yuku.devoxx.flowlayout.FlowLayout;
-import java.io.File;
-import java.io.FilenameFilter;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Locale;
-import java.util.regex.Matcher;
import static yuku.alkitab.base.util.Literals.Array;
@@ -175,7 +172,7 @@ public void onFloaterDragComplete(final float screenX, final float screenY) {
final Floater.Listener floater_listener = new Floater.Listener() {
@Override
public void onSelectComplete(final int ari) {
- jumpToAri(ari, false);
+ jumpToAri(ari);
history.add(ari);
}
};
@@ -273,7 +270,7 @@ public void onTwofingerEnd(final TwofingerLinearLayout.Mode mode) {
LeftDrawer.Text leftDrawer;
FrameLayout overlayContainer;
- View root;
+ ViewGroup root;
Toolbar toolbar;
VersesView lsSplit0;
VersesView lsSplit1;
@@ -310,7 +307,7 @@ public void onTwofingerEnd(final TwofingerLinearLayout.Mode mode) {
}
} else if (data instanceof Integer) {
final int ari = (Integer) data;
- jumpToAri(ari, false);
+ jumpToAri(ari);
history.add(ari);
}
};
@@ -369,6 +366,30 @@ public void onPositive(final MaterialDialog dialog) {
}
};
+ final ViewTreeObserver.OnGlobalLayoutListener splitRoot_globalLayout = new ViewTreeObserver.OnGlobalLayoutListener() {
+ Point lastSize;
+
+ @Override
+ public void onGlobalLayout() {
+ if (lastSize != null && lastSize.x == splitRoot.getWidth() && lastSize.y == splitRoot.getHeight()) {
+ return; // no need to layout now
+ }
+
+ if (activeSplitVersion == null) {
+ return; // we are not splitting
+ }
+
+ configureSplitSizes();
+
+ if (lastSize == null) {
+ lastSize = new Point();
+ }
+ lastSize.x = splitRoot.getWidth();
+ lastSize.y = splitRoot.getHeight();
+ }
+
+ };
+
static class IntentResult {
public int ari;
public boolean selectVerse;
@@ -425,9 +446,19 @@ public void onReceive(final Context context, final Intent intent) {
lsSplit1 = V.get(this, R.id.lsSplit1);
tSplitEmpty = V.get(this, R.id.tSplitEmpty);
splitRoot = V.get(this, R.id.splitRoot);
+ splitRoot.getViewTreeObserver().addOnGlobalLayoutListener(splitRoot_globalLayout);
+
splitHandleButton = V.get(this, R.id.splitHandleButton);
floater = V.get(this, R.id.floater);
+ // If layout is changed, updateToolbarLocation must be updated as well. This will be called in DEBUG to make sure
+ // updateToolbarLocation is also updated when layout is updated.
+ if (BuildConfig.DEBUG) {
+ if (root.getChildCount() != 2 || root.getChildAt(0).getId() != R.id.toolbar || root.getChildAt(1).getId() != R.id.splitRoot) {
+ throw new RuntimeException("Layout changed and this is no longer compatible with updateToolbarLocation");
+ }
+ }
+
updateToolbarLocation();
lsSplit0.setName("lsSplit0");
@@ -560,24 +591,24 @@ public void onReceive(final Context context, final Intent intent) {
if (selectVerse) {
for (int i = 0; i < selectVerseCount; i++) {
final int verse_1 = Ari.toVerse(openingAri) + i;
- lsSplit0.setVerseSelected(verse_1, true);
+ callAttentionForVerseToBothSplits(verse_1);
}
}
App.getLbm().registerReceiver(reloadAttributeMapReceiver, new IntentFilter(ACTION_ATTRIBUTE_MAP_CHANGED));
- if (!U.equals(getPackageName(), "yuku.alkitab") /* prevent self-import */
- && !U.equals(getPackageName(), "yuku.alkitab.kjv") /* prevent self-import */
- && Preferences.getInt(Prefkey.stop_import_yuku_alkitab_backups, 0) == 0
- && thereIsYukuAlkitabBackupFiles()) {
- startActivity(YukuAlkitabImportOfferActivity.createIntent());
- }
-
Announce.checkAnnouncements();
App.getLbm().registerReceiver(needsRestartReceiver, new IntentFilter(ACTION_NEEDS_RESTART));
}
+ void callAttentionForVerseToBothSplits(final int verse_1) {
+ lsSplit0.callAttentionForVerse(verse_1);
+ if (activeSplitVersion != null) {
+ lsSplit1.callAttentionForVerse(verse_1);
+ }
+ }
+
final BroadcastReceiver needsRestartReceiver = new BroadcastReceiver() {
@Override
public void onReceive(final Context context, final Intent intent) {
@@ -585,23 +616,6 @@ public void onReceive(final Context context, final Intent intent) {
}
};
- private boolean thereIsYukuAlkitabBackupFiles() {
- final File dir = new File(Environment.getExternalStorageDirectory(), "bible");
- if (!dir.exists()) return false;
-
- final File[] files = dir.listFiles(new FilenameFilter() {
- final Matcher m = YukuAlkitabImportOfferActivity.getBackupFilenameMatcher();
-
- @Override
- public boolean accept(final File dir, final String filename) {
- m.reset(filename);
- return m.matches();
- }
- });
-
- return files != null && files.length != 0;
- }
-
@Override protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
@@ -635,13 +649,15 @@ private IntentResult processIntent(Intent intent, String via) {
}
}
- if (Build.VERSION.SDK_INT >= 14) {
+ {
final IntentResult result = tryGetIntentResultFromBeam(intent);
if (result != null) return result;
}
- final IntentResult result = tryGetIntentResultFromView(intent);
- if (result != null) return result;
+ {
+ final IntentResult result = tryGetIntentResultFromView(intent);
+ if (result != null) return result;
+ }
return null;
}
@@ -671,7 +687,7 @@ private IntentResult tryGetIntentResultFromView(Intent intent) {
int lid = intent.getIntExtra("lid", 0);
int ari = LidToAri.lidToAri(lid);
if (ari != 0) {
- jumpToAri(ari, true);
+ jumpToAri(ari);
history.add(ari);
final IntentResult res = new IntentResult(ari);
res.selectVerse = selectVerse;
@@ -695,11 +711,11 @@ private void initNfcIfAvailable() {
nfcAdapter.setNdefPushMessageCallback(event -> {
JSONObject obj = new JSONObject();
try {
- obj.put("ari", Ari.encode(IsiActivity.this.activeBook.bookId, IsiActivity.this.chapter_1, lsSplit0.getVerseBasedOnScroll())); //$NON-NLS-1$
+ obj.put("ari", Ari.encode(IsiActivity.this.activeBook.bookId, IsiActivity.this.chapter_1, lsSplit0.getVerseBasedOnScroll()));
} catch (JSONException e) { // won't happen
}
byte[] payload = obj.toString().getBytes();
- NdefRecord record = new NdefRecord(NdefRecord.TNF_MIME_MEDIA, "application/vnd.yuku.alkitab.nfc.beam".getBytes(), new byte[0], payload); //$NON-NLS-1$
+ NdefRecord record = new NdefRecord(NdefRecord.TNF_MIME_MEDIA, "application/vnd.yuku.alkitab.nfc.beam".getBytes(), new byte[0], payload);
return new NdefMessage(new NdefRecord[] {
record,
NdefRecord.createApplicationRecord(getPackageName()),
@@ -727,9 +743,9 @@ private void enableNfcForegroundDispatchIfAvailable() {
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, IsiActivity.class).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
try {
- ndef.addDataType("application/vnd.yuku.alkitab.nfc.beam"); //$NON-NLS-1$
+ ndef.addDataType("application/vnd.yuku.alkitab.nfc.beam");
} catch (IntentFilter.MalformedMimeTypeException e) {
- throw new RuntimeException("fail mime type", e); //$NON-NLS-1$
+ throw new RuntimeException("fail mime type", e);
}
IntentFilter[] intentFiltersArray = new IntentFilter[] {ndef, };
nfcAdapter.enableForegroundDispatch(this, pendingIntent, intentFiltersArray, null);
@@ -752,12 +768,12 @@ private IntentResult tryGetIntentResultFromBeam(Intent intent) {
String json = new String(records[0].getPayload());
try {
JSONObject obj = new JSONObject(json);
- final int ari = obj.optInt("ari", -1); //$NON-NLS-1$
+ final int ari = obj.optInt("ari", -1);
if (ari == -1) return null;
return new IntentResult(ari);
} catch (JSONException e) {
- Log.e(TAG, "Malformed json from nfc", e); //$NON-NLS-1$
+ Log.e(TAG, "Malformed json from nfc", e);
return null;
}
}
@@ -898,7 +914,7 @@ int jumpTo(String reference) {
return 0;
}
- Log.d(TAG, "going to jump to " + reference); //$NON-NLS-1$
+ Log.d(TAG, "going to jump to " + reference);
Jumper jumper = new Jumper(reference);
if (! jumper.getParseSucceeded()) {
@@ -941,7 +957,7 @@ int jumpTo(String reference) {
/**
* Jump to a given ari
*/
- void jumpToAri(final int ari, final boolean selectVerse) {
+ void jumpToAri(final int ari) {
if (ari == 0) return;
final int bookId = Ari.toBook(ari);
@@ -955,11 +971,9 @@ void jumpToAri(final int ari, final boolean selectVerse) {
this.activeBook = book;
final int ari_cv = display(Ari.toChapter(ari), Ari.toVerse(ari));
- if (selectVerse) {
- // select the verse only if the displayed verse is equal to the requested verse
- if (ari == Ari.encode(this.activeBook.bookId, ari_cv)) {
- lsSplit0.setVerseSelected(Ari.toVerse(ari), true);
- }
+ // call attention to the verse only if the displayed verse is equal to the requested verse
+ if (ari == Ari.encode(this.activeBook.bookId, ari_cv)) {
+ callAttentionForVerseToBothSplits(Ari.toVerse(ari));
}
}
@@ -1135,15 +1149,15 @@ void bGoto_longClick() {
new MaterialDialog.Builder(this)
.adapter(historyAdapter, (materialDialog, view, position, charSequence) -> {
materialDialog.dismiss();
- int ari = history.getAri(position);
- jumpToAri(ari, true);
+ final int ari = history.getAri(position);
+ jumpToAri(ari);
history.add(ari);
Preferences.setBoolean(Prefkey.history_button_understood, true);
})
.autoDismiss(true)
.show();
} else {
- Toast.makeText(this, R.string.recentverses_not_available, Toast.LENGTH_SHORT).show();
+ Snackbar.make(root, R.string.recentverses_not_available, Snackbar.LENGTH_SHORT).show();
}
}
@@ -1286,31 +1300,21 @@ void updateToolbarLocation() {
// - not fullscreen, toolbar at bottom
// - not fullscreen, toolbar at top
- final FrameLayout.LayoutParams lp_root = (FrameLayout.LayoutParams) root.getLayoutParams();
+ // root contains exactly 2 children: toolbar and splitRoot. This is checked in DEBUG in onCreate.
+ // Need to move toolbar and splitRoot in order to accomplish this.
- if (fullScreen) {
- lp_root.topMargin = 0;
- lp_root.bottomMargin = 0;
- } else {
- final TypedValue tv = new TypedValue();
- getTheme().resolveAttribute(R.attr.actionBarSize, tv, true);
- final int actionBarSize = TypedValue.complexToDimensionPixelSize(tv.data, getResources().getDisplayMetrics());
- final FrameLayout.LayoutParams lp_toolbar = (FrameLayout.LayoutParams) toolbar.getLayoutParams();
+ if (!fullScreen) {
+ root.removeView(toolbar);
+ root.removeView(splitRoot);
if (Preferences.getBoolean(R.string.pref_bottomToolbarOnText_key, R.bool.pref_bottomToolbarOnText_default)) {
- lp_toolbar.gravity = Gravity.BOTTOM;
- lp_root.topMargin = 0;
- lp_root.bottomMargin = actionBarSize;
+ root.addView(splitRoot);
+ root.addView(toolbar);
} else {
- lp_toolbar.gravity = Gravity.NO_GRAVITY;
- lp_root.topMargin = actionBarSize;
- lp_root.bottomMargin = 0;
+ root.addView(toolbar);
+ root.addView(splitRoot);
}
-
- toolbar.setLayoutParams(lp_toolbar);
}
-
- root.setLayoutParams(lp_root);
}
@Override
@@ -1401,62 +1405,67 @@ void openSplitDisplay() {
return; // it's already split, no need to do anything
}
- // do it on after the layout pass
- overlayContainer.requestLayout();
- overlayContainer.post(() -> {
- splitHandleButton.setVisibility(View.VISIBLE);
+ configureSplitSizes();
- final int splitHandleThickness = getResources().getDimensionPixelSize(R.dimen.split_handle_thickness);
- if (splitHandleButton.getOrientation() == LabeledSplitHandleButton.Orientation.vertical) {
- splitRoot.setOrientation(LinearLayout.VERTICAL);
+ bVersion.setVisibility(View.GONE);
+ if (actionMode != null) actionMode.invalidate();
+ leftDrawer.getHandle().setSplitVersion(true);
+ }
- final int totalHeight = splitRoot.getHeight();
- final int masterHeight = totalHeight / 2 - splitHandleThickness / 2;
+ void configureSplitSizes() {
+ splitHandleButton.setVisibility(View.VISIBLE);
- { // divide by 2 the screen space
- final ViewGroup.LayoutParams lp = lsSplit0.getLayoutParams();
- lp.width = ViewGroup.LayoutParams.MATCH_PARENT;
- lp.height = masterHeight;
- lsSplit0.setLayoutParams(lp);
- }
+ float prop = Preferences.getFloat(Prefkey.lastSplitProp, Float.MIN_VALUE);
+ if (prop == Float.MIN_VALUE || prop < 0.f || prop > 1.f) {
+ prop = 0.5f; // guard against invalid values
+ }
- // no need to set height, because it has been set to match_parent, so it takes the remaining space.
- lsSplit1.setVisibility(View.VISIBLE);
+ final int splitHandleThickness = getResources().getDimensionPixelSize(R.dimen.split_handle_thickness);
+ if (splitHandleButton.getOrientation() == LabeledSplitHandleButton.Orientation.vertical) {
+ splitRoot.setOrientation(LinearLayout.VERTICAL);
- {
- final ViewGroup.LayoutParams lp = splitHandleButton.getLayoutParams();
- lp.width = ViewGroup.LayoutParams.MATCH_PARENT;
- lp.height = splitHandleThickness;
- splitHandleButton.setLayoutParams(lp);
- }
- } else {
- splitRoot.setOrientation(LinearLayout.HORIZONTAL);
+ final int totalHeight = splitRoot.getHeight();
+ final int masterHeight = (int) ((totalHeight - splitHandleThickness) * prop);
- final int totalWidth = splitRoot.getWidth();
- final int masterWidth = totalWidth / 2 - splitHandleThickness / 2;
+ { // divide the screen space
+ final ViewGroup.LayoutParams lp = lsSplit0.getLayoutParams();
+ lp.width = ViewGroup.LayoutParams.MATCH_PARENT;
+ lp.height = masterHeight;
+ lsSplit0.setLayoutParams(lp);
+ }
- { // divide by 2 the screen space
- final ViewGroup.LayoutParams lp = lsSplit0.getLayoutParams();
- lp.width = masterWidth;
- lp.height = ViewGroup.LayoutParams.MATCH_PARENT;
- lsSplit0.setLayoutParams(lp);
- }
+ // no need to set height, because it has been set to match_parent, so it takes the remaining space.
+ lsSplit1.setVisibility(View.VISIBLE);
+
+ {
+ final ViewGroup.LayoutParams lp = splitHandleButton.getLayoutParams();
+ lp.width = ViewGroup.LayoutParams.MATCH_PARENT;
+ lp.height = splitHandleThickness;
+ splitHandleButton.setLayoutParams(lp);
+ }
+ } else {
+ splitRoot.setOrientation(LinearLayout.HORIZONTAL);
- // no need to set width, because it has been set to match_parent, so it takes the remaining space.
- lsSplit1.setVisibility(View.VISIBLE);
+ final int totalWidth = splitRoot.getWidth();
+ final int masterWidth = (int) ((totalWidth - splitHandleThickness) * prop);
- {
- final ViewGroup.LayoutParams lp = splitHandleButton.getLayoutParams();
- lp.width = splitHandleThickness;
- lp.height = ViewGroup.LayoutParams.MATCH_PARENT;
- splitHandleButton.setLayoutParams(lp);
- }
+ { // divide the screen space
+ final ViewGroup.LayoutParams lp = lsSplit0.getLayoutParams();
+ lp.width = masterWidth;
+ lp.height = ViewGroup.LayoutParams.MATCH_PARENT;
+ lsSplit0.setLayoutParams(lp);
}
- });
- bVersion.setVisibility(View.GONE);
- if (actionMode != null) actionMode.invalidate();
- leftDrawer.getHandle().setSplitVersion(true);
+ // no need to set width, because it has been set to match_parent, so it takes the remaining space.
+ lsSplit1.setVisibility(View.VISIBLE);
+
+ {
+ final ViewGroup.LayoutParams lp = splitHandleButton.getLayoutParams();
+ lp.width = splitHandleThickness;
+ lp.height = ViewGroup.LayoutParams.MATCH_PARENT;
+ splitHandleButton.setLayoutParams(lp);
+ }
+ }
}
void closeSplitDisplay() {
@@ -1493,9 +1502,9 @@ private void menuSearch_click() {
// stay on the same book
ari_cv = display(result.chapter_1, result.verse_1);
- // select the verse only if the displayed verse is equal to the requested verse
+ // call attention to the verse only if the displayed verse is equal to the requested verse
if (Ari.encode(0, result.chapter_1, result.verse_1) == ari_cv) {
- lsSplit0.setVerseSelected(result.verse_1, true);
+ callAttentionForVerseToBothSplits(result.verse_1);
}
} else {
// change book
@@ -1510,7 +1519,7 @@ private void menuSearch_click() {
// select the verse only if the displayed verse is equal to the requested verse
if (Ari.encode(result.bookId, result.chapter_1, result.verse_1) == Ari.encode(this.activeBook.bookId, ari_cv)) {
- lsSplit0.setVerseSelected(result.verse_1, true);
+ callAttentionForVerseToBothSplits(result.verse_1);
}
}
@@ -1527,7 +1536,7 @@ private void menuSearch_click() {
if (result != null && result.chosenIntent != null) {
Intent chosenIntent = result.chosenIntent;
final String packageName = chosenIntent.getComponent().getPackageName();
- if (U.equals(packageName, "com.facebook.katana")) { //$NON-NLS-1$
+ if (U.equals(packageName, "com.facebook.katana")) {
String verseUrl = chosenIntent.getStringExtra(EXTRA_verseUrl);
if (verseUrl != null) {
chosenIntent.putExtra(Intent.EXTRA_TEXT, verseUrl); // change text to url
@@ -1741,7 +1750,7 @@ void bVersion_click() {
final int ari_source = arif_source >>> 8;
dialog.dismiss();
- jumpToAri(ari_target, true);
+ jumpToAri(ari_target);
// add both xref source and target, so user can go back to source easily
history.add(ari_source);
@@ -1927,7 +1936,7 @@ public void onHasMapsAttributeClick(final int ari) {
.show();
}
}
- };
+ }
class VerseInlineLinkSpanFactory implements VerseInlineLinkSpan.Factory {
private final Object source;
@@ -2071,7 +2080,7 @@ public void onClick(final Type type, final int arif, final Object source) {
* Please ignore it and leave it intact. */
if (hasEsvsbAsal == null) {
try {
- getPackageManager().getApplicationInfo("yuku.esvsbasal", 0); //$NON-NLS-1$
+ getPackageManager().getApplicationInfo("yuku.esvsbasal", 0);
hasEsvsbAsal = true;
} catch (PackageManager.NameNotFoundException e) {
hasEsvsbAsal = false;
@@ -2315,11 +2324,11 @@ public void onOk(int colorRgb) {
final int ari = Ari.encode(IsiActivity.this.activeBook.bookId, IsiActivity.this.chapter_1, selected.get(0));
try {
- Intent intent = new Intent("yuku.esvsbasal.action.GOTO"); //$NON-NLS-1$
- intent.putExtra("ari", ari); //$NON-NLS-1$
+ Intent intent = new Intent("yuku.esvsbasal.action.GOTO");
+ intent.putExtra("ari", ari);
startActivity(intent);
} catch (Exception e) {
- Log.e(TAG, "ESVSB starting", e); //$NON-NLS-1$
+ Log.e(TAG, "ESVSB starting", e);
}
} return true;
case R.id.menuGuide: {
@@ -2449,6 +2458,7 @@ void reloadBothAttributeMaps() {
int first;
int handle;
int root;
+ float prop; // proportion from top or left
@Override public void onHandleDragStart() {
splitRoot.setOnefingerEnabled(false);
@@ -2462,6 +2472,8 @@ void reloadBothAttributeMaps() {
handle = splitHandleButton.getWidth();
root = splitRoot.getWidth();
}
+
+ prop = Float.MIN_VALUE; // guard against glitches
}
@Override
@@ -2472,6 +2484,7 @@ public void onHandleDragMoveX(final float dxSinceLast, final float dxSinceStart)
lp.width = newW < 0? 0: newW > maxW? maxW: newW;
lp.height = ViewGroup.LayoutParams.MATCH_PARENT;
lsSplit0.setLayoutParams(lp);
+ prop = (float) lp.width / maxW;
}
@Override public void onHandleDragMoveY(float dySinceLast, float dySinceStart) {
@@ -2481,10 +2494,15 @@ public void onHandleDragMoveX(final float dxSinceLast, final float dxSinceStart)
lp.width = ViewGroup.LayoutParams.MATCH_PARENT;
lp.height = newH < 0? 0: newH > maxH? maxH: newH;
lsSplit0.setLayoutParams(lp);
+ prop = (float) lp.height / maxH;
}
@Override public void onHandleDragStop() {
splitRoot.setOnefingerEnabled(true);
+
+ if (prop != Float.MIN_VALUE) {
+ Preferences.setFloat(Prefkey.lastSplitProp, prop);
+ }
}
};
@@ -2588,7 +2606,7 @@ public void bCurrentReadingReference_click() {
}
final int ari_start = aris[0];
- jumpToAri(ari_start, false);
+ jumpToAri(ari_start);
history.add(ari_start);
leftDrawer.closeDrawer();
@@ -2604,7 +2622,7 @@ private void gotoProgressMark(final int preset_id) {
if (ari != 0) {
App.trackEvent("left_drawer_progress_mark_pin_click_succeed");
- jumpToAri(ari, false);
+ jumpToAri(ari);
history.add(ari);
} else {
App.trackEvent("left_drawer_progress_mark_pin_click_failed");
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/U.java b/Alkitab/src/main/java/yuku/alkitab/base/U.java
index 61f50a45d..8de1048df 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/U.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/U.java
@@ -9,6 +9,7 @@
import android.support.v4.graphics.ColorUtils;
import android.widget.TextView;
import yuku.afw.storage.Preferences;
+import yuku.alkitab.base.storage.NoBackupSharedPreferences;
import yuku.alkitab.base.storage.Prefkey;
import yuku.alkitab.debug.BuildConfig;
import yuku.alkitab.debug.R;
@@ -268,11 +269,21 @@ public static String inputStreamUtf8ToString(InputStream input) throws IOExcepti
* simpleToken, which is sensitive.
*/
public synchronized static String getInstallationId() {
+ final NoBackupSharedPreferences nbsp = NoBackupSharedPreferences.get();
+
String res = Preferences.getString(Prefkey.installation_id, null);
if (res == null) {
- res = "i1:" + UUID.randomUUID().toString();
- Preferences.setString(Prefkey.installation_id, res);
+ res = nbsp.getString(Prefkey.installation_id.name());
+ if (res == null) {
+ res = "i1:" + UUID.randomUUID().toString();
+ nbsp.setString(Prefkey.installation_id.name(), res);
+ }
+ } else {
+ // we need to remove it from the backed up folder and move it to the nonbacked up folder
+ Preferences.remove(Prefkey.installation_id);
+ nbsp.setString(Prefkey.installation_id.name(), res);
}
+
return res;
}
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/ac/AboutActivity.java b/Alkitab/src/main/java/yuku/alkitab/base/ac/AboutActivity.java
index 5112f3dd4..ecfc7db83 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/ac/AboutActivity.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/ac/AboutActivity.java
@@ -4,11 +4,10 @@
import android.content.AsyncTaskLoader;
import android.content.Intent;
import android.content.Loader;
-import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.net.Uri;
-import android.os.Build;
import android.os.Bundle;
+import android.support.v4.content.res.ResourcesCompat;
import android.support.v4.widget.ContentLoadingProgressBar;
import android.support.v7.widget.Toolbar;
import android.text.method.LinkMovementMethod;
@@ -180,13 +179,7 @@ public void onPositive(final MaterialDialog dialog) {
manualAnnouncementReload.set(false);
getLoaderManager().initLoader(LOADER_announce, null, announcementLoaderCallbacks).forceLoad();
- final Drawable logoDrawable;
- if (Build.VERSION.SDK_INT >= 15) {
- logoDrawable = getResources().getDrawableForDensity(R.drawable.ic_launcher, DisplayMetrics.DENSITY_XXXHIGH);
- } else {
- logoDrawable = getResources().getDrawable(R.drawable.ic_launcher);
- }
- imgLogo.setImageDrawable(logoDrawable);
+ imgLogo.setImageDrawable(ResourcesCompat.getDrawableForDensity(getResources(), R.drawable.ic_launcher, DisplayMetrics.DENSITY_XXXHIGH, null));
imgLogo.setOnTouchListener((v,event) -> {
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/ac/AlertDialogActivity.java b/Alkitab/src/main/java/yuku/alkitab/base/ac/AlertDialogActivity.java
new file mode 100644
index 000000000..51e08ce4d
--- /dev/null
+++ b/Alkitab/src/main/java/yuku/alkitab/base/ac/AlertDialogActivity.java
@@ -0,0 +1,95 @@
+package yuku.alkitab.base.ac;
+
+import android.content.ActivityNotFoundException;
+import android.content.Intent;
+import android.os.Bundle;
+import com.afollestad.materialdialogs.MaterialDialog;
+import yuku.alkitab.base.App;
+import yuku.alkitab.base.ac.base.BaseActivity;
+import yuku.alkitab.debug.R;
+
+/**
+ * Use this class to show an alert dialog if you don't have an existing activity to
+ * show the dialog on.
+ *
+ * This starts a transparent activity and then shows an alert dialog on top
+ * of the transparent activity.
+ */
+public class AlertDialogActivity extends BaseActivity {
+
+ private static final String EXTRA_TITLE = "title";
+ private static final String EXTRA_MESSAGE = "message";
+ private static final String EXTRA_NEGATIVE = "negative";
+ private static final String EXTRA_POSITIVE = "positive";
+ private static final String EXTRA_LAUNCH = "launch";
+
+ public static Intent createOkIntent(final String title, final String message) {
+ return new Intent(App.context, AlertDialogActivity.class)
+ .putExtra(EXTRA_TITLE, title)
+ .putExtra(EXTRA_MESSAGE, message);
+ }
+
+ public static Intent createAskIntent(final String title, final String message, final String negativeButtonText, final String positiveButtonText, final Intent launchWhenPositive) {
+ return new Intent(App.context, AlertDialogActivity.class)
+ .putExtra(EXTRA_TITLE, title)
+ .putExtra(EXTRA_MESSAGE, message)
+ .putExtra(EXTRA_NEGATIVE, negativeButtonText)
+ .putExtra(EXTRA_POSITIVE, positiveButtonText)
+ .putExtra(EXTRA_LAUNCH, launchWhenPositive);
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ final String title = getIntent().getStringExtra(EXTRA_TITLE);
+ final String message = getIntent().getStringExtra(EXTRA_MESSAGE);
+ final String negative = getIntent().getStringExtra(EXTRA_NEGATIVE);
+ final String positive = getIntent().getExtras().getString(EXTRA_POSITIVE, getString(android.R.string.ok));
+ final Intent launch = getIntent().getParcelableExtra(EXTRA_LAUNCH);
+
+ final MaterialDialog.Builder builder = new MaterialDialog.Builder(this);
+
+ if (title != null) {
+ builder.title(title);
+ }
+
+ if (message != null) {
+ builder.content(message);
+ }
+
+ builder.positiveText(positive);
+
+ builder.callback(new MaterialDialog.ButtonCallback() {
+ @Override
+ public void onPositive(final MaterialDialog dialog) {
+ final Intent returnIntent = new Intent();
+ setResult(RESULT_OK, returnIntent);
+ if (launch != null) {
+ try {
+ startActivity(launch);
+ } catch (ActivityNotFoundException e) {
+ new MaterialDialog.Builder(AlertDialogActivity.this)
+ .content("Actvity was not found for intent: " + launch.toString())
+ .positiveText(R.string.ok)
+ .show();
+ }
+ }
+ finish();
+ }
+
+ @Override
+ public void onNegative(final MaterialDialog dialog) {
+ finish();
+ }
+ });
+
+ if (negative != null) {
+ builder.negativeText(negative);
+ }
+
+ builder.dismissListener(dialog -> finish());
+
+ builder.show();
+ }
+}
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/ac/DevotionActivity.java b/Alkitab/src/main/java/yuku/alkitab/base/ac/DevotionActivity.java
index d138b7b6a..394f8a1af 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/ac/DevotionActivity.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/ac/DevotionActivity.java
@@ -8,8 +8,11 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
+import android.support.annotation.Nullable;
+import android.support.design.widget.Snackbar;
import android.support.v4.app.ShareCompat;
import android.support.v4.widget.DrawerLayout;
+import android.support.v4.widget.NestedScrollView;
import android.support.v7.app.ActionBar;
import android.support.v7.widget.Toolbar;
import android.text.format.DateFormat;
@@ -19,10 +22,9 @@
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
-import android.widget.ScrollView;
import android.widget.TextView;
-import android.widget.Toast;
import com.afollestad.materialdialogs.AlertDialogWrapper;
+import com.afollestad.materialdialogs.MaterialDialog;
import com.google.android.gms.analytics.HitBuilders;
import yuku.afw.V;
import yuku.afw.storage.Preferences;
@@ -32,7 +34,9 @@
import yuku.alkitab.base.ac.base.BaseLeftDrawerActivity;
import yuku.alkitab.base.devotion.ArticleMeidA;
import yuku.alkitab.base.devotion.ArticleMorningEveningEnglish;
+import yuku.alkitab.base.devotion.ArticleRefheart;
import yuku.alkitab.base.devotion.ArticleRenunganHarian;
+import yuku.alkitab.base.devotion.ArticleRoc;
import yuku.alkitab.base.devotion.ArticleSantapanHarian;
import yuku.alkitab.base.devotion.DevotionArticle;
import yuku.alkitab.base.devotion.DevotionDownloader;
@@ -59,12 +63,13 @@ public class DevotionActivity extends BaseLeftDrawerActivity implements LeftDraw
public static final DevotionDownloader devotionDownloader = new DevotionDownloader();
static final ThreadLocal yyyymmdd = new ThreadLocal() {
- @Override protected SimpleDateFormat initialValue() {
- return new SimpleDateFormat("yyyyMMdd", Locale.US); //$NON-NLS-1$
+ @Override
+ protected SimpleDateFormat initialValue() {
+ return new SimpleDateFormat("yyyyMMdd", Locale.US);
}
};
- TwofingerLinearLayout.Listener devotion_root_listener = new TwofingerLinearLayout.OnefingerListener() {
+ TwofingerLinearLayout.Listener root_listener = new TwofingerLinearLayout.OnefingerListener() {
@Override
public void onOnefingerLeft() {
bNext_click();
@@ -82,13 +87,13 @@ public static Intent createIntent() {
@Override
public void bPrev_click() {
- currentDate.setTime(currentDate.getTime() - 3600*24*1000);
+ currentDate.setTime(currentDate.getTime() - 3600 * 24 * 1000);
display();
}
@Override
public void bNext_click() {
- currentDate.setTime(currentDate.getTime() + 3600*24*1000);
+ currentDate.setTime(currentDate.getTime() + 3600 * 24 * 1000);
display();
}
@@ -132,6 +137,28 @@ public String getShareUrl(final SimpleDateFormat format, final Date date) {
return "http://www.bibleforandroid.com/renunganpagi/" + yyyymmdd.get().format(date).substring(4);
}
},
+ REFHEART("refheart", "Reforming Heart", "STEMI Pemuda") {
+ @Override
+ public DevotionArticle getArticle(final String date) {
+ return new ArticleRefheart(date);
+ }
+
+ @Override
+ public String getShareUrl(final SimpleDateFormat format, final Date date) {
+ return null; // TODO create redirect url
+ }
+ },
+ ROC("roc", "My Utmost (B. Indonesia)", "Oswald Chambers") {
+ @Override
+ public DevotionArticle getArticle(final String date) {
+ return new ArticleRoc(date);
+ }
+
+ @Override
+ public String getShareUrl(final SimpleDateFormat format, final Date date) {
+ return null;
+ }
+ },
RH("rh", "Renungan Harian", "Yayasan Gloria") {
@Override
public DevotionArticle getArticle(final String date) {
@@ -153,8 +180,7 @@ public DevotionArticle getArticle(final String date) {
public String getShareUrl(final SimpleDateFormat format, final Date date) {
return "http://www.ccel.org/ccel/spurgeon/morneve.d" + yyyymmdd.get().format(date) + "am.html";
}
- },
- ;
+ },;
public final String name;
public final String title;
@@ -178,6 +204,7 @@ public static DevotionKind getByName(String name) {
public abstract DevotionArticle getArticle(final String date);
+ @Nullable
public abstract String getShareUrl(SimpleDateFormat format, Date date);
}
@@ -186,11 +213,11 @@ public static DevotionKind getByName(String name) {
DrawerLayout drawerLayout;
LeftDrawer.Devotion leftDrawer;
- TwofingerLinearLayout devotion_root;
+ TwofingerLinearLayout root;
TextView lContent;
- ScrollView scrollContent;
+ NestedScrollView scrollContent;
TextView lStatus;
-
+
boolean renderSucceeded = false;
// currently shown
@@ -207,7 +234,9 @@ public LongReadChecker(DevotionActivity activity) {
ac = new WeakReference<>(activity);
}
- /** This will be called 30 seconds after startKind and startDate are set. */
+ /**
+ * This will be called 30 seconds after startKind and startDate are set.
+ */
@Override
public void handleMessage(final Message msg) {
final DevotionActivity ac = this.ac.get();
@@ -287,17 +316,17 @@ protected void onCreate(Bundle savedInstanceState) {
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeAsUpIndicator(R.drawable.ic_menu_white_24dp);
- devotion_root = V.get(this, R.id.devotion_root);
+ root = V.get(this, R.id.root);
lContent = V.get(this, R.id.lContent);
scrollContent = V.get(this, R.id.scrollContent);
lStatus = V.get(this, R.id.lStatus);
- devotion_root.setTwofingerEnabled(false);
- devotion_root.setListener(devotion_root_listener);
+ root.setTwofingerEnabled(false);
+ root.setListener(root_listener);
final DevotionKind storedKind = DevotionKind.getByName(Preferences.getString(Prefkey.devotion_last_kind_name, DEFAULT_DEVOTION_KIND.name));
- currentKind = storedKind == null? DEFAULT_DEVOTION_KIND: storedKind;
+ currentKind = storedKind == null ? DEFAULT_DEVOTION_KIND : storedKind;
currentDate = new Date();
new Prefetcher(currentKind).start();
@@ -305,7 +334,8 @@ protected void onCreate(Bundle savedInstanceState) {
display();
}
- @Override protected void onStart() {
+ @Override
+ protected void onStart() {
super.onStart();
{ // apply background color, and clear window background to prevent overdraw
@@ -339,7 +369,7 @@ public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_devotion, menu);
return true;
}
-
+
@Override
public boolean onOptionsItemSelected(MenuItem item) {
final int itemId = item.getItemId();
@@ -348,15 +378,17 @@ public boolean onOptionsItemSelected(MenuItem item) {
return true;
} else if (itemId == R.id.menuCopy) {
U.copyToClipboard(currentKind.title + "\n" + lContent.getText());
-
- Toast.makeText(this, R.string.renungan_sudah_disalin, Toast.LENGTH_SHORT).show();
-
+
+ Snackbar.make(root, R.string.renungan_sudah_disalin, Snackbar.LENGTH_SHORT).show();
+
return true;
} else if (itemId == R.id.menuShare) {
- Intent intent = ShareCompat.IntentBuilder.from(DevotionActivity.this)
+ final String shareUrl = currentKind.getShareUrl(yyyymmdd.get(), currentDate);
+
+ final Intent intent = ShareCompat.IntentBuilder.from(DevotionActivity.this)
.setType("text/plain")
.setSubject(currentKind.title)
- .setText(currentKind.title + '\n' + getCurrentDateDisplay() + '\n' + currentKind.getShareUrl(yyyymmdd.get(), currentDate) + "\n\n" + lContent.getText())
+ .setText(currentKind.title + '\n' + getCurrentDateDisplay() + (shareUrl == null ? "" : ('\n' + shareUrl)) + "\n\n" + lContent.getText())
.getIntent();
startActivityForResult(ShareActivity.createIntent(intent, getString(R.string.bagikan_renungan)), REQCODE_share);
return true;
@@ -364,7 +396,7 @@ public boolean onOptionsItemSelected(MenuItem item) {
startActivity(DevotionReminderActivity.createIntent());
return true;
}
-
+
return super.onOptionsItemSelected(item);
}
@@ -376,7 +408,7 @@ void display() {
}
if (article == null) {
- Log.d(TAG, "rendering null article"); //$NON-NLS-1$
+ Log.d(TAG, "rendering null article");
} else {
Log.d(TAG, "rendering article name=" + article.getKind().name + " date=" + article.getDate() + " readyToUse=" + article.getReadyToUse());
}
@@ -432,7 +464,7 @@ static class PatchTextExtraInfoJson {
CallbackSpan.OnClickListener verseClickListener = new CallbackSpan.OnClickListener() {
@Override
public void onClick(View widget, String reference) {
- Log.d(TAG, "Clicked verse reference inside devotion: " + reference); //$NON-NLS-1$
+ Log.d(TAG, "Clicked verse reference inside devotion: " + reference);
if (reference.startsWith("patchtext:")) {
final Uri uri = Uri.parse(reference);
@@ -493,9 +525,9 @@ synchronized void willNeed(final DevotionKind kind, final String date, final boo
final DevotionArticle article = kind.getArticle(date);
devotionDownloader.add(article, prioritize);
}
-
+
static boolean prefetcherRunning = false;
-
+
class Prefetcher extends Thread {
private final DevotionKind prefetchKind;
@@ -503,7 +535,8 @@ public Prefetcher(final DevotionKind kind) {
prefetchKind = kind;
}
- @Override public void run() {
+ @Override
+ public void run() {
if (prefetcherRunning) {
Log.d(TAG, "prefetcher is already running");
}
@@ -511,13 +544,13 @@ public Prefetcher(final DevotionKind kind) {
Thread.yield();
final Date today = new Date();
-
+
// hapus yang sudah lebih lama dari 6 bulan (180 hari)!
final int deleted = S.getDb().deleteDevotionsWithTouchTimeBefore(new Date(today.getTime() - 180 * 86400000L));
if (deleted > 0) {
- Log.d(TAG, "old devotions deleted: " + deleted); //$NON-NLS-1$
+ Log.d(TAG, "old devotions deleted: " + deleted);
}
-
+
prefetcherRunning = true;
try {
int DAYS = 31;
@@ -528,14 +561,14 @@ public Prefetcher(final DevotionKind kind) {
for (int i = 0; i < DAYS; i++) {
String date = yyyymmdd.get().format(today);
if (S.getDb().tryGetDevotion(prefetchKind.name, date) == null) {
- Log.d(TAG, "Prefetcher need to get " + date); //$NON-NLS-1$
+ Log.d(TAG, "Prefetcher need to get " + date);
willNeed(prefetchKind, date, false);
} else {
Thread.yield();
}
-
+
// maju ke besoknya
- today.setTime(today.getTime() + 3600*24*1000);
+ today.setTime(today.getTime() + 3600 * 24 * 1000);
}
} finally {
prefetcherRunning = false;
@@ -543,15 +576,24 @@ public Prefetcher(final DevotionKind kind) {
}
}
- @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (requestCode == REQCODE_share) {
- if (resultCode == RESULT_OK) {
- ShareActivity.Result result = ShareActivity.obtainResult(data);
- if (result != null && result.chosenIntent != null) {
- Intent chosenIntent = result.chosenIntent;
- if (U.equals(chosenIntent.getComponent().getPackageName(), "com.facebook.katana")) {
- chosenIntent.putExtra(Intent.EXTRA_TEXT, currentKind.getShareUrl(yyyymmdd.get(), currentDate));
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (requestCode == REQCODE_share && resultCode == RESULT_OK) {
+ final ShareActivity.Result result = ShareActivity.obtainResult(data);
+ if (result != null && result.chosenIntent != null) {
+ final Intent chosenIntent = result.chosenIntent;
+ if (U.equals(chosenIntent.getComponent().getPackageName(), "com.facebook.katana")) {
+ final String shareUrl = currentKind.getShareUrl(yyyymmdd.get(), currentDate);
+ if (shareUrl != null) {
+ chosenIntent.putExtra(Intent.EXTRA_TEXT, shareUrl);
+ startActivity(chosenIntent);
+ } else {
+ new MaterialDialog.Builder(this)
+ .content(R.string.no_url_for_facebook)
+ .positiveText(R.string.ok)
+ .show();
}
+ } else {
startActivity(chosenIntent);
}
}
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/ac/FontManagerActivity.java b/Alkitab/src/main/java/yuku/alkitab/base/ac/FontManagerActivity.java
index 4c4be1294..b7d32ad16 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/ac/FontManagerActivity.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/ac/FontManagerActivity.java
@@ -8,7 +8,6 @@
import android.os.IBinder;
import android.util.Log;
import android.view.View;
-import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
@@ -22,9 +21,6 @@
import yuku.alkitab.base.App;
import yuku.alkitab.base.ac.base.BaseActivity;
import yuku.alkitab.base.sv.DownloadService;
-import yuku.alkitab.base.sv.DownloadService.DownloadBinder;
-import yuku.alkitab.base.sv.DownloadService.DownloadEntry;
-import yuku.alkitab.base.sv.DownloadService.DownloadListener;
import yuku.alkitab.base.util.FontManager;
import yuku.alkitab.debug.R;
@@ -39,7 +35,7 @@
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
-public class FontManagerActivity extends BaseActivity implements DownloadListener {
+public class FontManagerActivity extends BaseActivity implements DownloadService.DownloadListener {
public static final String TAG = FontManagerActivity.class.getSimpleName();
private static final String URL_fontList = "https://alkitab-host.appspot.com/addon/fonts/v1/list-v2.txt";
@@ -61,18 +57,16 @@ public static Intent createIntent() {
}
@Override public void onServiceConnected(ComponentName name, IBinder service) {
- dls = ((DownloadBinder) service).getService();
+ dls = ((DownloadService.DownloadBinder) service).getService();
dls.setDownloadListener(FontManagerActivity.this);
- runOnUiThread(new Runnable() {
- @Override public void run() {
- loadFontList();
- }
- });
+ runOnUiThread(() -> loadFontList());
}
};
@Override protected void onCreate(Bundle savedInstanceState) {
- super.onCreateWithNonToolbarUpButton(savedInstanceState);
+ enableNonToolbarUpButton();
+ super.willNeedStoragePermission();
+ super.onCreate(savedInstanceState);
setContentView(R.layout.activity_font_manager);
setTitle(R.string.fm_activity_title);
@@ -85,7 +79,16 @@ public static Intent createIntent() {
bindService(new Intent(App.context, DownloadService.class), serviceConnection, BIND_AUTO_CREATE);
}
-
+
+ @Override
+ protected void onNeededPermissionsGranted(final boolean immediatelyGranted) {
+ super.onNeededPermissionsGranted(immediatelyGranted);
+
+ if (!immediatelyGranted && dls != null) {
+ loadFontList();
+ }
+ }
+
@Override protected void onDestroy() {
super.onDestroy();
@@ -132,16 +135,16 @@ void loadFontList() {
}
String getFontDownloadKey(String name) {
- return "FontManager/" + name; //$NON-NLS-1$
+ return "FontManager/" + name;
}
private String getFontNameFromDownloadKey(String key) {
- if (!key.startsWith("FontManager/")) return null; //$NON-NLS-1$
- return key.substring("FontManager/".length()); //$NON-NLS-1$
+ if (!key.startsWith("FontManager/")) return null;
+ return key.substring("FontManager/".length());
}
String getFontDownloadDestination(String name) {
- return new File(FontManager.getFontsPath(), "download-" + name + ".zip").getAbsolutePath(); //$NON-NLS-1$ //$NON-NLS-2$
+ return new File(FontManager.getFontsPath(), "download-" + name + ".zip").getAbsolutePath();
}
public static class FontItem {
@@ -204,7 +207,7 @@ public void onSuccess() {
bDelete.setVisibility(View.VISIBLE);
lErrorMsg.setVisibility(View.GONE);
} else {
- DownloadEntry entry = dls.getEntry(dlkey);
+ DownloadService.DownloadEntry entry = dls.getEntry(dlkey);
if (entry == null) {
progressbar.setIndeterminate(false);
progressbar.setMax(100);
@@ -255,27 +258,25 @@ public void onSuccess() {
return res;
}
- private OnClickListener bDownload_click = new OnClickListener() {
- @Override public void onClick(View v) {
- FontItem item = (FontItem) v.getTag(R.id.TAG_fontItem);
-
- String dlkey = getFontDownloadKey(item.name);
- dls.removeEntry(dlkey);
-
- if (dls.getEntry(dlkey) == null) {
- new File(FontManager.getFontsPath()).mkdirs();
- dls.startDownload(
- dlkey,
- String.format(URL_fontData, item.name),
- getFontDownloadDestination(item.name)
- );
- }
-
- notifyDataSetChanged();
+ private View.OnClickListener bDownload_click = v -> {
+ FontItem item = (FontItem) v.getTag(R.id.TAG_fontItem);
+
+ String dlkey = getFontDownloadKey(item.name);
+ dls.removeEntry(dlkey);
+
+ if (dls.getEntry(dlkey) == null) {
+ new File(FontManager.getFontsPath()).mkdirs();
+ dls.startDownload(
+ dlkey,
+ String.format(URL_fontData, item.name),
+ getFontDownloadDestination(item.name)
+ );
}
+
+ notifyDataSetChanged();
};
- private OnClickListener bDelete_click = v -> {
+ private View.OnClickListener bDelete_click = v -> {
final FontItem item = (FontItem) v.getTag(R.id.TAG_fontItem);
new AlertDialogWrapper.Builder(FontManagerActivity.this)
@@ -299,7 +300,7 @@ public void onSuccess() {
};
}
- @Override public void onStateChanged(DownloadEntry entry, DownloadService.State originalState) {
+ @Override public void onStateChanged(DownloadService.DownloadEntry entry, DownloadService.State originalState) {
adapter.notifyDataSetChanged();
if (originalState == DownloadService.State.finished) {
@@ -313,14 +314,14 @@ public void onSuccess() {
File fontDir = FontManager.getFontDir(fontName);
fontDir.mkdirs();
- Log.d(TAG, "Going to unzip " + downloadedZip, new Throwable().fillInStackTrace()); //$NON-NLS-1$
+ Log.d(TAG, "Going to unzip " + downloadedZip, new Throwable().fillInStackTrace());
ZipInputStream zis = new ZipInputStream(new BufferedInputStream(new FileInputStream(downloadedZip)));
try {
ZipEntry ze;
while ((ze = zis.getNextEntry()) != null) {
String zname = ze.getName();
- Log.d(TAG, "Extracting from zip: " + zname); //$NON-NLS-1$
+ Log.d(TAG, "Extracting from zip: " + zname);
File extractFile = new File(fontDir, zname);
FileOutputStream fos = new FileOutputStream(extractFile);
try {
@@ -347,7 +348,7 @@ public void onSuccess() {
}
}
- @Override public void onProgress(DownloadEntry entry, DownloadService.State originalState) {
+ @Override public void onProgress(DownloadService.DownloadEntry entry, DownloadService.State originalState) {
adapter.notifyDataSetChanged();
}
}
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/ac/GotoActivity.java b/Alkitab/src/main/java/yuku/alkitab/base/ac/GotoActivity.java
index def836527..4f0b56324 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/ac/GotoActivity.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/ac/GotoActivity.java
@@ -2,13 +2,17 @@
import android.content.Intent;
import android.os.Bundle;
+import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
+import android.support.v7.app.ActionBar;
+import android.support.v7.widget.Toolbar;
+import android.view.Menu;
+import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
-import com.google.samples.apps.iosched.ui.widget.SlidingTabLayout;
import yuku.afw.App;
import yuku.afw.V;
import yuku.afw.storage.Preferences;
@@ -16,11 +20,11 @@
import yuku.alkitab.base.fr.GotoDialerFragment;
import yuku.alkitab.base.fr.GotoDirectFragment;
import yuku.alkitab.base.fr.GotoGridFragment;
-import yuku.alkitab.base.fr.base.BaseGotoFragment.GotoFinishListener;
+import yuku.alkitab.base.fr.base.BaseGotoFragment;
import yuku.alkitab.base.storage.Prefkey;
import yuku.alkitab.debug.R;
-public class GotoActivity extends BaseActivity implements GotoFinishListener {
+public class GotoActivity extends BaseActivity implements BaseGotoFragment.GotoFinishListener {
public static final String TAG = GotoActivity.class.getSimpleName();
private static final String EXTRA_bookId = "bookId";
@@ -51,8 +55,9 @@ public static Result obtainResult(Intent data) {
return res;
}
+ Toolbar toolbar;
ViewPager viewPager;
- SlidingTabLayout slidingTabs;
+ TabLayout tablayout;
GotoPagerAdapter pagerAdapter;
boolean okToHideKeyboard = false;
@@ -69,10 +74,19 @@ public static Result obtainResult(Intent data) {
chapter_1 = getIntent().getIntExtra(EXTRA_chapter, 0);
verse_1 = getIntent().getIntExtra(EXTRA_verse, 0);
+ toolbar = V.get(this, R.id.toolbar);
+ setSupportActionBar(toolbar);
+ final ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayShowTitleEnabled(false);
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ toolbar.setNavigationOnClickListener(v -> navigateUp());
+ }
+
// ViewPager and its adapters use support library fragments, so use getSupportFragmentManager.
viewPager = V.get(this, R.id.viewPager);
viewPager.setAdapter(pagerAdapter = new GotoPagerAdapter(getSupportFragmentManager()));
- viewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
+ viewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
if (okToHideKeyboard && position != 1) {
@@ -86,9 +100,11 @@ public void onPageSelected(int position) {
}
});
- slidingTabs = V.get(this, R.id.sliding_tabs);
- slidingTabs.setCustomTabColorizer(position -> getResources().getColor(R.color.accent));
- slidingTabs.setViewPager(viewPager);
+ tablayout = V.get(this, R.id.tablayout);
+ tablayout.setTabMode(TabLayout.MODE_SCROLLABLE);
+ tablayout.setTabsFromPagerAdapter(pagerAdapter);
+ tablayout.setOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(viewPager));
+ viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tablayout));
if (savedInstanceState == null) {
// get from preferences
@@ -114,6 +130,33 @@ public void onPageSelected(int position) {
}
}
+ @Override
+ public boolean onCreateOptionsMenu(final Menu menu) {
+ getMenuInflater().inflate(R.menu.activity_goto, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onPrepareOptionsMenu(final Menu menu) {
+ final MenuItem menuAskForVerse = menu.findItem(R.id.menuAskForVerse);
+ final boolean val = Preferences.getBoolean(Prefkey.gotoAskForVerse, Prefkey.GOTO_ASK_FOR_VERSE_DEFAULT);
+ menuAskForVerse.setChecked(val);
+
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(final MenuItem item) {
+ if (item.getItemId() == R.id.menuAskForVerse) {
+ final boolean val = Preferences.getBoolean(Prefkey.gotoAskForVerse, Prefkey.GOTO_ASK_FOR_VERSE_DEFAULT);
+ Preferences.setBoolean(Prefkey.gotoAskForVerse, !val);
+ supportInvalidateOptionsMenu();
+ return true;
+ }
+
+ return super.onOptionsItemSelected(item);
+ }
+
@Override protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(INSTANCE_STATE_tab, viewPager.getCurrentItem());
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/ac/HelpActivity.java b/Alkitab/src/main/java/yuku/alkitab/base/ac/HelpActivity.java
index ee5ba5371..19dd9148e 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/ac/HelpActivity.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/ac/HelpActivity.java
@@ -48,7 +48,8 @@ public static Intent createViewAnnouncementIntent(final long[] announcementIds)
@SuppressLint("SetJavaScriptEnabled")
@Override
protected void onCreate(Bundle savedInstanceState) {
- super.onCreateWithNonToolbarUpButton(savedInstanceState);
+ enableNonToolbarUpButton();
+ super.onCreate(savedInstanceState);
setContentView(R.layout.activity_help);
webview = V.get(this, R.id.webView);
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/ac/MarkerListActivity.java b/Alkitab/src/main/java/yuku/alkitab/base/ac/MarkerListActivity.java
index b0bf851bd..5fbfe2012 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/ac/MarkerListActivity.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/ac/MarkerListActivity.java
@@ -100,7 +100,8 @@ public static Intent createIntent(Context context, Marker.Kind filter_kind, long
@SuppressLint("MissingSuperCall")
@Override
protected void onCreate(Bundle savedInstanceState) {
- super.onCreateWithNonToolbarUpButton(savedInstanceState);
+ enableNonToolbarUpButton();
+ super.onCreate(savedInstanceState);
setContentView(R.layout.activity_marker_list);
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/ac/MarkersActivity.java b/Alkitab/src/main/java/yuku/alkitab/base/ac/MarkersActivity.java
index 98c965311..2e9ded2cd 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/ac/MarkersActivity.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/ac/MarkersActivity.java
@@ -68,7 +68,8 @@ public static Intent createIntent() {
}
@Override protected void onCreate(Bundle savedInstanceState) {
- super.onCreateWithNonToolbarUpButton(savedInstanceState);
+ enableNonToolbarUpButton();
+ super.onCreate(savedInstanceState);
setContentView(R.layout.activity_markers);
setTitle(R.string.activity_title_markers);
@@ -124,7 +125,7 @@ public boolean onOptionsItemSelected(final MenuItem item) {
case R.id.menuMigrateFromV3: {
final FileChooserConfig config = new FileChooserConfig();
config.mode = FileChooserConfig.Mode.Open;
- config.pattern = YukuAlkitabImportOfferActivity.getBackupFilenameMatcher().pattern().toString();
+ config.pattern = "(yuku\\.alkitab|yuku\\.alkitab\\.kjv|org\\.sabda\\.alkitab|org\\.sabda\\.online)-(backup|autobackup-[0-9-]+)\\.xml";
config.title = getString(R.string.marker_migrate_file_chooser_title);
final Intent intent = FileChooserActivity.createIntent(this, config);
startActivityForResult(intent, REQCODE_migrateFromV3);
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/ac/SearchActivity.java b/Alkitab/src/main/java/yuku/alkitab/base/ac/SearchActivity.java
index 9e1bb5ff5..6cd5eab7c 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/ac/SearchActivity.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/ac/SearchActivity.java
@@ -7,19 +7,27 @@
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.design.widget.Snackbar;
+import android.support.v4.graphics.ColorUtils;
+import android.support.v4.widget.CursorAdapter;
+import android.support.v7.view.ActionMode;
+import android.support.v7.widget.SearchView;
import android.support.v7.widget.Toolbar;
import android.text.SpannableStringBuilder;
+import android.text.Spanned;
import android.text.TextUtils;
+import android.text.style.UnderlineSpan;
import android.util.SparseBooleanArray;
+import android.view.Menu;
+import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
+import android.widget.AbsListView;
+import android.widget.AdapterView;
import android.widget.AutoCompleteTextView;
import android.widget.CheckBox;
import android.widget.CompoundButton;
-import android.widget.CursorAdapter;
import android.widget.ListView;
-import android.widget.SearchView;
import android.widget.TextView;
import com.afollestad.materialdialogs.AlertDialogWrapper;
import com.afollestad.materialdialogs.MaterialDialog;
@@ -56,10 +64,10 @@ public class SearchActivity extends BaseActivity {
final String COLUMN_QUERY_STRING = "query_string";
+ View root;
TextView bVersion;
SearchView searchView;
ListView lsSearchResults;
- View empty;
TextView tSearchTips;
View panelFilter;
CheckBox cFilterOlds;
@@ -76,6 +84,102 @@ public class SearchActivity extends BaseActivity {
Version searchInVersion;
String searchInVersionId;
SearchHistoryAdapter searchHistoryAdapter;
+ ActionMode actionMode;
+
+ final AdapterView.OnItemLongClickListener lsSearchResults_itemLongClick = (parent, view, position, id) -> {
+ if (actionMode == null) {
+ actionMode = startSupportActionMode(new ActionMode.Callback() {
+ @Override
+ public boolean onCreateActionMode(final ActionMode mode, final Menu menu) {
+ getMenuInflater().inflate(R.menu.context_search, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onPrepareActionMode(final ActionMode mode, final Menu menu) {
+ final int checked_count = lsSearchResults.getCheckedItemCount();
+
+ if (checked_count == 1) {
+ mode.setTitle(R.string.verse_select_one_verse_selected);
+ } else {
+ mode.setTitle(getString(R.string.verse_select_multiple_verse_selected, checked_count));
+ }
+
+ return true;
+ }
+
+ @Override
+ public boolean onActionItemClicked(final ActionMode mode, final MenuItem item) {
+ final int itemId = item.getItemId();
+ if (itemId == R.id.menuSelectAll) {
+ for (int i = 0, size = adapter.getCount(); i < size; i++) {
+ lsSearchResults.setItemChecked(i, true);
+ }
+ onCheckedVerseChanged();
+
+ } else if (itemId == R.id.menuCopy) {
+ final SpannableStringBuilder sb = new SpannableStringBuilder();
+
+ final IntArrayList aris = adapter.getSearchResults();
+ final SparseBooleanArray checkeds = lsSearchResults.getCheckedItemPositions();
+ for (int i = 0, size = checkeds.size(); i < size; i++) {
+ if (!checkeds.valueAt(i)) continue;
+ final int position = checkeds.keyAt(i);
+ final int ari = aris.get(position);
+
+ final String reference = searchInVersion.reference(ari);
+ final String verseText = U.removeSpecialCodes(searchInVersion.loadVerseText(ari));
+
+ final int sb_len = sb.length();
+ sb.append(reference).append("\n").append(verseText).append("\n\n");
+
+ if (size < 1000) { // too much spans is very slow
+ sb.setSpan(new UnderlineSpan(), sb_len, sb_len + reference.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ }
+ }
+
+ U.copyToClipboard(sb);
+ Snackbar.make(root, R.string.search_selected_verse_copied, Snackbar.LENGTH_SHORT).show();
+
+ mode.finish();
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public void onDestroyActionMode(final ActionMode mode) {
+ uncheckAllVerses();
+ actionMode = null;
+ }
+ });
+ }
+
+ final boolean old = lsSearchResults.isItemChecked(position);
+ lsSearchResults.setItemChecked(position, !old);
+
+ onCheckedVerseChanged();
+
+ return true;
+ };
+
+ private void uncheckAllVerses() {
+ final SparseBooleanArray checkeds = lsSearchResults.getCheckedItemPositions();
+ for (int i = checkeds.size() - 1; i >= 0; i--) {
+ if (checkeds.valueAt(i)) lsSearchResults.setItemChecked(checkeds.keyAt(i), false);
+ }
+ }
+
+ private void onCheckedVerseChanged() {
+ adapter.notifyDataSetChanged();
+ if (actionMode != null) {
+ if (lsSearchResults.getCheckedItemCount() == 0) {
+ actionMode.finish();
+ } else {
+ actionMode.invalidate();
+ }
+ }
+ }
static class SearchHistory {
public static class Entry {
@@ -145,8 +249,8 @@ public static Intent createIntent(int openedBookId) {
setContentView(R.layout.activity_search);
+ root = V.get(this, R.id.root);
lsSearchResults = V.get(this, R.id.lsSearchResults);
- empty = V.get(this, android.R.id.empty);
tSearchTips = V.get(this, R.id.tSearchTips);
panelFilter = V.get(this, R.id.panelFilter);
cFilterOlds = V.get(this, R.id.cFilterOlds);
@@ -224,18 +328,28 @@ public boolean onQueryTextChange(String newText) {
tSearchTips.setText(sb);
}
- empty.setBackgroundColor(S.applied.backgroundColor);
+ tSearchTips.setBackgroundColor(S.applied.backgroundColor);
+
lsSearchResults.setBackgroundColor(S.applied.backgroundColor);
lsSearchResults.setCacheColorHint(S.applied.backgroundColor);
- lsSearchResults.setEmptyView(empty);
+ lsSearchResults.setEmptyView(tSearchTips);
Appearances.applyTextAppearance(tSearchTips);
hiliteColor = U.getSearchKeywordTextColorByBrightness(S.applied.backgroundBrightness);
+ lsSearchResults.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE);
lsSearchResults.setOnItemClickListener((parent, view, position, id) -> {
- int ari = adapter.getSearchResults().get(position);
- startActivity(Launcher.openAppAtBibleLocationWithVerseSelected(ari));
+ if (actionMode != null) {
+ // By default setItemChecked will be called when action mode is on.
+ // We just need to invalidate the view and the selected verse count.
+ onCheckedVerseChanged();
+ } else {
+ final int ari = adapter.getSearchResults().get(position);
+ startActivity(Launcher.openAppAtBibleLocationWithVerseSelected(ari));
+ }
});
+ lsSearchResults.setOnItemLongClickListener(lsSearchResults_itemLongClick);
+
bEditFilter.setOnClickListener(v -> bEditFilter_click());
cFilterOlds.setOnCheckedChangeListener(cFilterOlds_checkedChange);
cFilterNews.setOnCheckedChangeListener(cFilterNews_checkedChange);
@@ -557,6 +671,11 @@ protected void search(final String query_string) {
result = new IntArrayList(); // empty result
}
+ if (actionMode != null) {
+ actionMode.finish();
+ }
+
+ uncheckAllVerses();
lsSearchResults.setAdapter(adapter = new SearchAdapter(result, tokens));
if (result.size() > 0) {
@@ -689,22 +808,49 @@ public int getCount() {
}
@Override public void bindView(View view, int position, ViewGroup parent) {
- TextView lReference = V.get(view, R.id.lReference);
- TextView lSnippet = V.get(view, R.id.lSnippet);
-
- int ari = searchResults.get(position);
+ final boolean checked = lsSearchResults.isItemChecked(position);
+ final int checkedBgColor;
+ final int checkedTextColor;
+
+ if (checked) {
+ final int colorRgb = Preferences.getInt(R.string.pref_selectedVerseBgColor_key, R.integer.pref_selectedVerseBgColor_default);
+ checkedBgColor = ColorUtils.setAlphaComponent(colorRgb, 0xa0);
+ checkedTextColor = U.getTextColorForSelectedVerse(checkedBgColor);
+ } else {
+ // no need to calculate
+ checkedBgColor = 0;
+ checkedTextColor = 0;
+ }
+
+ final TextView lReference = V.get(view, R.id.lReference);
+ final TextView lSnippet = V.get(view, R.id.lSnippet);
+
+ final int ari = searchResults.get(position);
final SpannableStringBuilder sb = new SpannableStringBuilder(searchInVersion.reference(ari));
Appearances.applySearchResultReferenceAppearance(lReference, sb);
+ if (checked) {
+ lReference.setTextColor(checkedTextColor);
+ }
+
+ Appearances.applyTextAppearance(lSnippet);
+ if (checked) {
+ lSnippet.setTextColor(checkedTextColor);
+ }
final String verseText = U.removeSpecialCodes(searchInVersion.loadVerseText(ari));
if (verseText != null) {
- lSnippet.setText(SearchEngine.hilite(verseText, tokens, hiliteColor));
+ lSnippet.setText(SearchEngine.hilite(verseText, tokens, checked? checkedTextColor: hiliteColor));
} else {
lSnippet.setText(R.string.generic_verse_not_available_in_this_version);
}
- Appearances.applyTextAppearance(lSnippet);
+
+ if (checked) {
+ view.setBackgroundColor(checkedBgColor);
+ } else {
+ view.setBackgroundColor(0x0);
+ }
}
IntArrayList getSearchResults() {
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/ac/SearchBookFilterActivity.java b/Alkitab/src/main/java/yuku/alkitab/base/ac/SearchBookFilterActivity.java
index 9b1cbe0c9..a2088115a 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/ac/SearchBookFilterActivity.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/ac/SearchBookFilterActivity.java
@@ -5,20 +5,18 @@
import android.graphics.drawable.InsetDrawable;
import android.os.Bundle;
import android.os.Parcelable;
+import android.support.v7.widget.GridLayoutManager;
+import android.support.v7.widget.RecyclerView;
import android.util.SparseBooleanArray;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.AdapterView;
import android.widget.CheckBox;
-import android.widget.CompoundButton;
-import android.widget.GridView;
import android.widget.TextView;
import yuku.afw.App;
import yuku.afw.V;
import yuku.afw.storage.Preferences;
-import yuku.afw.widget.EasyAdapter;
import yuku.alkitab.base.U;
import yuku.alkitab.base.ac.base.BaseActivity;
import yuku.alkitab.base.util.BookNameSorter;
@@ -32,7 +30,7 @@ public class SearchBookFilterActivity extends BaseActivity {
SparseBooleanArray selectedBookIds;
BookAdapter adapter;
- int[][] bookCategoryMappings = {
+ static final int[][] bookCategoryMappings = {
{R.id.cOldTestament, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38},
{R.id.cOldPentateuch, 0, 1, 2, 3, 4},
{R.id.cOldHistory, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16},
@@ -47,35 +45,6 @@ public class SearchBookFilterActivity extends BaseActivity {
{R.id.cNewApocalypse, 65},
};
- CompoundButton.OnCheckedChangeListener category_checkedChange = new CompoundButton.OnCheckedChangeListener() {
- @Override
- public void onCheckedChanged(final CompoundButton buttonView, final boolean isChecked) {
- int[] bookCategoryMapping = null;
- for (int[] mapping : bookCategoryMappings) {
- if (mapping[0] == buttonView.getId()) {
- bookCategoryMapping = mapping;
- break;
- }
- }
- assert bookCategoryMapping != null;
-
- // all on?
- boolean all_on = true;
- for (int i = 1; i < bookCategoryMapping.length; i++) {
- if (!selectedBookIds.get(bookCategoryMapping[i])) {
- all_on = false;
- break;
- }
- }
-
- for (int i = 1; i < bookCategoryMapping.length; i++) {
- selectedBookIds.put(bookCategoryMapping[i], !all_on);
- }
-
- display();
- }
- };
-
public static Intent createIntent(final SparseBooleanArray selectedBookIds, final Book[] books) {
final Intent res = new Intent(App.context, SearchBookFilterActivity.class);
res.putExtra(EXTRA_selectedBookIds, sparseBooleanArrayToIntArray(selectedBookIds));
@@ -130,52 +99,17 @@ public void onCreate(Bundle savedInstanceState) {
//noinspection SuspiciousSystemArraycopy
System.arraycopy(booksParcelable, 0, books, 0, booksParcelable.length);
- GridView gridBook = V.get(this, R.id.gridBook);
- gridBook.setAdapter(adapter = new BookAdapter(books));
- gridBook.setOnItemClickListener(gridBook_itemClick);
-
- for (int[] bookCategoryMapping : bookCategoryMappings) {
- V.get(this, bookCategoryMapping[0]).setOnCheckedChangeListener(category_checkedChange);
- }
+ final RecyclerView gridBook = V.get(this, R.id.gridBook);
+ adapter = new BookAdapter(books);
+ final GridLayoutManager manager = new GridLayoutManager(getApplication(), 6);
+ manager.setSpanSizeLookup(adapter.spanSizeLookup);
+ gridBook.setLayoutManager(manager);
+ gridBook.setAdapter(adapter);
V.get(this, R.id.bOk).setOnClickListener(bOk_click);
V.get(this, R.id.bCancel).setOnClickListener(bCancel_click);
-
- display();
}
- void display() {
- for (int[] bookCategoryMapping : bookCategoryMappings) {
- final CheckBox checkBox = V.get(this, bookCategoryMapping[0]);
- checkBox.setOnCheckedChangeListener(null);
-
- // all books related to this checkbox are on?
- boolean all_on = true;
- for (int i = 1; i < bookCategoryMapping.length; i++) {
- if (!selectedBookIds.get(bookCategoryMapping[i])) {
- all_on = false;
- break;
- }
- }
-
- checkBox.setChecked(all_on);
- checkBox.setOnCheckedChangeListener(category_checkedChange);
- }
-
- adapter.notifyDataSetChanged();
- }
-
- AdapterView.OnItemClickListener gridBook_itemClick = new AdapterView.OnItemClickListener() {
- @Override
- public void onItemClick(final AdapterView> parent, final View view, final int position, final long id) {
- final Book book = adapter.getItem(position);
- final boolean oldstate = selectedBookIds.get(book.bookId);
- final boolean newstate = !oldstate;
- selectedBookIds.put(book.bookId, newstate);
- display();
- }
- };
-
View.OnClickListener bOk_click = new View.OnClickListener() {
@Override
public void onClick(final View v) {
@@ -186,16 +120,33 @@ public void onClick(final View v) {
}
};
- View.OnClickListener bCancel_click = new View.OnClickListener() {
- @Override
- public void onClick(final View v) {
- finish();
+ View.OnClickListener bCancel_click = v -> finish();
+
+ static class VH extends RecyclerView.ViewHolder {
+ int viewType;
+
+ public VH(final View itemView, final int viewType) {
+ super(itemView);
+ this.viewType = viewType;
}
- };
+ }
+
+ class BookAdapter extends RecyclerView.Adapter {
+ public static final int TYPE_CATEGORIES = 1;
+ public static final int TYPE_BOOK = 2;
- class BookAdapter extends EasyAdapter {
final Book[] books_grid;
+ public GridLayoutManager.SpanSizeLookup spanSizeLookup = new GridLayoutManager.SpanSizeLookup() {
+ @Override
+ public int getSpanSize(final int position) {
+ if (position == 0) {
+ return 6;
+ }
+ return 1;
+ }
+ };
+
public BookAdapter(Book[] books) {
// sort or not based on pref
if (Preferences.getBoolean(App.context.getString(R.string.pref_alphabeticBookSort_key), App.context.getResources().getBoolean(R.bool.pref_alphabeticBookSort_default))) {
@@ -206,42 +157,96 @@ public BookAdapter(Book[] books) {
}
@Override
- public View newView(int position, ViewGroup parent) {
- TextView res = new TextView(SearchBookFilterActivity.this);
- res.setLayoutParams(new GridView.LayoutParams(getResources().getDimensionPixelSize(R.dimen.goto_grid_cell_width_book), getResources().getDimensionPixelSize(R.dimen.goto_grid_cell_height)));
- res.setGravity(Gravity.CENTER);
- res.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
- return res;
+ public int getItemViewType(final int position) {
+ if (position == 0) return TYPE_CATEGORIES;
+ return TYPE_BOOK;
}
@Override
- public void bindView(View view, int position, ViewGroup parent) {
- final TextView lName = (TextView) view;
-
- final Book book = getItem(position);
-
- lName.setText(BookNameSorter.getBookAbbr(book));
-
- if (selectedBookIds.get(book.bookId)) {
- lName.setTextColor(0xffffffff);
- final ColorDrawable color = new ColorDrawable(U.getBackgroundColorByBookId(book.bookId));
- final InsetDrawable bg = new InsetDrawable(color, getResources().getDimensionPixelOffset(R.dimen.goto_grid_cell_inset));
- lName.setBackgroundDrawable(bg);
+ public VH onCreateViewHolder(final ViewGroup parent, final int viewType) {
+ if (viewType == TYPE_CATEGORIES) {
+ return new VH(getLayoutInflater().inflate(R.layout.search_book_filter_categories, parent, false), viewType);
} else {
- lName.setTextColor(U.getForegroundColorOnDarkBackgroundByBookId(book.bookId));
- lName.setBackgroundColor(0x0);
+ final TextView res = new TextView(SearchBookFilterActivity.this);
+ res.setLayoutParams(new GridLayoutManager.LayoutParams(0 /* will be ignored */, getResources().getDimensionPixelSize(R.dimen.goto_grid_cell_height)));
+ res.setGravity(Gravity.CENTER);
+ res.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
+ return new VH(res, viewType);
}
}
@Override
- public int getCount() {
- return books_grid.length;
+ public void onBindViewHolder(final VH holder, final int position) {
+ if (holder.viewType == TYPE_CATEGORIES) {
+ for (int[] bookCategoryMapping : bookCategoryMappings) {
+ final CheckBox checkBox = V.get(holder.itemView, bookCategoryMapping[0]);
+ checkBox.setOnCheckedChangeListener(null);
+
+ { // show current state
+ // all books related to this checkbox are on?
+ boolean all_on = true;
+ for (int i = 1; i < bookCategoryMapping.length; i++) {
+ if (!selectedBookIds.get(bookCategoryMapping[i])) {
+ all_on = false;
+ break;
+ }
+ }
+
+ checkBox.setChecked(all_on);
+ }
+
+ { // then, put a change listener
+ checkBox.setOnCheckedChangeListener((buttonView, isChecked) -> {
+ // all on?
+ boolean all_on = true;
+ for (int i = 1; i < bookCategoryMapping.length; i++) {
+ if (!selectedBookIds.get(bookCategoryMapping[i])) {
+ all_on = false;
+ break;
+ }
+ }
+
+ for (int i = 1; i < bookCategoryMapping.length; i++) {
+ selectedBookIds.put(bookCategoryMapping[i], !all_on);
+ }
+
+ notifyDataSetChanged();
+ });
+ }
+ }
+ } else {
+ final TextView lName = (TextView) holder.itemView;
+ final Book book = getBookFromPosition(position);
+
+ lName.setText(BookNameSorter.getBookAbbr(book));
+
+ if (selectedBookIds.get(book.bookId)) {
+ lName.setTextColor(0xffffffff);
+ final ColorDrawable color = new ColorDrawable(U.getBackgroundColorByBookId(book.bookId));
+ final InsetDrawable bg = new InsetDrawable(color, getResources().getDimensionPixelOffset(R.dimen.goto_grid_cell_inset));
+ //noinspection deprecation
+ lName.setBackgroundDrawable(bg);
+ } else {
+ lName.setTextColor(U.getForegroundColorOnDarkBackgroundByBookId(book.bookId));
+ lName.setBackgroundColor(0x0);
+ }
+
+ lName.setOnClickListener(v -> {
+ final boolean oldstate = selectedBookIds.get(book.bookId);
+ final boolean newstate = !oldstate;
+ selectedBookIds.put(book.bookId, newstate);
+ notifyDataSetChanged();
+ });
+ }
}
@Override
- public Book getItem(int position) {
- return books_grid[position];
+ public int getItemCount() {
+ return 1 + books_grid.length;
}
+ public Book getBookFromPosition(int position) {
+ return books_grid[position - 1];
+ }
}
}
\ No newline at end of file
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/ac/SecretSettingsActivity.java b/Alkitab/src/main/java/yuku/alkitab/base/ac/SecretSettingsActivity.java
index 48ee6cc56..342203a5e 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/ac/SecretSettingsActivity.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/ac/SecretSettingsActivity.java
@@ -72,11 +72,6 @@ public class SecretSettingsActivity extends BasePreferenceActivity {
return true;
};
- Preference.OnPreferenceClickListener secret_old_v3_marker_import = preference -> {
- startActivity(new Intent(App.context, YukuAlkitabImportOfferActivity.class));
- return true;
- };
-
Preference.OnPreferenceClickListener secret_reset_read_announcements = preference -> {
final TLongSet read = Announce.getReadAnnouncementIds();
Preferences.remove(Prefkey.announce_read_ids);
@@ -95,7 +90,6 @@ protected void onCreate(Bundle savedInstanceState) {
findPreference("secret_progress_mark_history").setOnPreferenceClickListener(secret_progress_mark_history_click);
findPreference("secret_version_table").setOnPreferenceClickListener(secret_version_table_click);
findPreference("secret_sync_debug").setOnPreferenceClickListener(secret_sync_debug);
- findPreference("secret_old_v3_marker_import").setOnPreferenceClickListener(secret_old_v3_marker_import);
findPreference("secret_reset_read_announcements").setOnPreferenceClickListener(secret_reset_read_announcements);
}
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/ac/SettingsActivity.java b/Alkitab/src/main/java/yuku/alkitab/base/ac/SettingsActivity.java
index 2052b8388..3df37bcd5 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/ac/SettingsActivity.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/ac/SettingsActivity.java
@@ -1,20 +1,27 @@
package yuku.alkitab.base.ac;
-import android.app.Activity;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.Handler;
-import android.preference.CheckBoxPreference;
-import android.preference.ListPreference;
-import android.preference.Preference;
-import android.preference.PreferenceFragment;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentTransaction;
+import android.support.v7.preference.CheckBoxPreference;
+import android.support.v7.preference.ListPreference;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceFragmentCompat;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.util.TypedValue;
import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
import com.afollestad.materialdialogs.AlertDialogWrapper;
+import yuku.afw.V;
import yuku.afw.storage.Preferences;
import yuku.alkitab.base.App;
import yuku.alkitab.base.IsiActivity;
-import yuku.alkitab.base.ac.base.BasePreferenceActivity;
+import yuku.alkitab.base.ac.base.BaseActivity;
import yuku.alkitab.base.config.AppConfig;
import yuku.alkitab.base.sync.SyncSettingsActivity;
import yuku.alkitab.base.util.ChangeLanguageHelper;
@@ -22,58 +29,97 @@
import yuku.alkitab.base.widget.VerseItem;
import yuku.alkitab.debug.R;
-import java.util.List;
+public class SettingsActivity extends BaseActivity {
+ private static final String EXTRA_subClassName = "subClassName";
-import static yuku.alkitab.base.util.Literals.List;
+ static class Header {
+ int titleResId;
+ Class extends PreferenceFragmentCompat> clazz;
+ Intent clickIntent;
-public class SettingsActivity extends BasePreferenceActivity {
- public List VALID_FRAGMENT_NAMES = List(
- DisplayFragment.class.getName(),
- UsageFragment.class.getName(),
- CopyShareFragment.class.getName()
- );
- Header firstHeaderWithFragment;
+ public Header(final int titleResId, final Class extends PreferenceFragmentCompat> clazz, final Intent clickIntent) {
+ this.titleResId = titleResId;
+ this.clazz = clazz;
+ this.clickIntent = clickIntent;
+ }
+ }
+
+ static Header[] headers = {
+ new Header(R.string.pref_sync_title, null, new Intent(App.context, SyncSettingsActivity.class)),
+ new Header(R.string.pref_penampilan_layar, DisplayFragment.class, null),
+ new Header(R.string.pref_penggunaan, UsageFragment.class, null),
+ new Header(R.string.pref_copy_share, CopyShareFragment.class, null),
+ };
+
+ RecyclerView lsHeaders;
+ HeadersAdapter headersAdapter;
public static Intent createIntent() {
return new Intent(App.context, SettingsActivity.class);
}
- @Override
- public void onBuildHeaders(final List target) {
- super.onBuildHeaders(target);
-
- loadHeadersFromResource(R.xml.settings_headers, target);
+ private static Intent createSubIntent(Class extends PreferenceFragmentCompat> subClass) {
+ return new Intent(App.context, SettingsActivity.class)
+ .putExtra(EXTRA_subClassName, subClass.getName());
+ }
- // look for first header with a fragment
- for (final Header header : target) {
- if (header.fragment != null) {
- firstHeaderWithFragment = header;
- break;
- }
+ @Override
+ protected void onCreate(final Bundle savedInstanceState) {
+ super.enableNonToolbarUpButton();
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_settings);
+
+ final String subClassName = getIntent().getStringExtra(EXTRA_subClassName);
+ if (subClassName == null) {
+ lsHeaders = V.get(this, R.id.lsHeaders);
+ lsHeaders.setLayoutManager(new LinearLayoutManager(this));
+ lsHeaders.setAdapter(headersAdapter = new HeadersAdapter());
+ } else {
+ final FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
+ ft.replace(R.id.fragment_container, Fragment.instantiate(this, subClassName), subClassName);
+ ft.commit();
}
+ }
- for (final Header header : target) {
- if (header.id == R.id.header_id_sync) {
- header.intent = new Intent(App.context, SyncSettingsActivity.class);
- }
+ static class VH extends RecyclerView.ViewHolder {
+ public VH(final View itemView) {
+ super(itemView);
}
}
- @Override
- public Header onGetInitialHeader() {
- return firstHeaderWithFragment;
- }
+ class HeadersAdapter extends RecyclerView.Adapter {
+ final TypedValue tv = new TypedValue();
- @Override
- protected boolean isValidFragment(final String fragmentName) {
- return VALID_FRAGMENT_NAMES.contains(fragmentName);
- }
+ @Override
+ public VH onCreateViewHolder(final ViewGroup parent, final int viewType) {
+ final View v = getLayoutInflater().inflate(android.R.layout.simple_list_item_1, parent, false);
+ getTheme().resolveAttribute(R.attr.selectableItemBackground, tv, true);
+ v.setBackgroundResource(tv.resourceId);
+ return new VH(v);
+ }
+
+ @Override
+ public void onBindViewHolder(final VH holder, final int position) {
+ final Header header = headers[position];
+ ((TextView) holder.itemView).setText(header.titleResId);
+ holder.itemView.setOnClickListener(v -> {
+ if (header.clickIntent != null) {
+ startActivity(header.clickIntent);
+ } else if (header.clazz != null) {
+ startActivity(createSubIntent(header.clazz));
+ }
+ });
+ }
- public static class DisplayFragment extends PreferenceFragment {
@Override
- public void onCreate(final Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
+ public int getItemCount() {
+ return headers.length;
+ }
+ }
+ public static class DisplayFragment extends PreferenceFragmentCompat {
+ @Override
+ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
addPreferencesFromResource(R.xml.settings_display);
final ListPreference pref_language = (ListPreference) findPreference(getString(R.string.pref_language_key));
@@ -86,9 +132,7 @@ public void onCreate(final Bundle savedInstanceState) {
ChangeLanguageHelper.notifyLocaleChanged();
// restart this activity
- final Activity ac = getActivity();
- ac.finish();
- startActivity(ac.getIntent());
+ getActivity().recreate();
});
return true;
});
@@ -118,11 +162,9 @@ public void onCreate(final Bundle savedInstanceState) {
}
}
- public static class UsageFragment extends PreferenceFragment {
+ public static class UsageFragment extends PreferenceFragmentCompat {
@Override
- public void onCreate(final Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
+ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
addPreferencesFromResource(R.xml.settings_usage);
final ListPreference pref_volumeButtonNavigation = (ListPreference) findPreference(getString(R.string.pref_volumeButtonNavigation_key));
@@ -162,11 +204,9 @@ public void onCreate(final Bundle savedInstanceState) {
}
}
- public static class CopyShareFragment extends PreferenceFragment {
+ public static class CopyShareFragment extends PreferenceFragmentCompat {
@Override
- public void onCreate(final Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
+ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
addPreferencesFromResource(R.xml.settings_copy_share);
}
}
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/ac/ShareActivity.java b/Alkitab/src/main/java/yuku/alkitab/base/ac/ShareActivity.java
index aafadb38c..4dbc397d2 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/ac/ShareActivity.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/ac/ShareActivity.java
@@ -58,7 +58,8 @@ public static Result obtainResult(Intent data) {
}
@Override protected void onCreate(Bundle savedInstanceState) {
- super.onCreateWithNonToolbarUpButton(savedInstanceState);
+ enableNonToolbarUpButton();
+ super.onCreate(savedInstanceState);
setContentView(R.layout.activity_share);
String title = getIntent().getStringExtra(Intent.EXTRA_TITLE);
@@ -180,7 +181,7 @@ public ResolveListAdapter(Context context, Intent intent, Intent[] initialIntent
}
ActivityInfo ai = ii.resolveActivityInfo(getPackageManager(), 0);
if (ai == null) {
- Log.w("ResolverActivity", "No activity found for " + ii); //$NON-NLS-1$ //$NON-NLS-2$
+ Log.w("ResolverActivity", "No activity found for " + ii);
continue;
}
ResolveInfo ri = new ResolveInfo();
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/ac/SongViewActivity.java b/Alkitab/src/main/java/yuku/alkitab/base/ac/SongViewActivity.java
index 523cec401..3dd498d2f 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/ac/SongViewActivity.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/ac/SongViewActivity.java
@@ -4,10 +4,10 @@
import android.content.Intent;
import android.media.MediaPlayer;
import android.net.Uri;
-import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.Nullable;
+import android.support.design.widget.Snackbar;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.app.ShareCompat;
import android.support.v4.widget.DrawerLayout;
@@ -25,7 +25,6 @@
import android.view.Window;
import android.webkit.WebView;
import android.webkit.WebViewClient;
-import android.widget.Toast;
import com.afollestad.materialdialogs.AlertDialogWrapper;
import com.afollestad.materialdialogs.MaterialDialog;
import yuku.afw.V;
@@ -83,7 +82,7 @@ public class SongViewActivity extends BaseLeftDrawerActivity implements SongFrag
DrawerLayout drawerLayout;
LeftDrawer.Songs leftDrawer;
- TwofingerLinearLayout song_container;
+ TwofingerLinearLayout root;
ViewGroup no_song_data_container;
View bDownload;
View circular_progress;
@@ -383,12 +382,12 @@ public void onDrawerOpened(final View drawerView) {
}
});
- song_container = V.get(this, R.id.song_container);
+ root = V.get(this, R.id.root);
no_song_data_container = V.get(this, R.id.no_song_data_container);
bDownload = V.get(this, R.id.bDownload);
- song_container.setTwofingerEnabled(false);
- song_container.setListener(song_container_listener);
+ root.setTwofingerEnabled(false);
+ root.setListener(song_container_listener);
bDownload.setOnClickListener(v -> openDownloadSongBookPage());
}
@@ -476,12 +475,7 @@ void checkAudioExistance() {
if (U.equals(currentBookName, checkedBookName) && currentSong != null && U.equals(currentSong.code, checkedCode)) {
runOnUiThread(() -> {
if (mediaPlayerController.canHaveNewUrl()) {
- final String baseUrl;
- if (Build.VERSION.SDK_INT >= 14) {
- baseUrl = "https://alkitab-host.appspot.com/addon/audio/";
- } else {
- baseUrl = "http://alkitab-host.appspot.com/addon/audio/"; // no streaming https support in old Android
- }
+ final String baseUrl = "https://alkitab-host.appspot.com/addon/audio/";
final String url = baseUrl + getAudioFilename(currentBookName, currentSong.code);
if (response.contains("extension=mp3")) {
mediaPlayerController.mediaKnownToExist(url, false);
@@ -544,7 +538,7 @@ void checkAudioExistance() {
if (currentSong != null) {
U.copyToClipboard(convertSongToText(currentSong));
- Toast.makeText(this, R.string.sn_copied, Toast.LENGTH_SHORT).show();
+ Snackbar.make(root, R.string.sn_copied, Snackbar.LENGTH_SHORT).show();
}
} return true;
@@ -824,7 +818,7 @@ void displaySong(String bookName, @Nullable Song song) {
}
void displaySong(String bookName, @Nullable Song song, boolean onCreate) {
- song_container.setVisibility(song != null? View.VISIBLE: View.GONE);
+ root.setVisibility(song != null ? View.VISIBLE : View.GONE);
no_song_data_container.setVisibility(song != null? View.GONE: View.VISIBLE);
if (!onCreate) {
@@ -847,7 +841,7 @@ void displaySong(String bookName, @Nullable Song song, boolean onCreate) {
templateCustomVars.putString("patch_text_open_link", getString(R.string.patch_text_open_link));
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
- ft.replace(R.id.song_container, SongFragment.create(song, "templates/song.html", templateCustomVars));
+ ft.replace(R.id.root, SongFragment.create(song, "templates/song.html", templateCustomVars));
ft.commitAllowingStateLoss();
currentBookName = bookName;
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/ac/VersionsActivity.java b/Alkitab/src/main/java/yuku/alkitab/base/ac/VersionsActivity.java
index 582a72e76..f31c2ddac 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/ac/VersionsActivity.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/ac/VersionsActivity.java
@@ -15,6 +15,7 @@
import android.os.Environment;
import android.provider.MediaStore;
import android.provider.Settings;
+import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
@@ -42,10 +43,8 @@
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.TextView;
-import android.widget.Toast;
import com.afollestad.materialdialogs.AlertDialogWrapper;
import com.afollestad.materialdialogs.MaterialDialog;
-import com.google.samples.apps.iosched.ui.widget.SlidingTabLayout;
import com.mobeta.android.dslv.DragSortController;
import com.mobeta.android.dslv.DragSortListView;
import yuku.afw.V;
@@ -102,10 +101,10 @@ public class VersionsActivity extends BaseActivity {
private static final int REQCODE_openFile = 1;
- SectionsPagerAdapter mSectionsPagerAdapter;
+ SectionsPagerAdapter sectionsPagerAdapter;
- ViewPager mViewPager;
- SlidingTabLayout slidingTabs;
+ ViewPager viewPager;
+ TabLayout tablayout;
String query_text;
public static Intent createIntent() {
@@ -114,6 +113,7 @@ public static Intent createIntent() {
@Override
protected void onCreate(Bundle savedInstanceState) {
+ super.willNeedStoragePermission();
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_versions);
@@ -126,15 +126,17 @@ protected void onCreate(Bundle savedInstanceState) {
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
- mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
+ sectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
- mViewPager = V.get(this, R.id.viewPager);
- mViewPager.setAdapter(mSectionsPagerAdapter);
+ viewPager = V.get(this, R.id.viewPager);
+ viewPager.setAdapter(sectionsPagerAdapter);
- slidingTabs = V.get(this, R.id.sliding_tabs);
- slidingTabs.setCustomTabColorizer(position -> getResources().getColor(R.color.accent));
- slidingTabs.setViewPager(mViewPager);
+ tablayout = V.get(this, R.id.tablayout);
+ tablayout.setTabMode(TabLayout.MODE_SCROLLABLE);
+ tablayout.setTabsFromPagerAdapter(sectionsPagerAdapter);
+ tablayout.setOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(viewPager));
+ viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tablayout));
processIntent(getIntent(), "onCreate");
@@ -164,7 +166,7 @@ private void checkAndProcessOpenFileIntent(Intent intent) {
if (!U.equals(intent.getAction(), Intent.ACTION_VIEW)) return;
// we are trying to open a file, so let's go to the DOWNLOADED tab, as it is more relevant.
- mViewPager.setCurrentItem(1);
+ viewPager.setCurrentItem(1);
Uri uri = intent.getData();
@@ -377,7 +379,7 @@ void clickOnOpenFile() {
config.mode = FileChooserConfig.Mode.Open;
config.initialDir = Environment.getExternalStorageDirectory().getAbsolutePath();
config.title = getString(R.string.ed_choose_pdb_or_yes_file);
- config.pattern = ".*\\.(?i:pdb|yes|yes\\.gz)"; //$NON-NLS-1$
+ config.pattern = ".*\\.(?i:pdb|yes|yes\\.gz)";
startActivityForResult(FileChooserActivity.createIntent(App.context, config), REQCODE_openFile);
} else {
@@ -439,7 +441,7 @@ private void handleFileOpenPdb(final String pdbFilename) {
ConvertOptionsDialog.ConvertOptionsCallback callback = new ConvertOptionsDialog.ConvertOptionsCallback() {
private void showPdbReadErrorDialog(Throwable exception) {
final StringWriter sw = new StringWriter(400);
- sw.append('(').append(exception.getClass().getName()).append("): ").append(exception.getMessage()).append('\n'); //$NON-NLS-1$
+ sw.append('(').append(exception.getClass().getName()).append("): ").append(exception.getMessage()).append('\n');
exception.printStackTrace(new PrintWriter(sw));
new AlertDialogWrapper.Builder(VersionsActivity.this)
@@ -461,7 +463,7 @@ private void showResult(final String filenameyes, Throwable exception, List 0) {
StringBuilder msg = new StringBuilder(getString(R.string.ed_the_following_books_from_the_pdb_file_are_not_recognized) + '\n');
for (String s: wronglyConvertedBookNames) {
- msg.append("- ").append(s).append('\n'); //$NON-NLS-1$
+ msg.append("- ").append(s).append('\n');
}
new AlertDialogWrapper.Builder(VersionsActivity.this)
@@ -490,12 +492,12 @@ private void showResult(final String filenameyes, Throwable exception, List() {
@Override protected File doInBackground(Void... params) {
- String tmpfile3 = filename + "-" + (int)(Math.random() * 100000) + ".tmp3"; //$NON-NLS-1$ //$NON-NLS-2$
+ String tmpfile3 = filename + "-" + (int)(Math.random() * 100000) + ".tmp3";
try {
GZIPInputStream in = new GZIPInputStream(new FileInputStream(filename));
FileOutputStream out = new FileOutputStream(tmpfile3); // decompressed file
@@ -696,12 +698,12 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) {
boolean renameOk = new File(tmpfile3).renameTo(maybeDecompressed);
if (!renameOk) {
- throw new RuntimeException("Failed to rename!"); //$NON-NLS-1$
+ throw new RuntimeException("Failed to rename!");
}
} catch (Exception e) {
return null;
} finally {
- Log.d(TAG, "menghapus tmpfile3: " + tmpfile3); //$NON-NLS-1$
+ Log.d(TAG, "menghapus tmpfile3: " + tmpfile3);
new File(tmpfile3).delete();
}
return maybeDecompressed;
@@ -715,14 +717,17 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) {
}
}.execute();
}
- } else if (filename.toLowerCase(Locale.US).endsWith(".yes")) { //$NON-NLS-1$
+ } else if (filename.toLowerCase(Locale.US).endsWith(".yes")) {
App.trackEvent("versions_open_yes");
handleFileOpenYes(filename);
- } else if (filename.toLowerCase(Locale.US).endsWith(".pdb")) { //$NON-NLS-1$
+ } else if (filename.toLowerCase(Locale.US).endsWith(".pdb")) {
App.trackEvent("versions_open_pdb");
handleFileOpenPdb(filename);
} else {
- Toast.makeText(App.context, R.string.ed_invalid_file_selected, Toast.LENGTH_SHORT).show();
+ new MaterialDialog.Builder(this)
+ .content(R.string.ed_invalid_file_selected)
+ .positiveText(R.string.ok)
+ .show();
}
return;
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/ac/YukuAlkitabImportOfferActivity.java b/Alkitab/src/main/java/yuku/alkitab/base/ac/YukuAlkitabImportOfferActivity.java
deleted file mode 100644
index 07ec844b0..000000000
--- a/Alkitab/src/main/java/yuku/alkitab/base/ac/YukuAlkitabImportOfferActivity.java
+++ /dev/null
@@ -1,153 +0,0 @@
-package yuku.alkitab.base.ac;
-
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.Environment;
-import android.util.TypedValue;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.Button;
-import android.widget.ListView;
-import android.widget.TextView;
-import com.afollestad.materialdialogs.AlertDialogWrapper;
-import yuku.afw.V;
-import yuku.afw.storage.Preferences;
-import yuku.afw.widget.EasyAdapter;
-import yuku.alkitab.base.App;
-import yuku.alkitab.base.ac.base.BaseActivity;
-import yuku.alkitab.base.storage.Prefkey;
-import yuku.alkitab.base.util.BookmarkImporter;
-import yuku.alkitab.debug.R;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FilenameFilter;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-public class YukuAlkitabImportOfferActivity extends BaseActivity {
-
- TextView tImportDesc;
- Button bCancel;
- Button bNoMore;
- ListView lsBackupFiles;
- BackupFilesAdapter adapter;
-
- public static Intent createIntent() {
- return new Intent(App.context, YukuAlkitabImportOfferActivity.class);
- }
-
- @Override
- protected void onCreate(final Bundle savedInstanceState) {
- super.onCreateWithNonToolbarUpButton(savedInstanceState);
- setContentView(R.layout.activity_yuku_alkitab_import_offer);
-
- tImportDesc = V.get(this, R.id.tImportDesc);
- bCancel = V.get(this, R.id.bCancel);
- bNoMore = V.get(this, R.id.bNoMore);
- lsBackupFiles = V.get(this, R.id.lsBackupFiles);
-
- lsBackupFiles.setAdapter(adapter = new BackupFilesAdapter());
- lsBackupFiles.setOnItemClickListener((parent, view, position, id) -> {
- final FileInputStream fis;
- try {
- fis = new FileInputStream(adapter.getFile(position));
- BookmarkImporter.importBookmarks(YukuAlkitabImportOfferActivity.this, fis, true);
- Preferences.setInt(Prefkey.stop_import_yuku_alkitab_backups, 2);
- } catch (FileNotFoundException e) {
- new AlertDialogWrapper.Builder(YukuAlkitabImportOfferActivity.this)
- .setMessage(R.string.marker_migrate_error_opening_backup_file)
- .setPositiveButton(R.string.ok, null)
- .show();
- }
- });
-
- bCancel.setOnClickListener(v -> finish());
-
- bNoMore.setOnClickListener(v -> new AlertDialogWrapper.Builder(this)
- .setMessage(R.string.marker_migrate_no_more_confirmation)
- .setPositiveButton(R.string.ok, (dialog, which) -> {
- Preferences.setInt(Prefkey.stop_import_yuku_alkitab_backups, 1);
- finish();
- })
- .setNegativeButton(R.string.cancel, null)
- .show());
- }
-
- class BackupFilesAdapter extends EasyAdapter {
- final List files = new ArrayList<>();
- final java.text.DateFormat sdf = android.text.format.DateFormat.getDateFormat(YukuAlkitabImportOfferActivity.this);
-
- BackupFilesAdapter() {
- final File dir = new File(Environment.getExternalStorageDirectory(), "bible");
- if (!dir.exists()) return;
-
- final File[] files = dir.listFiles(new FilenameFilter() {
- final Matcher m = getBackupFilenameMatcher();
-
- @Override
- public boolean accept(final File dir, final String filename) {
- m.reset(filename);
- return m.matches();
- }
- });
-
- if (files == null || files.length == 0) {
- return;
- }
-
- // sort from newest to oldest
- Arrays.sort(files, (lhs, rhs) -> {
- final long cmp = rhs.lastModified() - lhs.lastModified();
- if (cmp > 0) return 1;
- if (cmp < 0) return -1;
- return 0;
- });
-
- Collections.addAll(this.files, files);
- }
-
- @Override
- public View newView(final int position, final ViewGroup parent) {
- return getLayoutInflater().inflate(R.layout.item_yuku_alkitab_import_offer, parent, false);
- }
-
- @Override
- public void bindView(final View view, final int position, final ViewGroup parent) {
- final TextView text1 = V.get(view, android.R.id.text1);
- final TextView text2 = V.get(view, android.R.id.text2);
-
- final File file = files.get(position);
-
- final TypedValue tv = new TypedValue();
- getTheme().resolveAttribute(android.R.attr.textAppearanceMedium, tv, true);
- text1.setTextAppearance(text1.getContext(), tv.data);
-
- if (position == 0) {
- text1.setText(R.string.marker_migrate_import_from_newest);
- } else {
- text1.setText(R.string.marker_migrate_import_from_other);
- }
- text2.setText(getString(R.string.marker_migrate_filename_dated, file.getName(), sdf.format(new Date(file.lastModified()))));
- }
-
- @Override
- public int getCount() {
- return files.size();
- }
-
- File getFile(int position) {
- return files.get(position);
- }
- }
-
- public static Matcher getBackupFilenameMatcher() {
- return Pattern.compile("yuku.alkitab(\\.kjv)?-(backup|autobackup-[0-9-]+)\\.xml").matcher("");
- }
-}
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/ac/base/BaseActivity.java b/Alkitab/src/main/java/yuku/alkitab/base/ac/base/BaseActivity.java
index ca1d52288..93e3f7e89 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/ac/base/BaseActivity.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/ac/base/BaseActivity.java
@@ -1,25 +1,44 @@
package yuku.alkitab.base.ac.base;
+import android.Manifest;
import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.res.Configuration;
import android.graphics.drawable.ColorDrawable;
+import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
+import android.provider.Settings;
+import android.support.v4.app.ActivityCompat;
import android.support.v4.app.NavUtils;
import android.support.v4.app.TaskStackBuilder;
+import android.support.v4.content.ContextCompat;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
+import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.util.TypedValue;
import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import com.afollestad.materialdialogs.MaterialDialog;
import yuku.afw.storage.Preferences;
import yuku.alkitab.base.storage.Prefkey;
import yuku.alkitab.base.util.ChangeLanguageHelper;
import yuku.alkitab.debug.R;
-public abstract class BaseActivity extends AppCompatActivity {
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import static yuku.alkitab.base.util.Literals.Array;
+
+public abstract class BaseActivity extends AppCompatActivity implements ActivityCompat.OnRequestPermissionsResultCallback {
public static final String TAG = BaseActivity.class.getSimpleName();
- private boolean withNonToolbarUpButton;
+ private static final int REQCODE_PERMISSION_storage = 1;
+ private static final int REQCODE_permissionSettings = 9970;
+
+ private boolean enableNonToolbarUpButton;
+ private boolean willNeedStoragePermission;
private int lastKnownLocaleSerialNumber;
@@ -63,28 +82,139 @@ protected void applyActionBarAndStatusBarColors() {
}
}
+ /**
+ * Call this from subclasses before super.onCreate() to enable up button.
+ */
+ protected void enableNonToolbarUpButton() {
+ this.enableNonToolbarUpButton = true;
+ }
+
+ /**
+ * Call this from subclasses before super.onCreate() to make
+ * the activity ask for storage permission and do not proceed
+ * if the permission is not granted.
+ */
+ protected void willNeedStoragePermission() {
+ this.willNeedStoragePermission = true;
+ }
+
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
lastKnownLocaleSerialNumber = ChangeLanguageHelper.getLocaleSerialCounter();
+
+ if (this.enableNonToolbarUpButton) {
+ final ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ }
+ }
+
+ if (willNeedStoragePermission) {
+ askStoragePermission();
+ }
}
- protected void onCreateWithNonToolbarUpButton(Bundle savedInstanceState) {
- this.withNonToolbarUpButton = true;
+ private void askStoragePermission() {
+ if (!(
+ Build.VERSION.SDK_INT < 16
+ || (
+ ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
+ && ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
+ )
+ )) {
+ if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
+ ||ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_EXTERNAL_STORAGE)
+ ) {
+ final AtomicBoolean oked = new AtomicBoolean(false);
+ new MaterialDialog.Builder(this)
+ .content(R.string.storage_permission_rationale)
+ .positiveText(R.string.ok)
+ .onPositive((materialDialog, dialogAction) -> {
+ oked.set(true);
+ ActivityCompat.requestPermissions(this, Array(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE), REQCODE_PERMISSION_storage);
+ })
+ .dismissListener(dialog -> {
+ if (!oked.get()) {
+ finish();
+ }
+ })
+ .show();
+ } else {
+ ActivityCompat.requestPermissions(this, Array(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE), REQCODE_PERMISSION_storage);
+ }
+ } else {
+ onNeededPermissionsGranted(true);
+ }
+ }
- super.onCreate(savedInstanceState);
+ /**
+ * Override this to do something after we confirm that all needed permissions are granted.
+ * This is only called if {@link #willNeedStoragePermission()} was called.
+ * @param immediatelyGranted whether the permission is granted immediately without leaving the first onCreate().
+ * Use this to determine whether we need to do initialization (e.g. load dir contents)
+ * and to determine whether it is safe to init now.
+ */
+ protected void onNeededPermissionsGranted(boolean immediatelyGranted) {
+ }
- final ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
+ @Override
+ public void onRequestPermissionsResult(final int requestCode, final String[] permissions, final int[] grantResults) {
+ if (requestCode == REQCODE_PERMISSION_storage) {
+ // all must be granted
+ boolean allGranted = true;
+ for (final int grantResult : grantResults) {
+ if (grantResult != PackageManager.PERMISSION_GRANTED) {
+ allGranted = false;
+ }
+ }
+
+ if (allGranted) {
+ onNeededPermissionsGranted(false);
+ } else {
+ if (!ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
+ || !ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_EXTERNAL_STORAGE)) {
+
+ // user selects do not ask again
+ final AtomicBoolean oked = new AtomicBoolean(false);
+ new MaterialDialog.Builder(this)
+ .content("You need to have the Storage permission enabled to continue, because we need to store shared media such as Bible versions and fonts.")
+ .positiveText(R.string.ok)
+ .onPositive((materialDialog, dialogAction) -> {
+ oked.set(true);
+ startActivityForResult(new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).setData(Uri.fromParts("package", getPackageName(), null)), REQCODE_permissionSettings);
+ })
+ .negativeText(R.string.cancel)
+ .dismissListener(dialog -> {
+ if (!oked.get()) {
+ finish();
+ }
+ })
+ .show();
+ } else {
+ finish();
+ }
+ }
+
+ return;
}
- lastKnownLocaleSerialNumber = ChangeLanguageHelper.getLocaleSerialCounter();
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+ }
+
+ @Override
+ protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
+ if (requestCode == REQCODE_permissionSettings) {
+ askStoragePermission();
+ return;
+ }
+
+ super.onActivityResult(requestCode, resultCode, data);
}
@Override public boolean onOptionsItemSelected(MenuItem item) {
- if (withNonToolbarUpButton && item.getItemId() == android.R.id.home) {
+ if (enableNonToolbarUpButton && item.getItemId() == android.R.id.home) {
navigateUp();
return true;
}
@@ -107,4 +237,24 @@ protected void navigateUp() {
NavUtils.navigateUpTo(this, upIntent);
}
}
+
+ @Override
+ public void onConfigurationChanged(final Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+
+ { // reconfigure toolbar height (Need to have a toolbar with id toolbar)
+ final View v = findViewById(R.id.toolbar);
+ if (v instanceof Toolbar) {
+ final Toolbar toolbar = (Toolbar) v;
+ final ViewGroup.LayoutParams lp = toolbar.getLayoutParams();
+ final TypedValue tv = new TypedValue();
+ getTheme().resolveAttribute(R.attr.actionBarSize, tv, true);
+ final int h = (int) tv.getDimension(getResources().getDisplayMetrics());
+ lp.height = h;
+ toolbar.setLayoutParams(lp);
+ // Workaround for https://code.google.com/p/android/issues/detail?id=79813
+ toolbar.setMinimumHeight(h);
+ }
+ }
+ }
}
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/br/VersionDownloadCompleteReceiver.java b/Alkitab/src/main/java/yuku/alkitab/base/br/VersionDownloadCompleteReceiver.java
index ff36205c1..3568fb2e8 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/br/VersionDownloadCompleteReceiver.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/br/VersionDownloadCompleteReceiver.java
@@ -11,6 +11,7 @@
import android.widget.Toast;
import yuku.alkitab.base.App;
import yuku.alkitab.base.S;
+import yuku.alkitab.base.ac.AlertDialogActivity;
import yuku.alkitab.base.ac.VersionsActivity;
import yuku.alkitab.base.model.MVersionDb;
import yuku.alkitab.base.storage.YesReaderFactory;
@@ -110,7 +111,11 @@ public void onReceive(Context context, Intent intent) {
pfd.close();
} catch (IOException e) {
Log.e(TAG, "I/O error when saving downloaded version", e);
- Toast.makeText(context, "I/O error when saving downloaded version", Toast.LENGTH_SHORT).show(); // TODO proper msg
+ context.startActivity(
+ AlertDialogActivity.createOkIntent(null, context.getString(R.string.version_download_saving_io_error))
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ );
+ App.getLbm().sendBroadcast(new Intent(VersionsActivity.VersionListFragment.ACTION_RELOAD));
return;
} finally {
DownloadMapper.instance.remove(id);
@@ -120,7 +125,11 @@ public void onReceive(Context context, Intent intent) {
if (reader == null) {
new File(destPath).delete();
- Toast.makeText(context, R.string.version_download_corrupted_file, Toast.LENGTH_SHORT).show(); // TODO proper msg
+ context.startActivity(
+ AlertDialogActivity.createOkIntent(null, context.getString(R.string.version_download_corrupted_file))
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ );
+ App.getLbm().sendBroadcast(new Intent(VersionsActivity.VersionListFragment.ACTION_RELOAD));
return;
}
@@ -146,7 +155,10 @@ public void onReceive(Context context, Intent intent) {
Toast.makeText(App.context, TextUtils.expandTemplate(context.getText(R.string.version_download_complete), mvDb.longName), Toast.LENGTH_LONG).show();
if ("ta".equals(mvDb.locale) || "te".equals(mvDb.locale) || "my".equals(mvDb.locale) || "el".equals(mvDb.locale)) {
- Toast.makeText(App.context, R.string.version_download_need_fonts, Toast.LENGTH_SHORT).show(); // TODO proper msg
+ context.startActivity(
+ AlertDialogActivity.createOkIntent(null, context.getString(R.string.version_download_need_fonts))
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ );
}
App.getLbm().sendBroadcast(new Intent(VersionsActivity.VersionListFragment.ACTION_RELOAD));
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/cp/FileProvider.java b/Alkitab/src/main/java/yuku/alkitab/base/cp/FileProvider.java
deleted file mode 100644
index dec104653..000000000
--- a/Alkitab/src/main/java/yuku/alkitab/base/cp/FileProvider.java
+++ /dev/null
@@ -1,157 +0,0 @@
-package yuku.alkitab.base.cp;
-
-import android.content.ContentProvider;
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.database.MatrixCursor;
-import android.net.Uri;
-import android.os.Environment;
-import android.os.ParcelFileDescriptor;
-import android.provider.OpenableColumns;
-import android.webkit.MimeTypeMap;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-
-/**
- * Provider to support easy sharing of files (public and private) between apps.
- *
- *
AUTHORITY/external/path means external storage path
- *
AUTHORITY/cache/path means internal cache path
- */
-public class FileProvider extends ContentProvider {
- private static final String[] COLUMNS = { OpenableColumns.DISPLAY_NAME, OpenableColumns.SIZE };
-
- @Override
- public boolean onCreate() {
- return true;
- }
-
- @Override
- public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
- final File file = getFileForUri(uri);
-
- if (file == null) {
- throw new IllegalArgumentException("Unknown path in uri: " + uri);
- }
-
- if (!file.isFile() || !file.canRead()) {
- throw new IllegalArgumentException("Can't read file in uri: " + uri);
- }
-
- if (projection == null) {
- projection = COLUMNS;
- }
-
- String[] cols = new String[projection.length];
- Object[] values = new Object[projection.length];
- int i = 0;
- for (String col : projection) {
- if (OpenableColumns.DISPLAY_NAME.equals(col)) {
- cols[i] = OpenableColumns.DISPLAY_NAME;
- values[i++] = file.getName();
- } else if (OpenableColumns.SIZE.equals(col)) {
- cols[i] = OpenableColumns.SIZE;
- values[i++] = file.length();
- }
- }
-
- cols = copyOf(cols, i);
- values = copyOf(values, i);
-
- final MatrixCursor cursor = new MatrixCursor(cols, 1);
- cursor.addRow(values);
- return cursor;
- }
-
- private File getFileForUri(final Uri uri) {
- final String externalPrefix = "/external/";
- final String cachePrefix = "/cache/";
- final String uriPath = uri.getPath();
-
- if (uriPath.startsWith(externalPrefix)) {
- return new File(Environment.getExternalStorageDirectory().getAbsolutePath(), uriPath.substring(externalPrefix.length()));
- } else if (uriPath.startsWith(cachePrefix)) {
- return new File(getContext().getCacheDir().getAbsolutePath(), uriPath.substring(cachePrefix.length()));
- }
- return null;
- }
-
- @Override
- public String getType(Uri uri) {
- final File file = getFileForUri(uri);
-
- final int lastDot = file.getName().lastIndexOf('.');
- if (lastDot >= 0) {
- final String extension = file.getName().substring(lastDot + 1);
- final String mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
- if (mime != null) {
- return mime;
- }
- }
-
- return "application/octet-stream";
- }
-
- @Override
- public Uri insert(Uri uri, ContentValues values) {
- throw new UnsupportedOperationException("No external inserts");
- }
-
- @Override
- public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
- throw new UnsupportedOperationException("No external updates");
- }
-
- @Override
- public int delete(Uri uri, String selection, String[] selectionArgs) {
- throw new UnsupportedOperationException("No external deletes");
- }
-
- @Override
- public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
- final File file = getFileForUri(uri);
- final int fileMode = modeToMode(mode);
- return ParcelFileDescriptor.open(file, fileMode);
- }
-
- private static String[] copyOf(String[] original, int newLength) {
- final String[] result = new String[newLength];
- System.arraycopy(original, 0, result, 0, newLength);
- return result;
- }
-
- private static Object[] copyOf(Object[] original, int newLength) {
- final Object[] result = new Object[newLength];
- System.arraycopy(original, 0, result, 0, newLength);
- return result;
- }
-
- /**
- * Copied from ContentResolver.java
- */
- private static int modeToMode(String mode) {
- int modeBits;
- if ("r".equals(mode)) {
- modeBits = ParcelFileDescriptor.MODE_READ_ONLY;
- } else if ("w".equals(mode) || "wt".equals(mode)) {
- modeBits = ParcelFileDescriptor.MODE_WRITE_ONLY
- | ParcelFileDescriptor.MODE_CREATE
- | ParcelFileDescriptor.MODE_TRUNCATE;
- } else if ("wa".equals(mode)) {
- modeBits = ParcelFileDescriptor.MODE_WRITE_ONLY
- | ParcelFileDescriptor.MODE_CREATE
- | ParcelFileDescriptor.MODE_APPEND;
- } else if ("rw".equals(mode)) {
- modeBits = ParcelFileDescriptor.MODE_READ_WRITE
- | ParcelFileDescriptor.MODE_CREATE;
- } else if ("rwt".equals(mode)) {
- modeBits = ParcelFileDescriptor.MODE_READ_WRITE
- | ParcelFileDescriptor.MODE_CREATE
- | ParcelFileDescriptor.MODE_TRUNCATE;
- } else {
- throw new IllegalArgumentException("Invalid mode: " + mode);
- }
- return modeBits;
- }
-}
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/devotion/ArticleRefheart.java b/Alkitab/src/main/java/yuku/alkitab/base/devotion/ArticleRefheart.java
new file mode 100644
index 000000000..dfe26c87b
--- /dev/null
+++ b/Alkitab/src/main/java/yuku/alkitab/base/devotion/ArticleRefheart.java
@@ -0,0 +1,61 @@
+package yuku.alkitab.base.devotion;
+
+import android.support.annotation.NonNull;
+import android.text.Html;
+import android.text.SpannableStringBuilder;
+import yuku.alkitab.base.ac.DevotionActivity;
+import yuku.alkitab.base.widget.CallbackSpan;
+
+public class ArticleRefheart extends DevotionArticle {
+ public static final String TAG = ArticleRefheart.class.getSimpleName();
+ private String date;
+ private String bodyHtml;
+ private boolean readyToUse;
+
+ public ArticleRefheart(String date) {
+ this.date = date;
+ }
+
+ public ArticleRefheart(String date, String bodyHtml, boolean readyToUse) {
+ this.date = date;
+ this.bodyHtml = bodyHtml;
+ this.readyToUse = readyToUse;
+ }
+
+ @Override
+ public String getDate() {
+ return date;
+ }
+
+ @Override
+ public boolean getReadyToUse() {
+ return readyToUse;
+ }
+
+ @Override
+ public DevotionActivity.DevotionKind getKind() {
+ return DevotionActivity.DevotionKind.REFHEART;
+ }
+
+ @Override
+ public void fillIn(String raw) {
+ bodyHtml = raw;
+ readyToUse = !raw.startsWith("NG");
+ }
+
+ @Override
+ public CharSequence getContent(CallbackSpan.OnClickListener verseClickListener) {
+ final SpannableStringBuilder sb = new SpannableStringBuilder();
+ sb.append(Html.fromHtml(bodyHtml));
+
+ convertLinks(sb, verseClickListener);
+
+ return sb;
+ }
+
+ @Override
+ @NonNull
+ public String getBody() {
+ return bodyHtml;
+ }
+}
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/devotion/ArticleRoc.java b/Alkitab/src/main/java/yuku/alkitab/base/devotion/ArticleRoc.java
new file mode 100644
index 000000000..109cf31bd
--- /dev/null
+++ b/Alkitab/src/main/java/yuku/alkitab/base/devotion/ArticleRoc.java
@@ -0,0 +1,61 @@
+package yuku.alkitab.base.devotion;
+
+import android.support.annotation.NonNull;
+import android.text.Html;
+import android.text.SpannableStringBuilder;
+import yuku.alkitab.base.ac.DevotionActivity;
+import yuku.alkitab.base.widget.CallbackSpan;
+
+public class ArticleRoc extends DevotionArticle {
+ public static final String TAG = ArticleRoc.class.getSimpleName();
+ private String date;
+ private String bodyHtml;
+ private boolean readyToUse;
+
+ public ArticleRoc(String date) {
+ this.date = date;
+ }
+
+ public ArticleRoc(String date, String bodyHtml, boolean readyToUse) {
+ this.date = date;
+ this.bodyHtml = bodyHtml;
+ this.readyToUse = readyToUse;
+ }
+
+ @Override
+ public String getDate() {
+ return date;
+ }
+
+ @Override
+ public boolean getReadyToUse() {
+ return readyToUse;
+ }
+
+ @Override
+ public DevotionActivity.DevotionKind getKind() {
+ return DevotionActivity.DevotionKind.ROC;
+ }
+
+ @Override
+ public void fillIn(String raw) {
+ bodyHtml = raw;
+ readyToUse = !raw.startsWith("NG");
+ }
+
+ @Override
+ public CharSequence getContent(CallbackSpan.OnClickListener verseClickListener) {
+ final SpannableStringBuilder sb = new SpannableStringBuilder();
+ sb.append(Html.fromHtml(bodyHtml));
+
+ convertLinks(sb, verseClickListener);
+
+ return sb;
+ }
+
+ @Override
+ @NonNull
+ public String getBody() {
+ return bodyHtml;
+ }
+}
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/devotion/DevotionArticle.java b/Alkitab/src/main/java/yuku/alkitab/base/devotion/DevotionArticle.java
index 1ecbf5699..00c85a33b 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/devotion/DevotionArticle.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/devotion/DevotionArticle.java
@@ -32,6 +32,9 @@ protected void convertLinks(final SpannableStringBuilder sb, final CallbackSpan.
URLSpan[] spans = sb.getSpans(0, sb.length(), URLSpan.class);
for (URLSpan oldSpan: spans) {
String url = oldSpan.getURL();
+ if (url.startsWith("http:") || url.startsWith("https:")) {
+ continue; // do not change web links
+ }
CallbackSpan newSpan = new CallbackSpan<>(url, verseClickListener);
sb.setSpan(newSpan, sb.getSpanStart(oldSpan), sb.getSpanEnd(oldSpan), 0);
sb.removeSpan(oldSpan);
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/devotion/DevotionDownloader.java b/Alkitab/src/main/java/yuku/alkitab/base/devotion/DevotionDownloader.java
index 8a9c6d510..15422bb60 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/devotion/DevotionDownloader.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/devotion/DevotionDownloader.java
@@ -89,7 +89,7 @@ public void run() {
// success!
article.fillIn(output);
- if (output.startsWith("NG")) { //$NON-NLS-1$
+ if (output.startsWith("NG")) {
broadcastDownloadStatus(App.context.getString(R.string.kesalahan_dalam_mengunduh_namaumum_tgl_tgl_output, kind.title, article.getDate(), output));
} else {
broadcastDownloadStatus(App.context.getString(R.string.berhasil_mengunduh_namaumum_tgl_tgl, kind.title, article.getDate()));
@@ -99,10 +99,10 @@ public void run() {
// let's now store it to db
S.getDb().storeArticleToDevotions(article);
} catch (IOException e) {
- Log.w(TAG, "@@run", e); //$NON-NLS-1$
+ Log.w(TAG, "@@run", e);
broadcastDownloadStatus(App.context.getString(R.string.gagal_mengunduh_namaumum_tgl_tgl, kind.title, article.getDate()));
- Log.d(TAG, "Downloader failed to download"); //$NON-NLS-1$
+ Log.d(TAG, "Downloader failed to download");
}
}
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/fr/GotoDialerFragment.java b/Alkitab/src/main/java/yuku/alkitab/base/fr/GotoDialerFragment.java
index 5a53ccf8a..427197221 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/fr/GotoDialerFragment.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/fr/GotoDialerFragment.java
@@ -1,17 +1,15 @@
package yuku.alkitab.base.fr;
-import android.os.Build;
+import android.content.SharedPreferences;
import android.os.Bundle;
-import android.view.Gravity;
+import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.view.ViewTreeObserver;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.CheckedTextView;
-import android.widget.ScrollView;
import android.widget.Spinner;
import android.widget.TextView;
import yuku.afw.App;
@@ -20,6 +18,7 @@
import yuku.alkitab.base.S;
import yuku.alkitab.base.U;
import yuku.alkitab.base.fr.base.BaseGotoFragment;
+import yuku.alkitab.base.storage.Prefkey;
import yuku.alkitab.base.util.BookNameSorter;
import yuku.alkitab.debug.R;
import yuku.alkitab.model.Book;
@@ -27,9 +26,9 @@
public class GotoDialerFragment extends BaseGotoFragment {
public static final String TAG = GotoDialerFragment.class.getSimpleName();
- private static final String EXTRA_verse = "verse"; //$NON-NLS-1$
- private static final String EXTRA_chapter = "chapter"; //$NON-NLS-1$
- private static final String EXTRA_bookId = "bookId"; //$NON-NLS-1$
+ private static final String EXTRA_verse = "verse";
+ private static final String EXTRA_chapter = "chapter";
+ private static final String EXTRA_bookId = "bookId";
TextView active;
TextView passive;
@@ -83,14 +82,10 @@ public static Bundle createArgs(int bookId, int chapter_1, int verse_1) {
cbBook.setAdapter(adapter = new BookAdapter());
tChapter.setOnClickListener(tChapter_click);
- if (tChapterLabel != null) { // not always present in layout
- tChapterLabel.setOnClickListener(tChapter_click);
- }
+ tChapterLabel.setOnClickListener(tChapter_click);
tVerse.setOnClickListener(tVerse_click);
- if (tVerseLabel != null) { // not always present in layout
- tVerseLabel.setOnClickListener(tVerse_click);
- }
+ tVerseLabel.setOnClickListener(tVerse_click);
V.get(res, R.id.bDigit0).setOnClickListener(button_click);
V.get(res, R.id.bDigit1).setOnClickListener(button_click);
@@ -102,33 +97,40 @@ public static Bundle createArgs(int bookId, int chapter_1, int verse_1) {
V.get(res, R.id.bDigit7).setOnClickListener(button_click);
V.get(res, R.id.bDigit8).setOnClickListener(button_click);
V.get(res, R.id.bDigit9).setOnClickListener(button_click);
- V.get(res, R.id.bDigitC).setOnClickListener(button_click);
- V.get(res, R.id.bDigitSwitch).setOnClickListener(button_click);
+ V.get(res, R.id.bDigitBackspace).setOnClickListener(button_click);
- // if the scrolled content height is not more than the available space, remove the gravity
- final View scrollRoot = V.get(res, R.id.scrollRoot);
- scrollRoot.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
- @Override
- public void onGlobalLayout() {
- final ScrollView.LayoutParams lp = (ScrollView.LayoutParams) scrollRoot.getLayoutParams();
- final int contentHeight = scrollRoot.getMeasuredHeight();
- final int containerHeight = res.getMeasuredHeight();
- lp.gravity = contentHeight <= containerHeight ? Gravity.CENTER_VERTICAL : Gravity.NO_GRAVITY;
- scrollRoot.setLayoutParams(lp);
-
- if (Build.VERSION.SDK_INT >= 16) {
- scrollRoot.getViewTreeObserver().removeOnGlobalLayoutListener(this);
- } else {
- // what!? Deprecated because of typo!?
- //noinspection deprecation
- scrollRoot.getViewTreeObserver().removeGlobalOnLayoutListener(this);
- }
- }
- });
+ showOrHideVerse();
+ Preferences.registerObserver(preferenceChangeListener);
return res;
}
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+
+ Preferences.unregisterObserver(preferenceChangeListener);
+ }
+
+ final SharedPreferences.OnSharedPreferenceChangeListener preferenceChangeListener = (sharedPreferences, key) -> {
+ if (key.equals(Prefkey.gotoAskForVerse.name())) {
+ showOrHideVerse();
+ }
+ };
+
+ void showOrHideVerse() {
+ if (Preferences.getBoolean(Prefkey.gotoAskForVerse, Prefkey.GOTO_ASK_FOR_VERSE_DEFAULT)) {
+ tVerse.setVisibility(View.VISIBLE);
+ tVerseLabel.setVisibility(View.VISIBLE);
+ } else {
+ if (active == tVerse) {
+ activate(tChapter, tVerse);
+ }
+ tVerse.setVisibility(View.GONE);
+ tVerseLabel.setVisibility(View.GONE);
+ }
+ }
+
@Override public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
@@ -152,22 +154,25 @@ public void onItemSelected(AdapterView> parent, View view, int position, long
}
});
- bOk.setOnClickListener(new View.OnClickListener() {
- @Override public void onClick(View v) {
- int chapter = 0;
- int verse = 0;
+ bOk.setOnClickListener(v -> {
+ int selectedChapter_1 = 0;
+ int selectedVerse_1 = 0;
+
+ try {
+ selectedChapter_1 = Integer.parseInt(tChapter.getText().toString());
- try {
- chapter = Integer.parseInt(tChapter.getText().toString());
- verse = Integer.parseInt(tVerse.getText().toString());
- } catch (NumberFormatException e) {
- // let it still be 0
+ if (Preferences.getBoolean(Prefkey.gotoAskForVerse, Prefkey.GOTO_ASK_FOR_VERSE_DEFAULT)) {
+ selectedVerse_1 = Integer.parseInt(tVerse.getText().toString());
+ } else {
+ selectedVerse_1 = 0;
}
+ } catch (NumberFormatException e) {
+ // let it still be 0
+ }
- int bookId = adapter.getItem(cbBook.getSelectedItemPosition()).bookId;
+ final int selectedBookId = adapter.getItem(cbBook.getSelectedItemPosition()).bookId;
- ((GotoFinishListener) getActivity()).onGotoFinished(GotoFinishListener.GOTO_TAB_dialer, bookId, chapter, verse);
- }
+ ((GotoFinishListener) getActivity()).onGotoFinished(GotoFinishListener.GOTO_TAB_dialer, selectedBookId, selectedChapter_1, selectedVerse_1);
});
active = tChapter;
@@ -197,42 +202,24 @@ public void onItemSelected(AdapterView> parent, View view, int position, long
}
};
- View.OnClickListener button_click = new View.OnClickListener() {
- @Override public void onClick(View v) {
- int id = v.getId();
- if (id == R.id.bDigit0) press("0"); //$NON-NLS-1$
- if (id == R.id.bDigit1) press("1"); //$NON-NLS-1$
- if (id == R.id.bDigit2) press("2"); //$NON-NLS-1$
- if (id == R.id.bDigit3) press("3"); //$NON-NLS-1$
- if (id == R.id.bDigit4) press("4"); //$NON-NLS-1$
- if (id == R.id.bDigit5) press("5"); //$NON-NLS-1$
- if (id == R.id.bDigit6) press("6"); //$NON-NLS-1$
- if (id == R.id.bDigit7) press("7"); //$NON-NLS-1$
- if (id == R.id.bDigit8) press("8"); //$NON-NLS-1$
- if (id == R.id.bDigit9) press("9"); //$NON-NLS-1$
- if (id == R.id.bDigitC) press("C"); //$NON-NLS-1$
- if (id == R.id.bDigitSwitch) press(":"); //$NON-NLS-1$
- }
+ View.OnClickListener button_click = v -> {
+ final int id = v.getId();
+ if (id == R.id.bDigit0) press("0");
+ else if (id == R.id.bDigit1) press("1");
+ else if (id == R.id.bDigit2) press("2");
+ else if (id == R.id.bDigit3) press("3");
+ else if (id == R.id.bDigit4) press("4");
+ else if (id == R.id.bDigit5) press("5");
+ else if (id == R.id.bDigit6) press("6");
+ else if (id == R.id.bDigit7) press("7");
+ else if (id == R.id.bDigit8) press("8");
+ else if (id == R.id.bDigit9) press("9");
+ else if (id == R.id.bDigitBackspace) press("backspace");
};
-
-// TODO (move to activity to support keyboard) @Override public boolean onKeyDown(int keyCode, KeyEvent event) {
-// if (keyCode >= KeyEvent.KEYCODE_0 && keyCode <= KeyEvent.KEYCODE_9) {
-// pencet(String.valueOf((char) ('0' + keyCode - KeyEvent.KEYCODE_0)));
-// return true;
-// } else if (keyCode == KeyEvent.KEYCODE_STAR) {
-// pencet("C"); //$NON-NLS-1$
-// return true;
-// } else if (keyCode == KeyEvent.KEYCODE_POUND) {
-// pencet(":"); //$NON-NLS-1$
-// return true;
-// }
-//
-// return super.onKeyDown(keyCode, event);
-// }
int tryReadChapter() {
try {
- return Integer.parseInt("0" + tChapter.getText().toString()); //$NON-NLS-1$
+ return Integer.parseInt("0" + tChapter.getText().toString());
} catch (NumberFormatException e) {
return 0;
}
@@ -240,7 +227,7 @@ int tryReadChapter() {
int tryReadVerse() {
try {
- return Integer.parseInt("0" + tVerse.getText().toString()); //$NON-NLS-1$
+ return Integer.parseInt("0" + tVerse.getText().toString());
} catch (NumberFormatException e) {
return 0;
}
@@ -272,12 +259,10 @@ void fixChapterOverflow() {
void press(String s) {
if (active != null) {
- if (s.equals("C")) { //$NON-NLS-1$
- active.setText(""); //$NON-NLS-1$
- return;
- } else if (s.equals(":")) { //$NON-NLS-1$
- if (passive != null) {
- activate(passive, active);
+ if (s.equals("backspace")) {
+ if (active.length() > 0) {
+ final CharSequence txt = active.getText();
+ active.setText(TextUtils.substring(txt, 0, txt.length() - 1));
}
return;
}
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/fr/GotoDirectFragment.java b/Alkitab/src/main/java/yuku/alkitab/base/fr/GotoDirectFragment.java
index 9e6cb2c8a..6f877ca1f 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/fr/GotoDirectFragment.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/fr/GotoDirectFragment.java
@@ -2,40 +2,59 @@
import android.app.Activity;
import android.os.Bundle;
+import android.support.annotation.Nullable;
import android.text.SpannableStringBuilder;
import android.text.TextUtils;
-import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.EditText;
+import android.widget.AutoCompleteTextView;
+import android.widget.Filter;
+import android.widget.Filterable;
import android.widget.TextView;
import com.afollestad.materialdialogs.AlertDialogWrapper;
+import gnu.trove.map.TIntObjectMap;
+import gnu.trove.map.hash.TIntObjectHashMap;
+import gnu.trove.set.TIntSet;
+import gnu.trove.set.hash.TIntHashSet;
import yuku.afw.V;
+import yuku.afw.widget.EasyAdapter;
import yuku.alkitab.base.S;
import yuku.alkitab.base.fr.base.BaseGotoFragment;
import yuku.alkitab.base.util.Jumper;
+import yuku.alkitab.base.util.Levenshtein;
import yuku.alkitab.debug.R;
+import yuku.alkitab.model.Book;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class GotoDirectFragment extends BaseGotoFragment {
public static final String TAG = GotoDirectFragment.class.getSimpleName();
- private static final String EXTRA_verse = "verse"; //$NON-NLS-1$
- private static final String EXTRA_chapter = "chapter"; //$NON-NLS-1$
- private static final String EXTRA_bookId = "bookId"; //$NON-NLS-1$
+ private static final String EXTRA_verse = "verse";
+ private static final String EXTRA_chapter = "chapter";
+ private static final String EXTRA_bookId = "bookId";
TextView lDirectSample;
- EditText tDirectReference;
+ AutoCompleteTextView tDirectReference;
View bOk;
+ AutoCompleteAdapter adapter;
+
int bookId;
int chapter_1;
int verse_1;
private Activity activity;
+ static class Candidate {
+ String title;
+ int score;
+ boolean bookOnly;
+ }
public static Bundle createArgs(int bookId, int chapter_1, int verse_1) {
Bundle args = new Bundle();
@@ -65,21 +84,25 @@ public void onAttach(final Activity activity) {
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View res = inflater.inflate(R.layout.fragment_goto_direct, container, false);
lDirectSample = V.get(res, R.id.lDirectSample);
+
tDirectReference = V.get(res, R.id.tDirectReference);
- bOk = V.get(res, R.id.bOk);
+ tDirectReference.setAdapter(adapter = new AutoCompleteAdapter());
+ tDirectReference.setOnItemClickListener((parent, view, position, id) -> {
+ if (!adapter.getItem(position).bookOnly) {
+ bOk.performClick();
+ }
+ });
+ bOk = V.get(res, R.id.bOk);
bOk.setOnClickListener(bOk_click);
-
- tDirectReference.setOnEditorActionListener(new TextView.OnEditorActionListener() {
- @Override
- public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
- bOk_click.onClick(bOk);
- return true;
- }
+
+ tDirectReference.setOnEditorActionListener((v, actionId, event) -> {
+ bOk_click.onClick(bOk);
+ return true;
});
return res;
}
-
+
@Override public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
@@ -141,4 +164,165 @@ public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
((GotoFinishListener) activity).onGotoFinished(GotoFinishListener.GOTO_TAB_direct, bookId, chapter, verse);
}
};
+
+ class AutoCompleteAdapter extends EasyAdapter implements Filterable {
+ final List candidates = new ArrayList<>();
+
+ @Override
+ public View newView(final int position, final ViewGroup parent) {
+ return activity.getLayoutInflater().inflate(R.layout.support_simple_spinner_dropdown_item, parent, false);
+ }
+
+ @Override
+ public void bindView(final View view, final int position, final ViewGroup parent) {
+ final TextView tv = (TextView) view;
+ final Candidate candidate = getItem(position);
+ tv.setText(candidate.title);
+ }
+
+ @Override
+ public int getCount() {
+ return candidates == null ? 0 : candidates.size();
+ }
+
+ /**
+ * This may not be removed, or the {@link android.widget.AutoCompleteTextView#setOnItemClickListener(android.widget.AdapterView.OnItemClickListener)} won't work!
+ */
+ @Override
+ public Candidate getItem(final int position) {
+ return candidates.get(position);
+ }
+
+ @Override
+ public Filter getFilter() {
+ return new Filter() {
+ final Book[] books = S.activeVersion.getConsecutiveBooks();
+ final TIntObjectMap bookIndex = new TIntObjectHashMap<>();
+
+ {
+ for (final Book book : books) {
+ bookIndex.put(book.bookId, book);
+ }
+ }
+
+ List bookRefs;
+
+ @Override
+ protected FilterResults performFiltering(@Nullable final CharSequence constraint) {
+ final FilterResults res = new FilterResults();
+
+ if (constraint == null) {
+ res.values = null;
+ res.count = 0;
+ return res;
+ }
+
+ final Jumper jumper = new Jumper(constraint.toString());
+ String bookName = jumper.getUnparsedBook();
+
+ final ArrayList candidates = new ArrayList<>();
+ if (bookName != null) {
+ bookName = bookName.trim().toLowerCase();
+ if (bookName.length() >= 1) {
+ final TIntSet addedBookIds = new TIntHashSet();
+
+ for (final Book book : books) {
+ String title = null;
+ int score = 0;
+
+ final String n = book.shortName.toLowerCase();
+ if (n.startsWith(bookName)) {
+ title = book.shortName;
+ score = 20;
+ } else if (n.contains(bookName)) {
+ title = book.shortName;
+ score = 10;
+ }
+
+ if (score != 0) {
+ addCandidate(jumper, candidates, title, score, book);
+ addedBookIds.add(book.bookId);
+ }
+ }
+
+ // now try the levenstein
+ if (candidates.size() < 5) {
+ List _bookRefs = this.bookRefs;
+ if (_bookRefs == null) {
+ this.bookRefs = _bookRefs = Jumper.createBookCandidates(books);
+ }
+
+ for (final Jumper.BookRef bookRef : _bookRefs) {
+ if (addedBookIds.contains(bookRef.bookId)) continue;
+
+ final int distance = Levenshtein.distance(bookName, bookRef.condensed);
+ final Book book = bookIndex.get(bookRef.bookId);
+ addCandidate(jumper, candidates, book.shortName, -distance, book);
+ addedBookIds.add(bookRef.bookId);
+ }
+ }
+ }
+ }
+
+ Collections.sort(candidates, (lhs, rhs) -> rhs.score - lhs.score);
+
+ res.count = candidates.size();
+ res.values = candidates;
+ return res;
+ }
+
+ private void addCandidate(final Jumper jumper, final ArrayList values, String title, final int score, final Book book) {
+ boolean bookOnly = true;
+
+ // try to add chapter and verse
+ final int chapter_1 = jumper.getChapter();
+ if (chapter_1 != 0) {
+ bookOnly = false;
+ title += " " + chapter_1;
+ final int verse_1 = jumper.getVerse();
+ if (verse_1 != 0) {
+ title += ":" + verse_1;
+ }
+
+ // do not add if the chapter is unavailable
+ if (chapter_1 < 1 || chapter_1 > book.chapter_count) {
+ return;
+ } else {
+ if (verse_1 != 0 && (verse_1 < 1 || verse_1 > book.verse_counts[chapter_1 - 1])) {
+ return;
+ }
+ }
+ }
+
+ final Candidate c = new Candidate();
+ c.title = title;
+ c.score = score;
+ c.bookOnly = bookOnly;
+ values.add(c);
+ }
+
+ @Override
+ protected void publishResults(final CharSequence constraint, final FilterResults results) {
+ candidates.clear();
+
+ if (results.values != null) {
+ //noinspection unchecked
+ candidates.addAll((List) results.values);
+ }
+
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public CharSequence convertResultToString(final Object resultValue) {
+ final Candidate c = (Candidate) resultValue;
+ if (c.bookOnly) {
+ return c.title + " "; // for user to start typing the chapter number
+ }
+
+ return c.title;
+ }
+ };
+ }
+ }
}
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/fr/GotoGridFragment.java b/Alkitab/src/main/java/yuku/alkitab/base/fr/GotoGridFragment.java
index 2970ea1f8..139189775 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/fr/GotoGridFragment.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/fr/GotoGridFragment.java
@@ -2,26 +2,22 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
-import android.graphics.drawable.ColorDrawable;
-import android.graphics.drawable.InsetDrawable;
import android.os.Bundle;
+import android.support.v4.view.ViewCompat;
+import android.support.v7.widget.GridLayoutManager;
+import android.support.v7.widget.RecyclerView;
import android.text.SpannableStringBuilder;
import android.text.style.UnderlineSpan;
-import android.util.TypedValue;
-import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.GridView;
import android.widget.TextView;
-import yuku.afw.App;
import yuku.afw.V;
import yuku.afw.storage.Preferences;
-import yuku.afw.widget.EasyAdapter;
import yuku.alkitab.base.S;
import yuku.alkitab.base.U;
import yuku.alkitab.base.fr.base.BaseGotoFragment;
+import yuku.alkitab.base.storage.Prefkey;
import yuku.alkitab.base.util.BookNameSorter;
import yuku.alkitab.debug.R;
import yuku.alkitab.model.Book;
@@ -29,18 +25,18 @@
public class GotoGridFragment extends BaseGotoFragment {
public static final String TAG = GotoGridFragment.class.getSimpleName();
- private static final String EXTRA_verse = "verse"; //$NON-NLS-1$
- private static final String EXTRA_chapter = "chapter"; //$NON-NLS-1$
- private static final String EXTRA_bookId = "bookId"; //$NON-NLS-1$
+ private static final String EXTRA_verse = "verse";
+ private static final String EXTRA_chapter = "chapter";
+ private static final String EXTRA_bookId = "bookId";
private static final int ANIM_DURATION = 200;
View panelChapterVerse;
TextView lSelectedBook;
TextView lSelectedChapter;
- GridView gridBook;
- GridView gridChapter;
- GridView gridVerse;
+ RecyclerView gridBook;
+ RecyclerView gridChapter;
+ RecyclerView gridVerse;
Book[] books;
BookAdapter bookAdapter;
@@ -49,34 +45,7 @@ public class GotoGridFragment extends BaseGotoFragment {
Book selectedBook;
int selectedChapter;
-
- private AdapterView.OnItemClickListener gridBook_itemClick = new AdapterView.OnItemClickListener() {
- @Override public void onItemClick(AdapterView> parent, View view, int position, long id) {
- selectedBook = bookAdapter.getItem(position);
- if (selectedBook.chapter_count == 1) {
- // for single-chapter books, jump directly to verse selection
- selectedChapter = 1;
- transitionBookToVerse();
- } else {
- transitionBookToChapter();
- }
- }
- };
-
- private AdapterView.OnItemClickListener gridChapter_itemClick = new AdapterView.OnItemClickListener() {
- @Override public void onItemClick(AdapterView> parent, View view, int position, long id) {
- selectedChapter = position + 1;
- transitionChapterToVerse();
- }
- };
- private AdapterView.OnItemClickListener gridVerse_itemClick = new AdapterView.OnItemClickListener() {
- @Override public void onItemClick(AdapterView> parent, View view, int position, long id) {
- int selectedVerse = position + 1;
- ((GotoFinishListener) getActivity()).onGotoFinished(GotoFinishListener.GOTO_TAB_grid, selectedBook.bookId, selectedChapter, selectedVerse);
- }
- };
-
private View.OnClickListener lSelectedBook_click = new View.OnClickListener() {
@Override public void onClick(View v) {
selectedBook = null;
@@ -100,6 +69,7 @@ void transitionBookToChapter() {
gridVerse.setVisibility(View.INVISIBLE);
animateFadeOutAndSlideLeft(gridBook, gridChapter);
+ ViewCompat.jumpDrawablesToCurrentState(lSelectedBook);
lSelectedBook.setAlpha(0.f);
lSelectedBook.animate().alpha(1.f).setDuration(ANIM_DURATION);
@@ -114,6 +84,7 @@ void transitionBookToVerse() {
gridChapter.setVisibility(View.INVISIBLE);
animateFadeOutAndSlideLeft(gridBook, gridVerse);
+ ViewCompat.jumpDrawablesToCurrentState(lSelectedBook);
lSelectedBook.setAlpha(0.f);
lSelectedBook.animate().alpha(1.f).setDuration(ANIM_DURATION);
@@ -121,9 +92,10 @@ void transitionBookToVerse() {
}
void transitionChapterToBook() {
- // TODO Animate
gridBook.setVisibility(View.VISIBLE);
panelChapterVerse.setVisibility(View.INVISIBLE);
+
+ animateFadeOutAndSlideRight(gridChapter, gridBook);
}
void transitionChapterToVerse() {
@@ -139,31 +111,51 @@ void transitionChapterToVerse() {
}
void transitionVerseToChapter() {
- // TODO Animate
gridBook.setVisibility(View.INVISIBLE);
panelChapterVerse.setVisibility(View.VISIBLE);
gridChapter.setVisibility(View.VISIBLE);
gridChapter.setAdapter(chapterAdapter = new ChapterAdapter(selectedBook));
gridVerse.setVisibility(View.INVISIBLE);
+
+ animateFadeOutAndSlideRight(gridVerse, gridChapter);
+
displaySelectedBookAndChapter();
}
- static void animateFadeOutAndSlideLeft(final GridView fadingOut, final GridView slidingLeft) {
+ static void animateFadeOutAndSlideLeft(final View fadingOut, final View slidingLeft) {
fadingOut.setVisibility(View.VISIBLE);
fadingOut.animate().alpha(0.f).setDuration(ANIM_DURATION).setListener(new AnimatorListenerAdapter() {
- @Override public void onAnimationEnd(Animator animation) {
+ @Override
+ public void onAnimationEnd(Animator animation) {
fadingOut.setAlpha(1.f);
fadingOut.setVisibility(View.INVISIBLE);
}
});
slidingLeft.setX(slidingLeft.getWidth());
slidingLeft.animate().translationXBy(-slidingLeft.getWidth()).setDuration(ANIM_DURATION).setListener(new AnimatorListenerAdapter() {
- @Override public void onAnimationEnd(Animator animation) {
+ @Override
+ public void onAnimationEnd(Animator animation) {
slidingLeft.setVisibility(View.VISIBLE);
}
});
}
+ static void animateFadeOutAndSlideRight(final View fadingOut, final View slidingRight) {
+ fadingOut.setVisibility(View.VISIBLE);
+ fadingOut.animate().alpha(0.f).setDuration(ANIM_DURATION).setListener(new AnimatorListenerAdapter() {
+ @Override public void onAnimationEnd(Animator animation) {
+ fadingOut.setAlpha(1.f);
+ fadingOut.setVisibility(View.INVISIBLE);
+ }
+ });
+ slidingRight.setX(-slidingRight.getWidth());
+ slidingRight.animate().translationXBy(slidingRight.getWidth()).setDuration(ANIM_DURATION).setListener(new AnimatorListenerAdapter() {
+ @Override public void onAnimationEnd(Animator animation) {
+ slidingRight.setVisibility(View.VISIBLE);
+ }
+ });
+ }
+
public static Bundle createArgs(int bookId, int chapter_1, int verse_1) {
Bundle args = new Bundle();
args.putInt(EXTRA_bookId, bookId);
@@ -179,6 +171,7 @@ protected void displaySelectedBookAndChapter() {
lSelectedChapter.setVisibility(View.GONE);
} else {
lSelectedChapter.setVisibility(View.VISIBLE);
+ ViewCompat.jumpDrawablesToCurrentState(lSelectedChapter);
lSelectedChapter.setText(underline("" + selectedChapter));
}
}
@@ -189,23 +182,29 @@ private CharSequence underline(CharSequence cs) {
return sb;
}
+ GridLayoutManager createLayoutManagerForNumbers() {
+ return new GridLayoutManager(getActivity(), getResources().getInteger(R.integer.goto_grid_numeric_num_columns));
+ }
+
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View res = inflater.inflate(R.layout.fragment_goto_grid, container, false);
panelChapterVerse = V.get(res, R.id.panelChapterVerse);
lSelectedBook = V.get(res, R.id.lSelectedBook);
lSelectedChapter = V.get(res, R.id.lSelectedChapter);
+
gridBook = V.get(res, R.id.gridBook);
gridChapter = V.get(res, R.id.gridChapter);
gridVerse = V.get(res, R.id.gridVerse);
panelChapterVerse.setVisibility(View.INVISIBLE);
- gridBook.setOnItemClickListener(gridBook_itemClick);
gridBook.setVisibility(View.VISIBLE);
gridChapter.setVisibility(View.INVISIBLE);
- gridChapter.setOnItemClickListener(gridChapter_itemClick);
gridVerse.setVisibility(View.INVISIBLE);
- gridVerse.setOnItemClickListener(gridVerse_itemClick);
-
+
+ gridBook.setLayoutManager(new GridLayoutManager(getActivity(), 6));
+ gridChapter.setLayoutManager(createLayoutManagerForNumbers());
+ gridVerse.setLayoutManager(createLayoutManagerForNumbers());
+
lSelectedBook.setOnClickListener(lSelectedBook_click);
lSelectedChapter.setOnClickListener(lSelectedChapter_click);
@@ -218,23 +217,24 @@ private CharSequence underline(CharSequence cs) {
books = S.activeVersion.getConsecutiveBooks();
gridBook.setAdapter(bookAdapter = new BookAdapter());
}
-
- abstract class GridAdapter extends EasyAdapter {
- @Override public View newView(int position, ViewGroup parent) {
- TextView res = new TextView(getActivity());
- res.setLayoutParams(new GridView.LayoutParams(getResources().getDimensionPixelSize(R.dimen.goto_grid_cell_width_book), getResources().getDimensionPixelSize(R.dimen.goto_grid_cell_height)));
- res.setGravity(Gravity.CENTER);
- res.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
- return res;
+
+ public class VH extends RecyclerView.ViewHolder {
+ public VH(final View itemView) {
+ super(itemView);
}
-
- @Override public void bindView(View view, int position, ViewGroup parent) {
- TextView lName = (TextView) view;
+ }
+
+ abstract class GridAdapter extends RecyclerView.Adapter {
+ @Override
+ public VH onCreateViewHolder(final ViewGroup parent, final int viewType) {
+ return new VH(getActivity().getLayoutInflater().inflate(R.layout.item_goto_grid_cell, parent, false));
+ }
+
+ @Override
+ public void onBindViewHolder(final VH holder, final int position) {
+ final TextView lName = (TextView) holder.itemView;
lName.setText(textForView(position));
lName.setTextColor(textColorForView(position));
- final ColorDrawable color = new ColorDrawable(backgroundColorForView(position));
- final InsetDrawable bg = new InsetDrawable(color, getResources().getDimensionPixelOffset(R.dimen.goto_grid_cell_inset));
- lName.setBackgroundDrawable(bg);
}
abstract CharSequence textForView(int position);
@@ -242,10 +242,6 @@ abstract class GridAdapter extends EasyAdapter {
int textColorForView(int position) {
return 0xffffffff;
}
-
- int backgroundColorForView(int position) {
- return 0x0; // transparent
- }
}
class BookAdapter extends GridAdapter {
@@ -253,18 +249,35 @@ class BookAdapter extends GridAdapter {
public BookAdapter() {
// sort or not based on pref
- if (Preferences.getBoolean(App.context.getString(R.string.pref_alphabeticBookSort_key), App.context.getResources().getBoolean(R.bool.pref_alphabeticBookSort_default))) {
+ if (Preferences.getBoolean(R.string.pref_alphabeticBookSort_key, R.bool.pref_alphabeticBookSort_default)) {
books_grid = BookNameSorter.sortAlphabetically(books);
} else {
books_grid = books.clone();
}
}
-
- @Override public int getCount() {
+
+ @Override
+ public int getItemCount() {
return books_grid.length;
}
- @Override public Book getItem(int position) {
+ @Override
+ public void onBindViewHolder(final VH holder, final int position) {
+ super.onBindViewHolder(holder, position); // must call this
+
+ holder.itemView.setOnClickListener(v -> {
+ selectedBook = bookAdapter.getItem(position);
+ if (selectedBook.chapter_count == 1) {
+ // for single-chapter books, jump directly to verse selection
+ selectedChapter = 1;
+ transitionBookToVerse();
+ } else {
+ transitionBookToChapter();
+ }
+ });
+ }
+
+ public Book getItem(int position) {
return books_grid[position];
}
@@ -275,9 +288,9 @@ public BookAdapter() {
}
@Override
- int backgroundColorForView(final int position) {
+ int textColorForView(final int position) {
final Book book = getItem(position);
- return U.getBackgroundColorByBookId(book.bookId);
+ return U.getForegroundColorOnDarkBackgroundByBookId(book.bookId);
}
}
@@ -287,11 +300,27 @@ class ChapterAdapter extends GridAdapter {
public ChapterAdapter(Book book) {
this.book = book;
}
-
- @Override public int getCount() {
+
+ @Override
+ public int getItemCount() {
return book.chapter_count;
}
-
+
+ @Override
+ public void onBindViewHolder(final VH holder, final int position) {
+ super.onBindViewHolder(holder, position); // must call this
+
+ holder.itemView.setOnClickListener(v -> {
+ selectedChapter = position + 1;
+
+ if (Preferences.getBoolean(Prefkey.gotoAskForVerse, Prefkey.GOTO_ASK_FOR_VERSE_DEFAULT)) {
+ transitionChapterToVerse();
+ } else {
+ ((GotoFinishListener) getActivity()).onGotoFinished(GotoFinishListener.GOTO_TAB_grid, selectedBook.bookId, selectedChapter, 0);
+ }
+ });
+ }
+
@Override CharSequence textForView(int position) {
return String.valueOf(position + 1);
}
@@ -306,11 +335,22 @@ public VerseAdapter(Book book, int chapter_1) {
this.chapter_1 = chapter_1;
}
- @Override public int getCount() {
+ @Override
+ public int getItemCount() {
int chapter_0 = chapter_1 - 1;
return chapter_0 < 0 || chapter_0 >= book.verse_counts.length? 0: book.verse_counts[chapter_0];
}
+ @Override
+ public void onBindViewHolder(final VH holder, final int position) {
+ super.onBindViewHolder(holder, position);
+
+ holder.itemView.setOnClickListener(v -> {
+ final int selectedVerse = position + 1;
+ ((GotoFinishListener) getActivity()).onGotoFinished(GotoFinishListener.GOTO_TAB_grid, selectedBook.bookId, selectedChapter, selectedVerse);
+ });
+ }
+
@Override CharSequence textForView(int position) {
return String.valueOf(position + 1);
}
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/model/VersionImpl.java b/Alkitab/src/main/java/yuku/alkitab/base/model/VersionImpl.java
index bb12841f5..48bc53f83 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/model/VersionImpl.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/model/VersionImpl.java
@@ -140,7 +140,7 @@ public synchronized Book getFirstBook() {
if (b != null) return b;
}
- Log.e(TAG, "No books available on this version. Version info: " + (this.bibleReader == null? "reader=null": (this.bibleReader.getLongName() + " books.length=" + books.length))); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
+ Log.e(TAG, "No books available on this version. Version info: " + (this.bibleReader == null? "reader=null": (this.bibleReader.getLongName() + " books.length=" + books.length)));
return null;
}
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/pdbconvert/ConvertOptionsDialog.java b/Alkitab/src/main/java/yuku/alkitab/base/pdbconvert/ConvertOptionsDialog.java
index b9e000c9a..f0fa84178 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/pdbconvert/ConvertOptionsDialog.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/pdbconvert/ConvertOptionsDialog.java
@@ -117,7 +117,7 @@ public void onPositive(final MaterialDialog dialog) {
if (tabEncoding == null) {
for (Map.Entry charset: Charset.availableCharsets().entrySet()) {
String key = charset.getKey();
- Log.d(TAG, "available charset: " + key); //$NON-NLS-1$
+ Log.d(TAG, "available charset: " + key);
charsets.add(key);
}
@@ -125,10 +125,10 @@ public void onPositive(final MaterialDialog dialog) {
@Override public int compare(String a, String b) {
int va = 0;
int vb = 0;
- if (a.equalsIgnoreCase("utf-8")) va = -2; //$NON-NLS-1$
- if (a.equalsIgnoreCase("iso-8859-1")) va = -1; //$NON-NLS-1$
- if (b.equalsIgnoreCase("utf-8")) vb = -2; //$NON-NLS-1$
- if (b.equalsIgnoreCase("iso-8859-1")) vb = -1; //$NON-NLS-1$
+ if (a.equalsIgnoreCase("utf-8")) va = -2;
+ if (a.equalsIgnoreCase("iso-8859-1")) va = -1;
+ if (b.equalsIgnoreCase("utf-8")) vb = -2;
+ if (b.equalsIgnoreCase("iso-8859-1")) vb = -1;
if (va == 0 && vb == 0) {
return a.compareToIgnoreCase(b);
@@ -146,7 +146,7 @@ public void onPositive(final MaterialDialog dialog) {
encodingAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
cbEncoding.setAdapter(encodingAdapter);
- showSample("utf-8"); // default! if greek or hebrew, this won't be cared! //$NON-NLS-1$
+ showSample("utf-8"); // default! if greek or hebrew, this won't be cared!
cbEncoding.setOnItemSelectedListener(cbEncoding_itemSelected);
}
@@ -157,9 +157,9 @@ void showSample(String encoding) {
String bookName = bookInfo.getFullName();
String verse = bookInfo.getVerse(1, 1);
if (verse.length() > 90) {
- verse = verse.substring(0, 88) + "..."; //$NON-NLS-1$
+ verse = verse.substring(0, 88) + "...";
}
- lSample.setText(bookName + " 1:1 " + verse); //$NON-NLS-1$
+ lSample.setText(bookName + " 1:1 " + verse);
}
private OnItemSelectedListener cbEncoding_itemSelected = new OnItemSelectedListener() {
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/pdbconvert/ConvertPdbToYes2.java b/Alkitab/src/main/java/yuku/alkitab/base/pdbconvert/ConvertPdbToYes2.java
index 13bed43e8..95516a5f2 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/pdbconvert/ConvertPdbToYes2.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/pdbconvert/ConvertPdbToYes2.java
@@ -74,19 +74,19 @@ public ConvertResult convert(final Context context, String filenamepdb, String y
progress(0, context.getString(R.string.cp_opening_pdb_file));
pdb_ = new BiblePlusPDB(new PDBFileStream(filenamepdb), Tabs.hebrewTab, Tabs.greekTab);
if (params.inputEncoding != null) pdb_.setEncoding(params.inputEncoding);
- Log.d(TAG, "Encoding used: " + params.inputEncoding); //$NON-NLS-1$
+ Log.d(TAG, "Encoding used: " + params.inputEncoding);
progress(10, context.getString(R.string.cp_loading_version_info));
pdb_.loadVersionInfo();
progress(20, context.getString(R.string.cp_loading_word_index));
pdb_.loadWordIndex();
- Log.d(TAG, "============ done reading pdb version info"); //$NON-NLS-1$
+ Log.d(TAG, "============ done reading pdb version info");
- Log.d(TAG, "pdb versionName: " + pdb_.getVersionName()); //$NON-NLS-1$
- Log.d(TAG, "pdb encoding: " + pdb_.getEncoding()); //$NON-NLS-1$
+ Log.d(TAG, "pdb versionName: " + pdb_.getVersionName());
+ Log.d(TAG, "pdb encoding: " + pdb_.getEncoding());
int nbook = pdb_.getBookCount();
- Log.d(TAG, "pdb getBookCount = " + nbook); //$NON-NLS-1$
+ Log.d(TAG, "pdb getBookCount = " + nbook);
progress(30, context.getString(R.string.cp_analyzing_available_books));
{
@@ -96,11 +96,11 @@ public ConvertResult convert(final Context context, String filenamepdb, String y
int bookNumber = pdbBookInfo.getBookNumber();
int bookId = PdbBookNumberToBookIdMapping.pdbBookNumberToBookId(bookNumber);
if (bookId < 0) {
- Log.w(TAG, "bookNumber " + bookNumber + " GA DIKENAL"); //$NON-NLS-1$ //$NON-NLS-2$
+ Log.w(TAG, "bookNumber " + bookNumber + " GA DIKENAL");
if (res.wronglyConvertedBookNames == null) {
res.wronglyConvertedBookNames = new ArrayList<>();
}
- res.wronglyConvertedBookNames.add(pdbBookInfo.getFullName() + " (" + bookNumber + ")"); //$NON-NLS-1$ //$NON-NLS-2$
+ res.wronglyConvertedBookNames.add(pdbBookInfo.getFullName() + " (" + bookNumber + ")");
}
}
bookIdToPdbBookPosMap_ = new TIntIntHashMap();
@@ -114,22 +114,22 @@ public ConvertResult convert(final Context context, String filenamepdb, String y
int pdbBookNumber = pdbBookInfo.getBookNumber();
int bookId = PdbBookNumberToBookIdMapping.pdbBookNumberToBookId(pdbBookNumber);
if (bookId < 0) {
- Log.w(TAG, "pdbBookNumber " + pdbBookNumber + " NOT KNOWN"); //$NON-NLS-1$ //$NON-NLS-2$
+ Log.w(TAG, "pdbBookNumber " + pdbBookNumber + " NOT KNOWN");
} else {
if (bookIdToPdbBookPosMap_.containsKey(bookId)) {
// just a warning of duplicate
if (res.wronglyConvertedBookNames == null) {
res.wronglyConvertedBookNames = new ArrayList<>();
}
- res.wronglyConvertedBookNames.add(pdbBookInfo.getFullName() + " (" + pdbBookNumber + "): duplicate"); //$NON-NLS-1$ //$NON-NLS-2$
+ res.wronglyConvertedBookNames.add(pdbBookInfo.getFullName() + " (" + pdbBookNumber + "): duplicate");
}
bookIdToPdbBookPosMap_.put(bookId, bookPos);
}
}
- Log.d(TAG, "bookIdToPdbBookPosMap_ (size " + bookIdToPdbBookPosMap_.size() + ") = " + bookIdToPdbBookPosMap_.toString()); //$NON-NLS-1$ //$NON-NLS-2$
+ Log.d(TAG, "bookIdToPdbBookPosMap_ (size " + bookIdToPdbBookPosMap_.size() + ") = " + bookIdToPdbBookPosMap_.toString());
- Log.d(TAG, "============ done reading list of books"); //$NON-NLS-1$
+ Log.d(TAG, "============ done reading list of books");
final int[] sortedBookIds = bookIdToPdbBookPosMap_.keys();
@@ -156,7 +156,7 @@ public ConvertResult convert(final Context context, String filenamepdb, String y
yesWriter.sections.add(lazyText);
progress(700, context.getString(R.string.cp_writing_translated_file));
- RandomOutputStream output = new RandomAccessFileRandomOutputStream(new RandomAccessFile(yesFilename, "rw")); //$NON-NLS-1$
+ RandomOutputStream output = new RandomAccessFileRandomOutputStream(new RandomAccessFile(yesFilename, "rw"));
yesWriter.writeToFile(output);
output.close();
@@ -164,7 +164,7 @@ public ConvertResult convert(final Context context, String filenamepdb, String y
pdb_.close();
} catch (Throwable e) {
pdb_ = null;
- Log.e(TAG, "Error reading pdb: ", e); //$NON-NLS-1$
+ Log.e(TAG, "Error reading pdb: ", e);
res.exception = e;
}
finish();
@@ -224,7 +224,7 @@ private BooksInfoSection getBooksInfo(final Context context, int baseProgress, b
}
b.chapter_offsets[chapter_0 + 1] = offsetPassed;
}
- Log.d(TAG, "book " + b.shortName + " (pdbBookNumber=" + pdbBookInfo.getBookNumber() + ", bookId=" + bookId + ") chapter_offsets: " + Arrays.toString(b.chapter_offsets)); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ Log.d(TAG, "book " + b.shortName + " (pdbBookNumber=" + pdbBookInfo.getBookNumber() + ", bookId=" + bookId + ") chapter_offsets: " + Arrays.toString(b.chapter_offsets));
yes2books.add(b);
@@ -234,7 +234,7 @@ private BooksInfoSection getBooksInfo(final Context context, int baseProgress, b
}
if (yes2books.size() != bookIdToPdbBookPosMap_.size()) {
- throw new RuntimeException("Some internal error, res size != bookIdToPdbBookPosMap_ size"); //$NON-NLS-1$
+ throw new RuntimeException("Some internal error, res size != bookIdToPdbBookPosMap_ size");
}
BooksInfoSection res = new BooksInfoSection();
@@ -264,17 +264,17 @@ String[] getCompleteVerseWithPreprocess(BookInfo pdbBookInfo, int chapter_0, int
boolean prependAtAt = false;
// look for 0x0e 'n' 0x0e
- if (s.contains("\u000en\u000e")) { //$NON-NLS-1$
+ if (s.contains("\u000en\u000e")) {
prependAtAt = true;
- s = s.replaceAll("\\s*\u000en\u000e\\s*", "@8"); //$NON-NLS-1$ //$NON-NLS-2$
+ s = s.replaceAll("\\s*\u000en\u000e\\s*", "@8");
}
boolean startingItalic = true;
while (true) {
- int pos = s.indexOf("\u000eb\u000e"); //$NON-NLS-1$
+ int pos = s.indexOf("\u000eb\u000e");
if (pos > 0) {
prependAtAt = true;
- String tag = startingItalic ? "@9" : "@7"; //$NON-NLS-1$ //$NON-NLS-2$
+ String tag = startingItalic ? "@9" : "@7";
s = s.substring(0, pos) + tag + s.substring(pos + 3); // TODO remove extraneous spaces
startingItalic = !startingItalic;
} else {
@@ -283,7 +283,7 @@ String[] getCompleteVerseWithPreprocess(BookInfo pdbBookInfo, int chapter_0, int
}
if (prependAtAt) {
- s = "@@" + s; //$NON-NLS-1$
+ s = "@@" + s;
}
ss[i] = s;
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/storage/InternalDb.java b/Alkitab/src/main/java/yuku/alkitab/base/storage/InternalDb.java
index a25630865..ee2e1bacd 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/storage/InternalDb.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/storage/InternalDb.java
@@ -21,7 +21,9 @@
import yuku.alkitab.base.ac.MarkerListActivity;
import yuku.alkitab.base.devotion.ArticleMeidA;
import yuku.alkitab.base.devotion.ArticleMorningEveningEnglish;
+import yuku.alkitab.base.devotion.ArticleRefheart;
import yuku.alkitab.base.devotion.ArticleRenunganHarian;
+import yuku.alkitab.base.devotion.ArticleRoc;
import yuku.alkitab.base.devotion.ArticleSantapanHarian;
import yuku.alkitab.base.devotion.DevotionArticle;
import yuku.alkitab.base.model.MVersion;
@@ -215,7 +217,7 @@ public List listMarkers(Marker.Kind kind, long label_id, String sortColu
final List res = new ArrayList<>();
final Cursor c;
if (label_id == 0) { // no restrictions
- c = db.query(Db.TABLE_Marker, null, Db.Marker.kind + "=?", new String[] {String.valueOf(kind.code)}, null, null, sortClause);
+ c = db.query(Db.TABLE_Marker, null, Db.Marker.kind + "=?", new String[]{String.valueOf(kind.code)}, null, null, sortClause);
} else if (label_id == MarkerListActivity.LABELID_noLabel) { // only without label
c = db.rawQuery("select " + Db.TABLE_Marker + ".* from " + Db.TABLE_Marker + " where " + Db.TABLE_Marker + "." + Db.Marker.kind + "=? and " + Db.TABLE_Marker + "." + Db.Marker.gid + " not in (select distinct " + Db.Marker_Label.marker_gid + " from " + Db.TABLE_Marker_Label + ") order by " + Db.TABLE_Marker + "." + sortClause, new String[] {String.valueOf(kind.code)});
} else { // filter by label_id
@@ -432,7 +434,7 @@ public int getHighlightColorRgb(int ari_bookchapter, IntArrayList selectedVerses
// check if exists
final Cursor c = helper.getReadableDatabase().query(
Db.TABLE_Marker, null, Db.Marker.ari + ">? and " + Db.Marker.ari + "<=? and " + Db.Marker.kind + "=?",
- new String[] {String.valueOf(ariMin), String.valueOf(ariMax), String.valueOf(Marker.Kind.highlight.code)},
+ new String[]{String.valueOf(ariMin), String.valueOf(ariMax), String.valueOf(Marker.Kind.highlight.code)},
null, null, null
);
@@ -526,8 +528,7 @@ public int deleteDevotionsWithTouchTimeBefore(Date date) {
* Try to get article from local db. Non ready-to-use article will be returned too.
*/
public DevotionArticle tryGetDevotion(String name, String date) {
- final Cursor c = helper.getReadableDatabase().query(Table.Devotion.tableName(), null, Table.Devotion.name + "=? and " + Table.Devotion.date + "=? and " + Table.Devotion.dataFormatVersion + "=?", ToStringArray(name, date, 1), null, null, null);
- try {
+ try (Cursor c = helper.getReadableDatabase().query(Table.Devotion.tableName(), null, Table.Devotion.name + "=? and " + Table.Devotion.date + "=? and " + Table.Devotion.dataFormatVersion + "=?", ToStringArray(name, date, 1), null, null, null)) {
final int col_body = c.getColumnIndexOrThrow(Table.Devotion.body.name());
final int col_readyToUse = c.getColumnIndexOrThrow(Table.Devotion.readyToUse.name());
@@ -549,12 +550,16 @@ public DevotionArticle tryGetDevotion(String name, String date) {
case MEID_A: {
return new ArticleMeidA(date, c.getString(col_body), c.getInt(col_readyToUse) > 0);
}
- default:
- return null;
+ case ROC: {
+ return new ArticleRoc(date, c.getString(col_body), c.getInt(col_readyToUse) > 0);
+ }
+ case REFHEART: {
+ return new ArticleRefheart(date, c.getString(col_body), c.getInt(col_readyToUse) > 0);
+ }
}
- } finally {
- c.close();
}
+
+ throw new RuntimeException("Should not be reachable");
}
public List listAllVersions() {
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/storage/InternalReader.java b/Alkitab/src/main/java/yuku/alkitab/base/storage/InternalReader.java
index 08a362cdf..7421b3718 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/storage/InternalReader.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/storage/InternalReader.java
@@ -233,11 +233,11 @@ private Yes1PericopeIndex loadPericopeIndex() {
return pericopeIndex_;
} catch (IOException e) {
- Log.e(TAG, "Error reading pericope index", e); //$NON-NLS-1$
+ Log.e(TAG, "Error reading pericope index", e);
return null;
} finally {
in.close();
- Log.d(TAG, "Read pericope index needed: " + (System.currentTimeMillis() - startTime)); //$NON-NLS-1$
+ Log.d(TAG, "Read pericope index needed: " + (System.currentTimeMillis() - startTime));
}
}
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/storage/NoBackupSharedPreferences.java b/Alkitab/src/main/java/yuku/alkitab/base/storage/NoBackupSharedPreferences.java
new file mode 100644
index 000000000..f4a20819b
--- /dev/null
+++ b/Alkitab/src/main/java/yuku/alkitab/base/storage/NoBackupSharedPreferences.java
@@ -0,0 +1,85 @@
+package yuku.alkitab.base.storage;
+
+import android.support.v4.content.ContextCompat;
+import android.support.v4.util.AtomicFile;
+import yuku.alkitab.base.App;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.nio.charset.Charset;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+
+public class NoBackupSharedPreferences {
+ static HashMap instances = new HashMap<>();
+
+ final File file;
+
+ static class Map extends LinkedHashMap {}
+
+ Map map;
+
+ public static NoBackupSharedPreferences get() {
+ return get("default.xml");
+ }
+
+ public static synchronized NoBackupSharedPreferences get(final String filename) {
+ NoBackupSharedPreferences res = instances.get(filename);
+ if (res == null) {
+ res = new NoBackupSharedPreferences(filename);
+ instances.put(filename, res);
+ }
+ return res;
+ }
+
+ private NoBackupSharedPreferences(final String filename) {
+ file = new File(new ContextCompat().getNoBackupFilesDir(App.context), filename);
+ if (file.exists()) {
+ final AtomicFile atom = new AtomicFile(file);
+ try {
+ final FileInputStream fis = atom.openRead();
+ map = App.getDefaultGson().fromJson(new InputStreamReader(fis, Charset.forName("utf-8")), Map.class);
+ fis.close();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ } else {
+ map = new Map();
+ }
+ }
+
+ private void save() {
+ final AtomicFile atom = new AtomicFile(file);
+ try {
+ final FileOutputStream fos = atom.startWrite();
+ final OutputStreamWriter w = new OutputStreamWriter(fos, Charset.forName("utf-8"));
+ App.getDefaultGson().toJson(map, w);
+ w.flush();
+ atom.finishWrite(fos);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public void setString(final String key, final String value) {
+ map.put(key, value);
+ save();
+ }
+
+ public String getString(final String key) {
+ final Object value = map.get(key);
+ if (value == null) {
+ return null;
+ }
+
+ if (!(value instanceof String)) {
+ return value.toString();
+ }
+
+ return (String) value;
+ }
+}
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/storage/Prefkey.java b/Alkitab/src/main/java/yuku/alkitab/base/storage/Prefkey.java
index 0a3b51454..9cb6ecd5f 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/storage/Prefkey.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/storage/Prefkey.java
@@ -102,6 +102,7 @@ public enum Prefkey {
lastVersionId,
lastSplitVersionId,
lastSplitOrientation, // string "horizontal" or "vertical"
+ lastSplitProp, // float proportion of the top or left split window
/**
* The whole history (with many entries)
@@ -109,13 +110,6 @@ public enum Prefkey {
*/
history,
- /**
- * (int) Do not offer importing yuku.alkitab or yuku.alkitab.kjv backup files any more.
- * 1: user suppressed it
- * 2: imported already
- */
- stop_import_yuku_alkitab_backups,
-
/** Announce: last annoucement check (auto only). Unix time. */
announce_last_check,
@@ -125,4 +119,10 @@ public enum Prefkey {
/** Current reading vars */
current_reading_ari_start,
current_reading_ari_end,
+
+ /** Option to ask for verse number in goto screen */
+ gotoAskForVerse,
+ ;
+
+ public static final boolean GOTO_ASK_FOR_VERSE_DEFAULT = true;
}
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/storage/SongDb.java b/Alkitab/src/main/java/yuku/alkitab/base/storage/SongDb.java
index c3d568844..10ae16b9a 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/storage/SongDb.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/storage/SongDb.java
@@ -103,7 +103,7 @@ public Song getSong(String bookName, String code) {
Cursor c = db.query(Table.SongInfo.tableName(),
columns,
- Table.SongInfo.bookName + "=? and " + Table.SongInfo.code + "=?", //$NON-NLS-1$ //$NON-NLS-2$
+ Table.SongInfo.bookName + "=? and " + Table.SongInfo.code + "=?",
new String[]{bookName, code},
null, null, null);
@@ -123,8 +123,8 @@ public Song getSong(String bookName, String code) {
public boolean songExists(String bookName, String code) {
SQLiteDatabase db = helper.getReadableDatabase();
- Cursor c = db.rawQuery("select count(*) from " + Table.SongInfo.tableName() + " where " //$NON-NLS-1$ //$NON-NLS-2$
- + Table.SongInfo.bookName + "=? and " + Table.SongInfo.code + "=?", //$NON-NLS-1$ //$NON-NLS-2$
+ Cursor c = db.rawQuery("select count(*) from " + Table.SongInfo.tableName() + " where "
+ + Table.SongInfo.bookName + "=? and " + Table.SongInfo.code + "=?",
new String[]{bookName, code});
try {
@@ -148,9 +148,9 @@ public Song getFirstSongFromBook(String bookName) {
Cursor c = db.query(Table.SongInfo.tableName(),
columns,
- Table.SongInfo.bookName + "=?", //$NON-NLS-1$
+ Table.SongInfo.bookName + "=?",
new String[]{bookName},
- null, null, Table.SongInfo.ordering + " asc", "1"); //$NON-NLS-1$ //$NON-NLS-2$
+ null, null, Table.SongInfo.ordering + " asc", "1");
try {
if (c.moveToNext()) {
@@ -255,13 +255,13 @@ private static Cursor querySongs(SQLiteDatabase db, String[] columns, String boo
columns,
null,
null,
- null, null, Table.SongInfo.bookName + " asc, " + Table.SongInfo.ordering + " asc"); //$NON-NLS-1$ //$NON-NLS-2$
+ null, null, Table.SongInfo.bookName + " asc, " + Table.SongInfo.ordering + " asc");
} else {
c = db.query(Table.SongInfo.tableName(),
columns,
- Table.SongInfo.bookName + "=?", //$NON-NLS-1$
+ Table.SongInfo.bookName + "=?",
new String[] {bookName},
- null, null, Table.SongInfo.ordering + " asc"); //$NON-NLS-1$
+ null, null, Table.SongInfo.ordering + " asc");
}
return c;
}
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/sv/DownloadService.java b/Alkitab/src/main/java/yuku/alkitab/base/sv/DownloadService.java
index 298cbefc5..3a24454e8 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/sv/DownloadService.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/sv/DownloadService.java
@@ -133,7 +133,7 @@ public boolean startDownload(String key, String url, String completeFile) {
e.state = State.created;
e.url = url;
e.completeFile = new File(completeFile);
- e.tempFile = new File(completeFile + ".part." + System.nanoTime() + ".tmp"); //$NON-NLS-1$ //$NON-NLS-2$
+ e.tempFile = new File(completeFile + ".part." + System.nanoTime() + ".tmp");
e.length = -1;
e.progress = 0;
enqueueAndStart(e);
@@ -181,7 +181,7 @@ void changeState(State newState) {
tempOut.write(buf, 0, read);
entry.progress += read;
dispatchProgress(entry);
- Log.d(TAG, "Entry " + entry.key + " progress " + entry.progress + "/" + entry.length); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ Log.d(TAG, "Entry " + entry.key + " progress " + entry.progress + "/" + entry.length);
}
tempOut.close();
is.close();
@@ -193,7 +193,7 @@ void changeState(State newState) {
entry.completeFile.delete();
boolean renameOk = entry.tempFile.renameTo(entry.completeFile);
if (!renameOk) {
- Log.w(TAG, "Failed to rename file from " + entry.tempFile + " to " + entry.completeFile); //$NON-NLS-1$ //$NON-NLS-2$
+ Log.w(TAG, "Failed to rename file from " + entry.tempFile + " to " + entry.completeFile);
entry.errorMsg = getString(R.string.dl_failed_to_rename_temporary_file);
changeState(State.failed);
return entry;
@@ -202,7 +202,7 @@ void changeState(State newState) {
// finished successfully
changeState(State.finished);
} catch (Exception e) {
- Log.w(TAG, "Failed download because of exception", e); //$NON-NLS-1$
+ Log.w(TAG, "Failed download because of exception", e);
entry.tempFile.delete();
entry.errorMsg = e.getClass().getSimpleName() + ' ' + e.getMessage();
changeState(State.failed);
@@ -221,7 +221,7 @@ public DownloadService getService() {
private void incrementWaiting() {
nwaiting.incrementAndGet();
- Log.d(TAG, "(inc) now nwaiting is " + nwaiting); //$NON-NLS-1$
+ Log.d(TAG, "(inc) now nwaiting is " + nwaiting);
}
public synchronized void decrementWaitingAndCheck() {
@@ -231,7 +231,7 @@ public synchronized void decrementWaitingAndCheck() {
Message.obtain(handler, MSG_stopSelf).sendToTarget();
}
- Log.d(TAG, "(dec) now nwaiting is " + nwaiting); //$NON-NLS-1$
+ Log.d(TAG, "(dec) now nwaiting is " + nwaiting);
}
public void dispatchProgress(DownloadEntry entry) {
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/sv/VersionConfigUpdaterService.java b/Alkitab/src/main/java/yuku/alkitab/base/sv/VersionConfigUpdaterService.java
index 1cc2d25be..10fcbc414 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/sv/VersionConfigUpdaterService.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/sv/VersionConfigUpdaterService.java
@@ -6,7 +6,6 @@
import android.os.Handler;
import android.util.Log;
import android.widget.Toast;
-import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import yuku.afw.storage.Preferences;
import yuku.alkitab.base.App;
@@ -44,17 +43,14 @@ public void onCreate() {
}
public void toast(final CharSequence s) {
- handler.post(new Runnable() {
- @Override
- public void run() {
- if (toast == null) {
- toast = Toast.makeText(VersionConfigUpdaterService.this, s, Toast.LENGTH_SHORT);
- } else {
- toast.setText(s);
- }
-
- toast.show();
+ handler.post(() -> {
+ if (toast == null) {
+ toast = Toast.makeText(this, s, Toast.LENGTH_SHORT);
+ } else {
+ toast.setText(s);
}
+
+ toast.show();
});
}
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/sync/Gcm.java b/Alkitab/src/main/java/yuku/alkitab/base/sync/Gcm.java
index 439f00c26..b4b621830 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/sync/Gcm.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/sync/Gcm.java
@@ -8,6 +8,7 @@
import com.google.android.gms.gcm.GoogleCloudMessaging;
import yuku.afw.storage.Preferences;
import yuku.alkitab.base.App;
+import yuku.alkitab.base.storage.NoBackupSharedPreferences;
import yuku.alkitab.base.storage.Prefkey;
import java.io.IOException;
@@ -92,7 +93,7 @@ public static String renewGcmRegistrationIdIfNeeded(@Nullable final Listener lis
*/
@Nullable
private static String getStoredRegistrationId() {
- final String registrationId = Preferences.getString(Prefkey.gcm_registration_id);
+ final String registrationId = readGcmRegistrationId();
if (registrationId == null) {
Log.i(TAG, "Registration not found.");
return null;
@@ -111,6 +112,21 @@ private static String getStoredRegistrationId() {
return registrationId;
}
+ private static String readGcmRegistrationId() {
+ final NoBackupSharedPreferences nbsp = NoBackupSharedPreferences.get();
+
+ String res = Preferences.getString(Prefkey.gcm_registration_id, null);
+ if (res == null) {
+ res = nbsp.getString(Prefkey.gcm_registration_id.name());
+ } else {
+ // we need to remove it from the backed up folder and move it to the nonbacked up folder
+ Preferences.remove(Prefkey.gcm_registration_id);
+ nbsp.setString(Prefkey.gcm_registration_id.name(), res);
+ }
+
+ return res;
+ }
+
private static void registerInBackground() {
new Thread(() -> {
try {
@@ -128,7 +144,7 @@ private static void registerInBackground() {
// Persist the regID - no need to register again.
Preferences.setInt(Prefkey.gcm_last_app_version_code, App.getVersionCode());
- Preferences.setString(Prefkey.gcm_registration_id, registrationId);
+ writeGcmRegistrationId(registrationId);
} catch (IOException ex) {
// If there is an error, don't just keep trying to register.
// Require the user to click a button again, or perform exponential back-off.
@@ -136,4 +152,10 @@ private static void registerInBackground() {
}
}).start();
}
+
+ private static void writeGcmRegistrationId(final String registrationId) {
+ Preferences.remove(Prefkey.gcm_registration_id);
+
+ NoBackupSharedPreferences.get().setString(Prefkey.gcm_registration_id.name(), registrationId);
+ }
}
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/sync/SyncLoginActivity.java b/Alkitab/src/main/java/yuku/alkitab/base/sync/SyncLoginActivity.java
index 22409d575..39644ce2c 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/sync/SyncLoginActivity.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/sync/SyncLoginActivity.java
@@ -59,7 +59,8 @@ public static Result obtainResult(final Intent data) {
@Override
protected void onCreate(final Bundle savedInstanceState) {
- super.onCreateWithNonToolbarUpButton(savedInstanceState);
+ enableNonToolbarUpButton();
+ super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sync_login);
tIntro = V.get(this, R.id.tIntro);
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/util/AddonManager.java b/Alkitab/src/main/java/yuku/alkitab/base/util/AddonManager.java
index 00698b716..d37c15e7f 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/util/AddonManager.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/util/AddonManager.java
@@ -8,7 +8,7 @@ public class AddonManager {
public static final String TAG = AddonManager.class.getSimpleName();
public static String getYesPath() {
- return new File(Environment.getExternalStorageDirectory(), "bible/yes").getAbsolutePath(); //$NON-NLS-1$
+ return new File(Environment.getExternalStorageDirectory(), "bible/yes").getAbsolutePath();
}
/**
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/util/Announce.java b/Alkitab/src/main/java/yuku/alkitab/base/util/Announce.java
index 9d949dbf9..30be9f0a0 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/util/Announce.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/util/Announce.java
@@ -7,7 +7,6 @@
import android.os.SystemClock;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
-import android.widget.Toast;
import com.squareup.okhttp.Call;
import com.squareup.okhttp.FormEncodingBuilder;
import com.squareup.okhttp.OkHttpClient;
@@ -69,9 +68,6 @@ private static void checkAnnouncements_worker() throws Exception {
final AnnounceCheckResult result = getAnnouncements();
if (!result.success) {
Log.d(TAG, "Announce check returns success=false: " + result.message);
- if (result.message != null) {
- Toast.makeText(App.context, "Announce: " + result.message, Toast.LENGTH_LONG).show();
- }
return;
}
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/util/BookNameSorter.java b/Alkitab/src/main/java/yuku/alkitab/base/util/BookNameSorter.java
index ed54ee971..66efe4b65 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/util/BookNameSorter.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/util/BookNameSorter.java
@@ -9,9 +9,9 @@
public class BookNameSorter {
public static final String TAG = BookNameSorter.class.getSimpleName();
- static final String[] numberedBookStartsWiths = {null, "I ", "II ", "III ", "IV ", "V "}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
- static final String[] numberedBookStartsWithNumbers = {null, "1", "2", "3", "4", "5"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
- static final String[] numberedBookReplaceWiths = {null, "1", "2", "3", "4", "5"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+ static final String[] numberedBookStartsWiths = {null, "I ", "II ", "III ", "IV ", "V "};
+ static final String[] numberedBookStartsWithNumbers = {null, "1", "2", "3", "4", "5"};
+ static final String[] numberedBookReplaceWiths = {null, "1", "2", "3", "4", "5"};
static final int[] numberedBookMap;
static final HashMap hardcodedAbbrs = new HashMap<>();
@@ -88,8 +88,8 @@ public static String getBookAbbr(Book book) {
}
// remove spaces and '.'
- name = name.replace(" ", ""); //$NON-NLS-1$ //$NON-NLS-2$
- name = name.replace(".", ""); //$NON-NLS-1$ //$NON-NLS-2$
+ name = name.replace(" ", "");
+ name = name.replace(".", "");
if (name.length() > 3) name = name.substring(0, 3);
return name;
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/util/FontManager.java b/Alkitab/src/main/java/yuku/alkitab/base/util/FontManager.java
index 6183c5f67..31b4d5758 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/util/FontManager.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/util/FontManager.java
@@ -6,7 +6,6 @@
import android.util.Log;
import java.io.File;
-import java.io.FileFilter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -37,14 +36,14 @@ public static Typeface createFromFile(String path) {
}
}
- Log.d(TAG, "TypefaceCreateFromFileCacher creating entry for " + path); //$NON-NLS-1$
+ Log.d(TAG, "TypefaceCreateFromFileCacher creating entry for " + path);
Typeface typeface = Typeface.createFromFile(path);
// cache too full?
if (keys.size() >= max) {
keys.remove(0);
values.remove(0);
- Log.d(TAG, "TypefaceCreateFromFileCacher removed entry from cache because cache is too full"); //$NON-NLS-1$
+ Log.d(TAG, "TypefaceCreateFromFileCacher removed entry from cache because cache is too full");
}
keys.add(path);
values.add(typeface);
@@ -54,7 +53,7 @@ public static Typeface createFromFile(String path) {
}
public static String getFontsPath() {
- return new File(Environment.getExternalStorageDirectory(), "bible/fonts").getAbsolutePath(); //$NON-NLS-1$
+ return new File(Environment.getExternalStorageDirectory(), "bible/fonts").getAbsolutePath();
}
public static Typeface getRegular(String name) {
@@ -70,7 +69,7 @@ public static File getFontDir(String name) {
}
static File getRegularPath(String name) {
- return new File(getFontsPath(), name + "/" + name + "-Regular.ttf"); //$NON-NLS-1$ //$NON-NLS-2$
+ return new File(getFontsPath(), name + "/" + name + "-Regular.ttf");
}
public static boolean isInstalled(String name) {
@@ -78,7 +77,7 @@ public static boolean isInstalled(String name) {
}
public static List getInstalledFonts() {
- List res = new ArrayList<>();
+ final List res = new ArrayList<>();
// enum the bible/fonts directory
File fontsDir = new File(getFontsPath());
@@ -90,45 +89,45 @@ public static List getInstalledFonts() {
return res;
}
- File[] dirs = fontsDir.listFiles(new FileFilter() {
- @Override public boolean accept(File pathname) {
- if (!pathname.isDirectory()) return false;
- String basename = pathname.getName();
- File ttf = getRegularPath(basename);
- if (!ttf.exists()) {
- Log.d(TAG, "Font dir " + pathname.getAbsolutePath() + " exists but " + ttf.getAbsolutePath() + " doesn't"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- return false;
- } else {
- return true;
- }
+ final File[] dirs = fontsDir.listFiles(pathname -> {
+ if (!pathname.isDirectory()) return false;
+ String basename = pathname.getName();
+ File ttf = getRegularPath(basename);
+ if (!ttf.exists()) {
+ Log.d(TAG, "Font dir " + pathname.getAbsolutePath() + " exists but " + ttf.getAbsolutePath() + " doesn't");
+ return false;
+ } else {
+ return true;
}
});
-
- Arrays.sort(dirs);
-
- for (File dir: dirs) {
- FontEntry e = new FontEntry();
- e.name = dir.getName();
- e.title = dir.getName(); // TODO more friendly
- e.dir = dir.getAbsolutePath();
- String basename = dir.getName();
- e.regularPath = getRegularPath(basename).getAbsolutePath();
- // TODO italic etc
- res.add(e);
- }
-
+
+ if (dirs != null) {
+ Arrays.sort(dirs);
+
+ for (File dir: dirs) {
+ FontEntry e = new FontEntry();
+ e.name = dir.getName();
+ e.title = dir.getName(); // TODO more friendly
+ e.dir = dir.getAbsolutePath();
+ String basename = dir.getName();
+ e.regularPath = getRegularPath(basename).getAbsolutePath();
+ // TODO italic etc
+ res.add(e);
+ }
+ }
+
return res;
}
public static Typeface typeface(String name) {
Typeface res;
- if (name == null || name.equals("DEFAULT") || name.equals("SANS_SERIF") || name.equals("")) res = Typeface.SANS_SERIF; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- else if (name.equals("SERIF")) res = Typeface.SERIF; //$NON-NLS-1$
- else if (name.equals("MONOSPACE")) res = Typeface.MONOSPACE; //$NON-NLS-1$
+ if (name == null || name.equals("DEFAULT") || name.equals("SANS_SERIF") || name.equals("")) res = Typeface.SANS_SERIF;
+ else if (name.equals("SERIF")) res = Typeface.SERIF;
+ else if (name.equals("MONOSPACE")) res = Typeface.MONOSPACE;
else {
res = getRegular(name);
if (res == null) {
- Log.w(TAG, "Failed to load font named " + name + " fallback to SANS_SERIF"); //$NON-NLS-1$ //$NON-NLS-2$
+ Log.w(TAG, "Failed to load font named " + name + " fallback to SANS_SERIF");
res = Typeface.SANS_SERIF;
}
}
@@ -136,7 +135,7 @@ public static Typeface typeface(String name) {
}
public static boolean isCustomFont(String name) {
- return !(name == null || name.equals("DEFAULT") || name.equals("SANS_SERIF") || name.equals("SERIF") || name.equals("MONOSPACE")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ return !(name == null || name.equals("DEFAULT") || name.equals("SANS_SERIF") || name.equals("SERIF") || name.equals("MONOSPACE"));
}
public static String getCustomFontUri(String name) {
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/util/Jumper.java b/Alkitab/src/main/java/yuku/alkitab/base/util/Jumper.java
index 81b801026..0abd52209 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/util/Jumper.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/util/Jumper.java
@@ -34,12 +34,12 @@ public interface Logger {
private boolean parseSucceeded = false;
- private static class BookRef {
- String condensed;
- int pos;
+ public static class BookRef {
+ public String condensed;
+ public int bookId;
@Override public String toString() {
- return condensed + ":" + pos; //$NON-NLS-1$
+ return condensed + ":" + bookId;
}
}
@@ -153,7 +153,7 @@ private boolean parse0(String reference) {
//# STAGE 5: Remove spaces on the left and right of "-"
if (reference.indexOf('-') >= 0) {
- reference = reference.replaceAll("\\s+-\\s+|\\s+-|-\\s+", "-"); //$NON-NLS-1$ //$NON-NLS-2$
+ reference = reference.replaceAll("\\s+-\\s+|\\s+-|-\\s+", "-");
if (BuildConfig.DEBUG) logger.d("jumper stage 5: " + reference);
}
@@ -202,7 +202,7 @@ private boolean parse0(String reference) {
//# STAGE 10: Split based on SPACE, :, PERIOD, and whitespaces between -'s and numbers.
//# Sample of wrong output: [Kisah, rasul34, 6-7, 8]
//# Sample of right output: [Kisah, rasul34, 6, -, 7, 8]
- String[] parts = reference.split("((\\s|:|\\.)+|(?=[0-9])(?<=-)|(?=-)(?<=[0-9][a-z]?))"); //$NON-NLS-1$
+ String[] parts = reference.split("((\\s|:|\\.)+|(?=[0-9])(?<=-)|(?=-)(?<=[0-9][a-z]?))");
if (BuildConfig.DEBUG) logger.d("jumper stage 10: " + Arrays.toString(parts));
//# STAGE 12: Remove string from empty parts
@@ -238,7 +238,7 @@ private boolean parse0(String reference) {
for (String b: parts) {
if (isWord(b)) {
- String number = ""; //$NON-NLS-1$
+ String number = "";
for (int i = b.length() - 1; i >= 0; i--) {
char c = b.charAt(i);
if (c >= '0' && c <= '9') {
@@ -271,7 +271,7 @@ private boolean parse0(String reference) {
int at = -1;
for (int i = 0; i < parts.length; i++) {
- if ("-".equals(parts[i]) || "--".equals(parts[i])) { //$NON-NLS-1$
+ if ("-".equals(parts[i]) || "--".equals(parts[i])) {
hasDash = true;
at = i;
break;
@@ -322,7 +322,7 @@ private boolean parse0(String reference) {
String s = null;
for (int j = 0; j <= startWord; j++) {
- s = (s == null)? parts[j]: s + " " + parts[j]; //$NON-NLS-1$
+ s = (s == null)? parts[j]: s + " " + parts[j];
}
bel.add(s);
@@ -382,28 +382,39 @@ private boolean parse(String alamat) {
return res;
}
-
- private List createBookCandidates(String[] bookNames, int[] bookIds) {
+
+ public static List createBookCandidates(Book[] books) {
+ String[] bookNames = new String[books.length];
+ int[] bookIds = new int[books.length];
+ for (int i = 0, booksLength = books.length; i < booksLength; i++) {
+ final Book book = books[i];
+ bookNames[i] = book.shortName;
+ bookIds[i] = book.bookId;
+ }
+ return createBookCandidates(bookNames, bookIds);
+ }
+
+ static List createBookCandidates(String[] bookNames, int[] bookIds) {
// create cache of condensed book titles where all spaces are stripped and lowercased and "1" becomes "I", "2" becomes "II" etc.
final List res = new ArrayList<>();
for (int i = 0, len = bookNames.length; i < len; i++) {
- String condensed = bookNames[i].replaceAll("(\\s|-|_)+", "").toLowerCase(Locale.getDefault()); //$NON-NLS-1$ //$NON-NLS-2$
+ String condensed = bookNames[i].replaceAll("(\\s|-|_)+", "").toLowerCase(Locale.getDefault());
{
BookRef ref = new BookRef();
ref.condensed = condensed;
- ref.pos = bookIds[i];
+ ref.bookId = bookIds[i];
res.add(ref);
}
- if (condensed.contains("1") || condensed.contains("2") || condensed.contains("3")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- condensed = condensed.replace("1", "i").replace("2", "ii").replace("3", "iii"); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
+ if (condensed.contains("1") || condensed.contains("2") || condensed.contains("3")) {
+ condensed = condensed.replace("1", "i").replace("2", "ii").replace("3", "iii");
BookRef ref = new BookRef();
ref.condensed = condensed;
- ref.pos = bookIds[i];
+ ref.bookId = bookIds[i];
res.add(ref);
}
@@ -420,14 +431,14 @@ private int guessBook(List refs) {
int res = -1;
// 0. clean up p_book
- p_book = p_book.replaceAll("(\\s|-|_)", "").toLowerCase(Locale.getDefault()); //$NON-NLS-1$ //$NON-NLS-2$
+ p_book = p_book.replaceAll("(\\s|-|_)", "").toLowerCase(Locale.getDefault());
if (BuildConfig.DEBUG) logger.d("guessBook phase 0: p_book = " + p_book);
// 1. try to match wholly (e.g.: "genesis", "john")
for (BookRef ref: refs) {
if (ref.condensed.equals(p_book)) {
if (BuildConfig.DEBUG) logger.d("guessBook phase 1 success: " + p_book);
- return ref.pos;
+ return ref.bookId;
}
}
@@ -438,7 +449,7 @@ private int guessBook(List refs) {
for (BookRef ref: refs) {
if (ref.condensed.startsWith(p_book)) {
passed++;
- if (passed == 1) pos_forLater = ref.pos;
+ if (passed == 1) pos_forLater = ref.bookId;
}
}
@@ -467,7 +478,7 @@ private int guessBook(List refs) {
if (score < minScore) {
minScore = score;
- pos = ref.pos;
+ pos = ref.bookId;
}
}
@@ -492,6 +503,10 @@ private int guessBook(List refs) {
public boolean getParseSucceeded() {
return parseSucceeded;
}
+
+ public String getUnparsedBook() {
+ return p_book;
+ }
/**
* @param books list of books from which the looked for book is searched
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/util/Levenshtein.java b/Alkitab/src/main/java/yuku/alkitab/base/util/Levenshtein.java
index 8c326f448..5c1d198b6 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/util/Levenshtein.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/util/Levenshtein.java
@@ -5,7 +5,7 @@ public class Levenshtein {
private static final int deletion = 500;
private static final int substitution = 400;
- static int distance(String s, String t) {
+ public static int distance(String s, String t) {
// d is a table with m+1 rows and n+1 columns
int m = s.length();
int n = t.length();
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/util/OsisBookNames.java b/Alkitab/src/main/java/yuku/alkitab/base/util/OsisBookNames.java
index 3962db9be..15fa41286 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/util/OsisBookNames.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/util/OsisBookNames.java
@@ -15,72 +15,72 @@ public class OsisBookNames {
static String[] names = {
- "Gen", //$NON-NLS-1$
- "Exod", //$NON-NLS-1$
- "Lev", //$NON-NLS-1$
- "Num", //$NON-NLS-1$
- "Deut", //$NON-NLS-1$
- "Josh", //$NON-NLS-1$
- "Judg", //$NON-NLS-1$
- "Ruth", //$NON-NLS-1$
- "1Sam", //$NON-NLS-1$
- "2Sam", //$NON-NLS-1$
- "1Kgs", //$NON-NLS-1$
- "2Kgs", //$NON-NLS-1$
- "1Chr", //$NON-NLS-1$
- "2Chr", //$NON-NLS-1$
- "Ezra", //$NON-NLS-1$
- "Neh", //$NON-NLS-1$
- "Esth", //$NON-NLS-1$
- "Job", //$NON-NLS-1$
- "Ps", //$NON-NLS-1$
- "Prov", //$NON-NLS-1$
- "Eccl", //$NON-NLS-1$
- "Song", //$NON-NLS-1$
- "Isa", //$NON-NLS-1$
- "Jer", //$NON-NLS-1$
- "Lam", //$NON-NLS-1$
- "Ezek", //$NON-NLS-1$
- "Dan", //$NON-NLS-1$
- "Hos", //$NON-NLS-1$
- "Joel", //$NON-NLS-1$
- "Amos", //$NON-NLS-1$
- "Obad", //$NON-NLS-1$
- "Jonah", //$NON-NLS-1$
- "Mic", //$NON-NLS-1$
- "Nah", //$NON-NLS-1$
- "Hab", //$NON-NLS-1$
- "Zeph", //$NON-NLS-1$
- "Hag", //$NON-NLS-1$
- "Zech", //$NON-NLS-1$
- "Mal", //$NON-NLS-1$
- "Matt", //$NON-NLS-1$
- "Mark", //$NON-NLS-1$
- "Luke", //$NON-NLS-1$
- "John", //$NON-NLS-1$
- "Acts", //$NON-NLS-1$
- "Rom", //$NON-NLS-1$
- "1Cor", //$NON-NLS-1$
- "2Cor", //$NON-NLS-1$
- "Gal", //$NON-NLS-1$
- "Eph", //$NON-NLS-1$
- "Phil", //$NON-NLS-1$
- "Col", //$NON-NLS-1$
- "1Thess",//$NON-NLS-1$
- "2Thess",//$NON-NLS-1$
- "1Tim", //$NON-NLS-1$
- "2Tim", //$NON-NLS-1$
- "Titus", //$NON-NLS-1$
- "Phlm", //$NON-NLS-1$
- "Heb", //$NON-NLS-1$
- "Jas", //$NON-NLS-1$
- "1Pet", //$NON-NLS-1$
- "2Pet", //$NON-NLS-1$
- "1John", //$NON-NLS-1$
- "2John", //$NON-NLS-1$
- "3John", //$NON-NLS-1$
- "Jude", //$NON-NLS-1$
- "Rev", //$NON-NLS-1$
+ "Gen",
+ "Exod",
+ "Lev",
+ "Num",
+ "Deut",
+ "Josh",
+ "Judg",
+ "Ruth",
+ "1Sam",
+ "2Sam",
+ "1Kgs",
+ "2Kgs",
+ "1Chr",
+ "2Chr",
+ "Ezra",
+ "Neh",
+ "Esth",
+ "Job",
+ "Ps",
+ "Prov",
+ "Eccl",
+ "Song",
+ "Isa",
+ "Jer",
+ "Lam",
+ "Ezek",
+ "Dan",
+ "Hos",
+ "Joel",
+ "Amos",
+ "Obad",
+ "Jonah",
+ "Mic",
+ "Nah",
+ "Hab",
+ "Zeph",
+ "Hag",
+ "Zech",
+ "Mal",
+ "Matt",
+ "Mark",
+ "Luke",
+ "John",
+ "Acts",
+ "Rom",
+ "1Cor",
+ "2Cor",
+ "Gal",
+ "Eph",
+ "Phil",
+ "Col",
+ "1Thess",
+ "2Thess",
+ "1Tim",
+ "2Tim",
+ "Titus",
+ "Phlm",
+ "Heb",
+ "Jas",
+ "1Pet",
+ "2Pet",
+ "1John",
+ "2John",
+ "3John",
+ "Jude",
+ "Rev",
};
static {
@@ -115,7 +115,7 @@ public static Pattern getBookNameWithChapterAndOptionalVersePattern() {
}
sb.append(')');
- sb.append("\\.([1-9][0-9]{0,2})(?:\\.([1-9][0-9]{0,2}))?"); //$NON-NLS-1$
+ sb.append("\\.([1-9][0-9]{0,2})(?:\\.([1-9][0-9]{0,2}))?");
bookNameWithChapterAndOptionalVersePattern = Pattern.compile(sb.toString());
}
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/util/QueryTokenizer.java b/Alkitab/src/main/java/yuku/alkitab/base/util/QueryTokenizer.java
index 7377bb858..e8f69085e 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/util/QueryTokenizer.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/util/QueryTokenizer.java
@@ -9,7 +9,7 @@
public class QueryTokenizer {
public static final String TAG = QueryTokenizer.class.getSimpleName();
- static Pattern oneToken = Pattern.compile("(\\+?)((?:\".*?\"|\\S)+)"); //$NON-NLS-1$
+ static Pattern oneToken = Pattern.compile("(\\+?)((?:\".*?\"|\\S)+)");
/**
* Convert a query string into tokens. Takes care of the quotes.
@@ -58,7 +58,7 @@ public static String[] tokenize(String query) {
}
public static boolean isPlussedToken(String token) {
- return (token.startsWith("+")); //$NON-NLS-1$
+ return (token.startsWith("+"));
}
public static String tokenWithoutPlus(String token) {
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/util/SearchEngine.java b/Alkitab/src/main/java/yuku/alkitab/base/util/SearchEngine.java
index 0987fcf53..d173759dd 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/util/SearchEngine.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/util/SearchEngine.java
@@ -123,13 +123,13 @@ public int compare(String object1, String object2) {
{
long ms = System.currentTimeMillis();
result = searchByGrepInside(version, word, prev, query.bookIds);
- Log.d(TAG, "search word '" + word + "' needed: " + (System.currentTimeMillis() - ms) + " ms"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ Log.d(TAG, "search word '" + word + "' needed: " + (System.currentTimeMillis() - ms) + " ms");
}
if (prev != null) {
- Log.d(TAG, "Will intersect " + prev.size() + " elements with " + result.size() + " elements..."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ Log.d(TAG, "Will intersect " + prev.size() + " elements with " + result.size() + " elements...");
result = intersect(prev, result);
- Log.d(TAG, "... the result is " + result.size() + " elements"); //$NON-NLS-1$//$NON-NLS-2$
+ Log.d(TAG, "... the result is " + result.size() + " elements");
}
index++;
@@ -224,7 +224,7 @@ static IntArrayList searchByGrepInside(final Version version, String word, final
}
}
- if (BuildConfig.DEBUG) Log.d(TAG, "searchByGrepInside book " + book.shortName + " done. res.size = " + res.size()); //$NON-NLS-1$ //$NON-NLS-2$
+ if (BuildConfig.DEBUG) Log.d(TAG, "searchByGrepInside book " + book.shortName + " done. res.size = " + res.size());
}
} else {
// search only on book-chapters that are in the source
@@ -251,7 +251,7 @@ static IntArrayList searchByGrepInside(final Version version, String word, final
count++;
}
- if (BuildConfig.DEBUG) Log.d(TAG, "searchByGrepInside book with source " + source.size() + " needed to read as many as " + count + " book-chapter. res.size=" + res.size()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ if (BuildConfig.DEBUG) Log.d(TAG, "searchByGrepInside book with source " + source.size() + " needed to read as many as " + count + " book-chapter. res.size=" + res.size());
}
return res;
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/util/SongFilter.java b/Alkitab/src/main/java/yuku/alkitab/base/util/SongFilter.java
index 1636ed4d8..1f97c3155 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/util/SongFilter.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/util/SongFilter.java
@@ -29,7 +29,7 @@ public static CompiledFilter compileFilter(String filter_string) {
for (int i = 0; i < tokens.length; i++) {
String token = tokens[i];
if (QueryTokenizer.isPlussedToken(token)) {
- ps[i] = Pattern.compile("\\b" + Pattern.quote(QueryTokenizer.tokenWithoutPlus(token)) + "\\b", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$ //$NON-NLS-2$
+ ps[i] = Pattern.compile("\\b" + Pattern.quote(QueryTokenizer.tokenWithoutPlus(token)) + "\\b", Pattern.CASE_INSENSITIVE);
} else {
ps[i] = Pattern.compile(Pattern.quote(token), Pattern.CASE_INSENSITIVE);
}
@@ -95,7 +95,7 @@ public static boolean match(Song song, CompiledFilter cf) {
}
private static boolean match(SongInfo song, Pattern p) {
- Matcher m = p.matcher(""); //$NON-NLS-1$
+ Matcher m = p.matcher("");
if (find(song.code, m)) return true;
if (find(song.title, m)) return true;
@@ -105,7 +105,7 @@ private static boolean match(SongInfo song, Pattern p) {
}
private static boolean match(Song song, Pattern p) {
- Matcher m = p.matcher(""); //$NON-NLS-1$
+ Matcher m = p.matcher("");
if (find(song.code, m)) return true;
if (find(song.title, m)) return true;
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/widget/LeftDrawer.java b/Alkitab/src/main/java/yuku/alkitab/base/widget/LeftDrawer.java
index 7d9ded47d..054d8f9d7 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/widget/LeftDrawer.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/widget/LeftDrawer.java
@@ -8,6 +8,7 @@
import android.content.IntentFilter;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
+import android.support.v4.widget.NestedScrollView;
import android.support.v7.widget.SwitchCompat;
import android.text.SpannableStringBuilder;
import android.text.style.RelativeSizeSpan;
@@ -21,7 +22,6 @@
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.PopupMenu;
-import android.widget.ScrollView;
import android.widget.Spinner;
import android.widget.TextView;
import yuku.afw.V;
@@ -44,7 +44,7 @@
import java.util.ArrayList;
import java.util.List;
-public abstract class LeftDrawer extends ScrollView {
+public abstract class LeftDrawer extends NestedScrollView {
// mandatory
TextView bBible;
@@ -560,7 +560,7 @@ public interface Handle {
void setDescription(CharSequence description);
}
- ScrollView scrollDescription;
+ NestedScrollView scrollDescription;
TextView tDescription;
View bRestart;
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/widget/SingleViewVerseAdapter.java b/Alkitab/src/main/java/yuku/alkitab/base/widget/SingleViewVerseAdapter.java
index a4f760866..eaf8571a5 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/widget/SingleViewVerseAdapter.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/widget/SingleViewVerseAdapter.java
@@ -26,6 +26,10 @@
public class SingleViewVerseAdapter extends VerseAdapter {
public static final String TAG = SingleViewVerseAdapter.class.getSimpleName();
+
+ public static final int TYPE_VERSE_TEXT = 0;
+ public static final int TYPE_PERICOPE = 1;
+
private SparseBooleanArray dictionaryModeAris;
public static class DictionaryLinkInfo {
@@ -44,9 +48,24 @@ public SingleViewVerseAdapter(Context context) {
super(context);
}
+ @Override
+ public int getViewTypeCount() {
+ return 2;
+ }
+
+ @Override
+ public int getItemViewType(final int position) {
+ final int id = itemPointer_[position];
+ if (id >= 0) {
+ return TYPE_VERSE_TEXT;
+ } else {
+ return TYPE_PERICOPE;
+ }
+ }
+
@Override public synchronized View getView(int position, View convertView, ViewGroup parent) {
// Need to determine this is pericope or verse
- int id = itemPointer_[position];
+ final int id = itemPointer_[position];
if (id >= 0) {
// VERSE. not pericope
@@ -58,7 +77,7 @@ public SingleViewVerseAdapter(Context context) {
}
final VerseItem res;
- if (convertView == null || convertView.getId() != R.id.itemVerse) {
+ if (convertView == null) {
res = (VerseItem) inflater_.inflate(R.layout.item_verse, parent, false);
} else {
res = (VerseItem) convertView;
@@ -145,12 +164,19 @@ public SingleViewVerseAdapter(Context context) {
// }
// }
+ // Do we need to call attention?
+ if (attentionStart_ != 0 && attentionPositions_ != null && attentionPositions_.contains(position)) {
+ res.callAttention(attentionStart_);
+ } else {
+ res.callAttention(0);
+ }
+
return res;
} else {
// PERICOPE. not verse.
final PericopeHeaderItem res;
- if (convertView == null || convertView.getId() != R.id.itemPericopeHeader) {
+ if (convertView == null) {
res = (PericopeHeaderItem) inflater_.inflate(R.layout.item_pericope_header, parent, false);
} else {
res = (PericopeHeaderItem) convertView;
@@ -181,7 +207,7 @@ public SingleViewVerseAdapter(Context context) {
} else {
lParallels.setVisibility(View.VISIBLE);
- SpannableStringBuilder sb = new SpannableStringBuilder("("); //$NON-NLS-1$
+ SpannableStringBuilder sb = new SpannableStringBuilder("(");
int total = pericopeBlock.parallels.length;
for (int i = 0; i < total; i++) {
@@ -190,9 +216,9 @@ public SingleViewVerseAdapter(Context context) {
if (i > 0) {
// force new line for certain parallel patterns
if ((total == 6 && i == 3) || (total == 4 && i == 2) || (total == 5 && i == 3)) {
- sb.append("; \n"); //$NON-NLS-1$
+ sb.append("; \n");
} else {
- sb.append("; "); //$NON-NLS-1$
+ sb.append("; ");
}
}
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/widget/SplitHandleButton.java b/Alkitab/src/main/java/yuku/alkitab/base/widget/SplitHandleButton.java
index cee72e69d..b4b6ec872 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/widget/SplitHandleButton.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/widget/SplitHandleButton.java
@@ -12,7 +12,9 @@ public class SplitHandleButton extends Button {
public interface SplitHandleButtonListener {
void onHandleDragStart();
+ /** Only called when orientation is horizontal */
void onHandleDragMoveX(float dxSinceLast, float dxSinceStart);
+ /** Only called when orientation is vertical */
void onHandleDragMoveY(float dySinceLast, float dySinceStart);
void onHandleDragStop();
}
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/widget/TextAppearancePanel.java b/Alkitab/src/main/java/yuku/alkitab/base/widget/TextAppearancePanel.java
index 474ab581d..86f0fdc79 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/widget/TextAppearancePanel.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/widget/TextAppearancePanel.java
@@ -5,7 +5,6 @@
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Typeface;
-import android.os.Build;
import android.text.SpannableStringBuilder;
import android.text.style.ForegroundColorSpan;
import android.view.LayoutInflater;
@@ -261,9 +260,6 @@ public void reload() {
if (position < 3) {
final String[] defaultFontNames = {"Roboto", "Droid Serif", "Droid Mono"};
- if (Build.VERSION.SDK_INT < 14) {
- defaultFontNames[0] = "Droid Sans";
- }
text1.setText(defaultFontNames[position]);
text1.setTypeface(new Typeface[] {Typeface.SANS_SERIF, Typeface.SERIF, Typeface.MONOSPACE}[position]);
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/widget/VerseAdapter.java b/Alkitab/src/main/java/yuku/alkitab/base/widget/VerseAdapter.java
index d4e91b0f5..969c1d1f8 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/widget/VerseAdapter.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/widget/VerseAdapter.java
@@ -8,6 +8,8 @@
import android.util.Log;
import android.view.LayoutInflater;
import android.widget.BaseAdapter;
+import gnu.trove.set.TIntSet;
+import gnu.trove.set.hash.TIntHashSet;
import yuku.alkitab.base.App;
import yuku.alkitab.base.S;
import yuku.alkitab.base.util.Highlights;
@@ -49,6 +51,12 @@ public abstract class VerseAdapter extends BaseAdapter {
LayoutInflater inflater_;
+ // For calling attention. All attentioned verses have the same start time.
+ // The last call to callAttentionForVerse() decides as when the animation starts.
+ // Calling setData* methods clears the attentioned verses.
+ long attentionStart_;
+ TIntSet attentionPositions_;
+
public VerseAdapter(Context context) {
density_ = context.getResources().getDisplayMetrics().density;
inflater_ = LayoutInflater.from(context);
@@ -59,6 +67,10 @@ public VerseAdapter(Context context) {
verses_ = verses;
pericopeBlocks_ = pericopeBlocks;
itemPointer_ = makeItemPointer(verses_.getVerseCount(), pericopeAris, pericopeBlocks, nblock);
+ attentionStart_ = 0;
+ if (attentionPositions_ != null) {
+ attentionPositions_.clear();
+ }
notifyDataSetChanged();
}
@@ -68,6 +80,10 @@ public VerseAdapter(Context context) {
verses_ = null;
pericopeBlocks_ = null;
itemPointer_ = null;
+ attentionStart_ = 0;
+ if (attentionPositions_ != null) {
+ attentionPositions_.clear();
+ }
notifyDataSetChanged();
}
@@ -275,7 +291,21 @@ public int getVerseFromPosition(int position) {
Log.w(TAG, "pericope title at the last position? does not make sense.");
return 0;
}
-
+
+ void callAttentionForVerse(final int verse_1) {
+ final int pos = getPositionIgnoringPericopeFromVerse(verse_1);
+ if (pos != -1) {
+ TIntSet ap = attentionPositions_;
+ if (ap == null) {
+ attentionPositions_ = ap = new TIntHashSet();
+ }
+ ap.add(pos);
+ attentionStart_ = System.currentTimeMillis();
+
+ notifyDataSetChanged();
+ }
+ }
+
/**
* Similar to {@link #getVerseFromPosition(int)}, but returns 0 if the specified position is a pericope or doesn't make sense.
*/
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/widget/VerseItem.java b/Alkitab/src/main/java/yuku/alkitab/base/widget/VerseItem.java
index 87f6547ed..b371b7fdf 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/widget/VerseItem.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/widget/VerseItem.java
@@ -27,9 +27,10 @@
import java.util.Date;
public class VerseItem extends LinearLayout implements Checkable {
- public static final String TAG = VerseItem.class.getSimpleName();
public static final String PROGRESS_MARK_DRAG_MIME_TYPE = "application/vnd.yuku.alkitab.progress_mark.drag";
+ private static final float ATTENTION_DURATION = 2000L;
+
private boolean checked;
private static Paint checkedPaintSolid;
private boolean collapsed;
@@ -43,6 +44,13 @@ public class VerseItem extends LinearLayout implements Checkable {
/** the ari of the verse represented by this view. If this is 0, this is a pericope or something else. */
private int ari;
+ /**
+ * Whether we briefly "color" this verse resulting from navigation from other parts of the app (e.g. verse navigation, search results).
+ * If the value is 0, it means do not color. If nonzero, it is the starting time when the animation starts.
+ */
+ private long attentionStart;
+ private static Paint attentionPaint;
+
public VerseItem(Context context, AttributeSet attrs) {
super(context, attrs);
}
@@ -90,9 +98,8 @@ protected void onDraw(Canvas canvas) {
final int h = getHeight();
if (checked) {
- Paint solid = VerseItem.checkedPaintSolid;
+ Paint solid = checkedPaintSolid;
if (solid == null) {
- //noinspection deprecation
checkedPaintSolid = solid = new Paint();
final int colorRgb = Preferences.getInt(R.string.pref_selectedVerseBgColor_key, R.integer.pref_selectedVerseBgColor_default);
final int color = ColorUtils.setAlphaComponent(colorRgb, 0xa0);
@@ -114,11 +121,45 @@ protected void onDraw(Canvas canvas) {
dragHoverBg.draw(canvas);
}
+ if (attentionStart != 0) {
+ final long now = System.currentTimeMillis();
+ final long elapsed = now - attentionStart;
+ if (elapsed >= ATTENTION_DURATION) {
+ attentionStart = 0;
+ } else {
+ final float opacity = 0.4f * (1.f - ((float) elapsed / ATTENTION_DURATION));
+ Paint p = attentionPaint;
+ if (p == null) {
+ attentionPaint = p = new Paint();
+ final int colorRgb = Preferences.getInt(R.string.pref_selectedVerseBgColor_key, R.integer.pref_selectedVerseBgColor_default);
+ p.setColor(colorRgb);
+ p.setStyle(Paint.Style.FILL);
+ }
+
+ p.setColor(ColorUtils.setAlphaComponent(p.getColor(), (int) (opacity * 255)));
+ canvas.drawRect(0, 0, w, h, p);
+
+ invalidate(); // animate
+ }
+ }
+
super.onDraw(canvas);
}
+ void callAttention(final long attentionStartTime) {
+ if (this.attentionStart != attentionStartTime) {
+ this.attentionStart = attentionStartTime;
+
+ if (attentionStartTime != 0) {
+ setWillNotDraw(false);
+ }
+ invalidate();
+ }
+ }
+
public static void invalidateSelectedVersePaints() {
checkedPaintSolid = null;
+ attentionPaint = null;
}
@Override
diff --git a/Alkitab/src/main/java/yuku/alkitab/base/widget/VersesView.java b/Alkitab/src/main/java/yuku/alkitab/base/widget/VersesView.java
index 415a71752..2c4cbc45e 100644
--- a/Alkitab/src/main/java/yuku/alkitab/base/widget/VersesView.java
+++ b/Alkitab/src/main/java/yuku/alkitab/base/widget/VersesView.java
@@ -314,14 +314,7 @@ public void checkVerses(IntArrayList verses_1, boolean callListener) {
void hideOrShowContextMenuButton() {
if (verseSelectionMode != VerseSelectionMode.multiple) return;
- SparseBooleanArray checkedPositions = getCheckedItemPositions();
- boolean anyChecked = false;
- if (checkedPositions != null) for (int i = 0; i < checkedPositions.size(); i++) if (checkedPositions.valueAt(i)) {
- anyChecked = true;
- break;
- }
-
- if (anyChecked) {
+ if (getCheckedItemCount() > 0) {
if (listener != null) listener.onSomeVersesSelected(this);
} else {
if (listener != null) listener.onNoVersesSelected(this);
@@ -502,19 +495,8 @@ public void setDataWithRetainSelectedVerses(boolean retainSelectedVerses, int ar
}
}
- public void setVerseSelected(final int verse_1, final boolean selected) {
- int pos = adapter.getPositionIgnoringPericopeFromVerse(verse_1);
- if (pos != -1) {
- setItemChecked(pos, selected);
- if (listener != null) {
- final IntArrayList selectedVerses_1 = getSelectedVerses_1();
- if (selectedVerses_1.size() > 0) {
- listener.onSomeVersesSelected(this);
- } else {
- listener.onNoVersesSelected(this);
- }
- }
- }
+ public void callAttentionForVerse(final int verse_1) {
+ adapter.callAttentionForVerse(verse_1);
}
/**
diff --git a/Alkitab/src/main/java/yuku/alkitab/yes1/Yes1PericopeBlock.java b/Alkitab/src/main/java/yuku/alkitab/yes1/Yes1PericopeBlock.java
index 6e2d994e4..d504bef98 100644
--- a/Alkitab/src/main/java/yuku/alkitab/yes1/Yes1PericopeBlock.java
+++ b/Alkitab/src/main/java/yuku/alkitab/yes1/Yes1PericopeBlock.java
@@ -34,7 +34,7 @@ public static Yes1PericopeBlock read(BintexReader in) throws IOException {
int version = in.readUint8();
if (version > 3) {
- throw new RuntimeException("Parallel block supported is only up to 3. Got version " + version); //$NON-NLS-1$
+ throw new RuntimeException("Parallel block supported is only up to 3. Got version " + version);
}
if (version == 3) {
diff --git a/Alkitab/src/main/java/yuku/alkitab/yes1/Yes1PericopeIndex.java b/Alkitab/src/main/java/yuku/alkitab/yes1/Yes1PericopeIndex.java
index 0664e6552..7d433ac33 100644
--- a/Alkitab/src/main/java/yuku/alkitab/yes1/Yes1PericopeIndex.java
+++ b/Alkitab/src/main/java/yuku/alkitab/yes1/Yes1PericopeIndex.java
@@ -31,14 +31,14 @@ public Yes1PericopeBlock getBlock(BintexReader in, int index) {
int currentPos = in.getPos();
if (currentPos > offset) {
- throw new RuntimeException("currentPos " + currentPos + " > offset " + offset + ", is invalid!"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ throw new RuntimeException("currentPos " + currentPos + " > offset " + offset + ", is invalid!");
}
in.skip(offset - currentPos);
return Yes1PericopeBlock.read(in);
} catch (IOException e) {
- Log.e(TAG, "getBlock error", e); //$NON-NLS-1$
+ Log.e(TAG, "getBlock error", e);
return null;
}
diff --git a/FileChooser/src/main/java/yuku/filechooser/FileChooserActivity.java b/Alkitab/src/main/java/yuku/filechooser/FileChooserActivity.java
similarity index 69%
rename from FileChooser/src/main/java/yuku/filechooser/FileChooserActivity.java
rename to Alkitab/src/main/java/yuku/filechooser/FileChooserActivity.java
index 592723911..f832f79d1 100644
--- a/FileChooser/src/main/java/yuku/filechooser/FileChooserActivity.java
+++ b/Alkitab/src/main/java/yuku/filechooser/FileChooserActivity.java
@@ -5,26 +5,25 @@
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.ActionBar;
-import android.support.v7.app.AppCompatActivity;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
+import yuku.alkitab.base.ac.base.BaseActivity;
+import yuku.alkitab.debug.R;
import java.io.File;
import java.io.FileFilter;
import java.util.Arrays;
-import java.util.Comparator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-public class FileChooserActivity extends AppCompatActivity {
- static final String EXTRA_config = "config"; //$NON-NLS-1$
- static final String EXTRA_result = "result"; //$NON-NLS-1$
+public class FileChooserActivity extends BaseActivity {
+ static final String EXTRA_config = "config";
+ static final String EXTRA_result = "result";
public static Intent createIntent(Context context, FileChooserConfig config) {
Intent res = new Intent(context, FileChooserActivity.class);
@@ -46,6 +45,7 @@ public static FileChooserResult obtainResult(Intent data) {
@Override
public void onCreate(Bundle savedInstanceState) {
+ super.willNeedStoragePermission();
super.onCreate(savedInstanceState);
final ActionBar actionBar = getSupportActionBar();
@@ -66,25 +66,31 @@ public void onCreate(Bundle savedInstanceState) {
init();
}
- private OnItemClickListener lsFile_itemClick = new OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView> parent, View v, int position, long id) {
- File file = adapter.getItem(position);
- if (file != null) {
- if (file.isDirectory()) {
- cd = file;
- ls();
- } else {
- FileChooserResult result = new FileChooserResult();
- result.currentDir = cd.getAbsolutePath();
- result.firstFilename = file.getAbsolutePath();
-
- Intent data = new Intent();
- data.putExtra(EXTRA_result, result);
-
- setResult(RESULT_OK, data);
- finish();
- }
+ @Override
+ protected void onNeededPermissionsGranted(final boolean immediatelyGranted) {
+ super.onNeededPermissionsGranted(immediatelyGranted);
+
+ if (!immediatelyGranted) {
+ init();
+ }
+ }
+
+ private AdapterView.OnItemClickListener lsFile_itemClick = (parent, view, position, id) -> {
+ File file = adapter.getItem(position);
+ if (file != null) {
+ if (file.isDirectory()) {
+ cd = file;
+ ls();
+ } else {
+ FileChooserResult result = new FileChooserResult();
+ result.currentDir = cd.getAbsolutePath();
+ result.firstFilename = file.getAbsolutePath();
+
+ Intent data = new Intent();
+ data.putExtra(EXTRA_result, result);
+
+ setResult(RESULT_OK, data);
+ finish();
}
}
};
@@ -123,7 +129,7 @@ public boolean accept(File pathname) {
}
if (m == null) {
- m = Pattern.compile(config.pattern).matcher(""); //$NON-NLS-1$
+ m = Pattern.compile(config.pattern).matcher("");
}
m.reset(pathname.getName());
@@ -135,28 +141,25 @@ public boolean accept(File pathname) {
files = new File[0];
}
- Arrays.sort(files, new Comparator() {
- @Override
- public int compare(File a, File b) {
- if (a.isDirectory() && !b.isDirectory()) {
- return -1;
- } else if (!a.isDirectory() && b.isDirectory()) {
- return +1;
- }
- // both files or both dirs
-
- String aname = a.getName();
- String bname = b.getName();
-
- // dot-files are later
- if (aname.startsWith(".") && !bname.startsWith(".")) { //$NON-NLS-1$ //$NON-NLS-2$
- return +1;
- } else if (!aname.startsWith(".") && bname.startsWith(".")) { //$NON-NLS-1$ //$NON-NLS-2$
- return -1;
- }
-
- return aname.compareToIgnoreCase(bname);
+ Arrays.sort(files, (a, b) -> {
+ if (a.isDirectory() && !b.isDirectory()) {
+ return -1;
+ } else if (!a.isDirectory() && b.isDirectory()) {
+ return +1;
}
+ // both files or both dirs
+
+ String aname = a.getName();
+ String bname = b.getName();
+
+ // dot-files are later
+ if (aname.startsWith(".") && !bname.startsWith(".")) {
+ return +1;
+ } else if (!aname.startsWith(".") && bname.startsWith(".")) {
+ return -1;
+ }
+
+ return aname.compareToIgnoreCase(bname);
});
adapter.setNewData(files);
diff --git a/FileChooser/src/main/java/yuku/filechooser/FileChooserConfig.java b/Alkitab/src/main/java/yuku/filechooser/FileChooserConfig.java
similarity index 100%
rename from FileChooser/src/main/java/yuku/filechooser/FileChooserConfig.java
rename to Alkitab/src/main/java/yuku/filechooser/FileChooserConfig.java
diff --git a/FileChooser/src/main/java/yuku/filechooser/FileChooserResult.java b/Alkitab/src/main/java/yuku/filechooser/FileChooserResult.java
similarity index 100%
rename from FileChooser/src/main/java/yuku/filechooser/FileChooserResult.java
rename to Alkitab/src/main/java/yuku/filechooser/FileChooserResult.java
diff --git a/FileChooser/src/main/java/yuku/filechooser/Utils.java b/Alkitab/src/main/java/yuku/filechooser/Utils.java
similarity index 100%
rename from FileChooser/src/main/java/yuku/filechooser/Utils.java
rename to Alkitab/src/main/java/yuku/filechooser/Utils.java
diff --git a/FileChooser/src/main/res/drawable-hdpi/filechooser_file.png b/Alkitab/src/main/res/drawable-hdpi/filechooser_file.png
similarity index 100%
rename from FileChooser/src/main/res/drawable-hdpi/filechooser_file.png
rename to Alkitab/src/main/res/drawable-hdpi/filechooser_file.png
diff --git a/FileChooser/src/main/res/drawable-hdpi/filechooser_folder.png b/Alkitab/src/main/res/drawable-hdpi/filechooser_folder.png
similarity index 100%
rename from FileChooser/src/main/res/drawable-hdpi/filechooser_folder.png
rename to Alkitab/src/main/res/drawable-hdpi/filechooser_folder.png
diff --git a/FileChooser/src/main/res/drawable-hdpi/filechooser_up.png b/Alkitab/src/main/res/drawable-hdpi/filechooser_up.png
similarity index 100%
rename from FileChooser/src/main/res/drawable-hdpi/filechooser_up.png
rename to Alkitab/src/main/res/drawable-hdpi/filechooser_up.png
diff --git a/Alkitab/src/main/res/drawable-hdpi/ic_action_content_select_all.png b/Alkitab/src/main/res/drawable-hdpi/ic_action_content_select_all.png
new file mode 100644
index 000000000..30b559090
Binary files /dev/null and b/Alkitab/src/main/res/drawable-hdpi/ic_action_content_select_all.png differ
diff --git a/Alkitab/src/main/res/drawable-hdpi/ic_song_keypad_backspace.png b/Alkitab/src/main/res/drawable-hdpi/ic_keypad_backspace.png
similarity index 100%
rename from Alkitab/src/main/res/drawable-hdpi/ic_song_keypad_backspace.png
rename to Alkitab/src/main/res/drawable-hdpi/ic_keypad_backspace.png
diff --git a/Alkitab/src/main/res/drawable-hdpi/ic_menu_copy.png b/Alkitab/src/main/res/drawable-hdpi/ic_menu_copy.png
index 7e39e2fb2..4eaeeb522 100644
Binary files a/Alkitab/src/main/res/drawable-hdpi/ic_menu_copy.png and b/Alkitab/src/main/res/drawable-hdpi/ic_menu_copy.png differ
diff --git a/FileChooser/src/main/res/drawable-mdpi/filechooser_file.png b/Alkitab/src/main/res/drawable-mdpi/filechooser_file.png
similarity index 100%
rename from FileChooser/src/main/res/drawable-mdpi/filechooser_file.png
rename to Alkitab/src/main/res/drawable-mdpi/filechooser_file.png
diff --git a/FileChooser/src/main/res/drawable-mdpi/filechooser_folder.png b/Alkitab/src/main/res/drawable-mdpi/filechooser_folder.png
similarity index 100%
rename from FileChooser/src/main/res/drawable-mdpi/filechooser_folder.png
rename to Alkitab/src/main/res/drawable-mdpi/filechooser_folder.png
diff --git a/FileChooser/src/main/res/drawable-mdpi/filechooser_up.png b/Alkitab/src/main/res/drawable-mdpi/filechooser_up.png
similarity index 100%
rename from FileChooser/src/main/res/drawable-mdpi/filechooser_up.png
rename to Alkitab/src/main/res/drawable-mdpi/filechooser_up.png
diff --git a/Alkitab/src/main/res/drawable-mdpi/ic_action_content_select_all.png b/Alkitab/src/main/res/drawable-mdpi/ic_action_content_select_all.png
new file mode 100644
index 000000000..590944606
Binary files /dev/null and b/Alkitab/src/main/res/drawable-mdpi/ic_action_content_select_all.png differ
diff --git a/Alkitab/src/main/res/drawable-mdpi/ic_song_keypad_backspace.png b/Alkitab/src/main/res/drawable-mdpi/ic_keypad_backspace.png
similarity index 100%
rename from Alkitab/src/main/res/drawable-mdpi/ic_song_keypad_backspace.png
rename to Alkitab/src/main/res/drawable-mdpi/ic_keypad_backspace.png
diff --git a/Alkitab/src/main/res/drawable-mdpi/ic_menu_copy.png b/Alkitab/src/main/res/drawable-mdpi/ic_menu_copy.png
index e9812741a..303987b83 100644
Binary files a/Alkitab/src/main/res/drawable-mdpi/ic_menu_copy.png and b/Alkitab/src/main/res/drawable-mdpi/ic_menu_copy.png differ
diff --git a/Alkitab/src/main/res/drawable-xhdpi/ic_action_content_select_all.png b/Alkitab/src/main/res/drawable-xhdpi/ic_action_content_select_all.png
new file mode 100644
index 000000000..5333821ba
Binary files /dev/null and b/Alkitab/src/main/res/drawable-xhdpi/ic_action_content_select_all.png differ
diff --git a/Alkitab/src/main/res/drawable-xhdpi/ic_song_keypad_backspace.png b/Alkitab/src/main/res/drawable-xhdpi/ic_keypad_backspace.png
similarity index 100%
rename from Alkitab/src/main/res/drawable-xhdpi/ic_song_keypad_backspace.png
rename to Alkitab/src/main/res/drawable-xhdpi/ic_keypad_backspace.png
diff --git a/Alkitab/src/main/res/drawable-xhdpi/ic_menu_copy.png b/Alkitab/src/main/res/drawable-xhdpi/ic_menu_copy.png
index c6ee59a59..89fd099aa 100644
Binary files a/Alkitab/src/main/res/drawable-xhdpi/ic_menu_copy.png and b/Alkitab/src/main/res/drawable-xhdpi/ic_menu_copy.png differ
diff --git a/Alkitab/src/main/res/drawable-xxhdpi/ic_action_content_select_all.png b/Alkitab/src/main/res/drawable-xxhdpi/ic_action_content_select_all.png
new file mode 100644
index 000000000..9cebc7182
Binary files /dev/null and b/Alkitab/src/main/res/drawable-xxhdpi/ic_action_content_select_all.png differ
diff --git a/Alkitab/src/main/res/drawable-xxhdpi/ic_song_keypad_backspace.png b/Alkitab/src/main/res/drawable-xxhdpi/ic_keypad_backspace.png
similarity index 100%
rename from Alkitab/src/main/res/drawable-xxhdpi/ic_song_keypad_backspace.png
rename to Alkitab/src/main/res/drawable-xxhdpi/ic_keypad_backspace.png
diff --git a/Alkitab/src/main/res/drawable-xxhdpi/ic_menu_copy.png b/Alkitab/src/main/res/drawable-xxhdpi/ic_menu_copy.png
index 2d7536a75..ce295bcb8 100644
Binary files a/Alkitab/src/main/res/drawable-xxhdpi/ic_menu_copy.png and b/Alkitab/src/main/res/drawable-xxhdpi/ic_menu_copy.png differ
diff --git a/Alkitab/src/main/res/drawable-xxxhdpi/ic_action_content_select_all.png b/Alkitab/src/main/res/drawable-xxxhdpi/ic_action_content_select_all.png
new file mode 100644
index 000000000..f89c56f96
Binary files /dev/null and b/Alkitab/src/main/res/drawable-xxxhdpi/ic_action_content_select_all.png differ
diff --git a/Alkitab/src/main/res/drawable-xxxhdpi/ic_menu_copy.png b/Alkitab/src/main/res/drawable-xxxhdpi/ic_menu_copy.png
new file mode 100644
index 000000000..2bc092eca
Binary files /dev/null and b/Alkitab/src/main/res/drawable-xxxhdpi/ic_menu_copy.png differ
diff --git a/Alkitab/src/main/res/drawable/goto_dialer_active.xml b/Alkitab/src/main/res/drawable/goto_dialer_active.xml
index 3848a810a..cd8d82c87 100644
--- a/Alkitab/src/main/res/drawable/goto_dialer_active.xml
+++ b/Alkitab/src/main/res/drawable/goto_dialer_active.xml
@@ -1,6 +1,6 @@
+ android:shape="oval">
diff --git a/Alkitab/src/main/res/drawable/goto_grid_selector.xml b/Alkitab/src/main/res/drawable/goto_grid_selector.xml
deleted file mode 100644
index 03f762551..000000000
--- a/Alkitab/src/main/res/drawable/goto_grid_selector.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Alkitab/src/main/res/layout-land/fragment_goto_dialer.xml b/Alkitab/src/main/res/layout-land/fragment_goto_dialer.xml
index 047f561d6..1ae03362a 100644
--- a/Alkitab/src/main/res/layout-land/fragment_goto_dialer.xml
+++ b/Alkitab/src/main/res/layout-land/fragment_goto_dialer.xml
@@ -1,74 +1,222 @@
-
+ android:layout_height="wrap_content"
+ android:gravity="center_horizontal"
+ android:orientation="vertical">
-
+
+
-
+
+
+ android:layout_gravity="center"
+ tools:listitem="@android:layout/simple_spinner_dropdown_item"
+ android:layout_marginLeft="16dp"
+ android:layout_marginRight="16dp"/>
+
+
+
+
+
+
+ android:textSize="24sp"
+ tools:text="123" />
+ android:layout_height="fill_parent"
+ android:layout_marginLeft="16dp"
+ android:layout_marginRight="8dp"
+ android:gravity="center_vertical"
+ android:text="@string/ayat_sebelumangka" />
+ android:textSize="24sp"
+ tools:text="123" />
-
-
+ android:layout_height="1dp"
+ android:layout_gravity="bottom"
+ android:layout_marginLeft="32dp"
+ android:layout_marginRight="32dp"
+ android:src="#1effffff" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
-
\ No newline at end of file
+
+
diff --git a/Alkitab/src/main/res/layout-land/keypad.xml b/Alkitab/src/main/res/layout-land/keypad.xml
deleted file mode 100644
index 35cdf4fc5..000000000
--- a/Alkitab/src/main/res/layout-land/keypad.xml
+++ /dev/null
@@ -1,129 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Alkitab/src/main/res/layout-small-port/keypad.xml b/Alkitab/src/main/res/layout-small-port/keypad.xml
deleted file mode 100644
index 86cb5cc35..000000000
--- a/Alkitab/src/main/res/layout-small-port/keypad.xml
+++ /dev/null
@@ -1,153 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Alkitab/src/main/res/layout-sw360dp-port/keypad.xml b/Alkitab/src/main/res/layout-sw360dp-port/keypad.xml
deleted file mode 100644
index d367f82a5..000000000
--- a/Alkitab/src/main/res/layout-sw360dp-port/keypad.xml
+++ /dev/null
@@ -1,154 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Alkitab/src/main/res/layout-v17/support_v14_preference_preference_category_material.xml b/Alkitab/src/main/res/layout-v17/support_v14_preference_preference_category_material.xml
new file mode 100644
index 000000000..db3abfe9e
--- /dev/null
+++ b/Alkitab/src/main/res/layout-v17/support_v14_preference_preference_category_material.xml
@@ -0,0 +1,27 @@
+
+
+
+
diff --git a/Alkitab/src/main/res/layout-v17/support_v14_preference_preference_information_material.xml b/Alkitab/src/main/res/layout-v17/support_v14_preference_preference_information_material.xml
new file mode 100644
index 000000000..7b1d82328
--- /dev/null
+++ b/Alkitab/src/main/res/layout-v17/support_v14_preference_preference_information_material.xml
@@ -0,0 +1,72 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Alkitab/src/main/res/layout-v17/support_v14_preference_preference_material.xml b/Alkitab/src/main/res/layout-v17/support_v14_preference_preference_material.xml
new file mode 100644
index 000000000..bc56718bb
--- /dev/null
+++ b/Alkitab/src/main/res/layout-v17/support_v14_preference_preference_material.xml
@@ -0,0 +1,82 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Alkitab/src/main/res/layout-v21/support_v14_preference_preference_category_material.xml b/Alkitab/src/main/res/layout-v21/support_v14_preference_preference_category_material.xml
new file mode 100644
index 000000000..dad9a5cb6
--- /dev/null
+++ b/Alkitab/src/main/res/layout-v21/support_v14_preference_preference_category_material.xml
@@ -0,0 +1,27 @@
+
+
+
+
diff --git a/Alkitab/src/main/res/layout-v21/support_v14_preference_preference_information_material.xml b/Alkitab/src/main/res/layout-v21/support_v14_preference_preference_information_material.xml
new file mode 100644
index 000000000..1166f4e83
--- /dev/null
+++ b/Alkitab/src/main/res/layout-v21/support_v14_preference_preference_information_material.xml
@@ -0,0 +1,72 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Alkitab/src/main/res/layout-v21/support_v14_preference_preference_material.xml b/Alkitab/src/main/res/layout-v21/support_v14_preference_preference_material.xml
new file mode 100644
index 000000000..da6b69fb5
--- /dev/null
+++ b/Alkitab/src/main/res/layout-v21/support_v14_preference_preference_material.xml
@@ -0,0 +1,82 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Alkitab/src/main/res/layout/activity_about.xml b/Alkitab/src/main/res/layout/activity_about.xml
index 55d727cb5..3e60d6735 100644
--- a/Alkitab/src/main/res/layout/activity_about.xml
+++ b/Alkitab/src/main/res/layout/activity_about.xml
@@ -12,7 +12,7 @@
android:layout_height="?attr/actionBarSize"
android:background="@color/primary" />
-
@@ -281,6 +281,6 @@
-
+
diff --git a/Alkitab/src/main/res/layout/activity_devotion.xml b/Alkitab/src/main/res/layout/activity_devotion.xml
index 8d21426cd..b82edf6a0 100644
--- a/Alkitab/src/main/res/layout/activity_devotion.xml
+++ b/Alkitab/src/main/res/layout/activity_devotion.xml
@@ -11,9 +11,5 @@
+ layout="@layout/left_drawer_devotion" />
\ No newline at end of file
diff --git a/Alkitab/src/main/res/layout/activity_devotion_content.xml b/Alkitab/src/main/res/layout/activity_devotion_content.xml
index ca56b3f5a..533864521 100644
--- a/Alkitab/src/main/res/layout/activity_devotion_content.xml
+++ b/Alkitab/src/main/res/layout/activity_devotion_content.xml
@@ -12,7 +12,7 @@
android:background="?attr/colorPrimary" />
@@ -20,7 +20,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
-
@@ -34,7 +34,7 @@
android:text="*Devotion content here."
android:textIsSelectable="true"
tools:ignore="HardcodedText" />
-
+
-
+ android:layout_height="?actionBarSize">
+
+
+
+
+ layout="@layout/left_drawer_text" />
\ No newline at end of file
diff --git a/Alkitab/src/main/res/layout/activity_isi_content.xml b/Alkitab/src/main/res/layout/activity_isi_content.xml
index 5f9a3fda4..75845e9a5 100644
--- a/Alkitab/src/main/res/layout/activity_isi_content.xml
+++ b/Alkitab/src/main/res/layout/activity_isi_content.xml
@@ -10,10 +10,67 @@
android:id="@+id/root"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
- android:layout_marginTop="?attr/actionBarSize"
android:orientation="vertical"
tools:ignore="UselessParent">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Alkitab/src/main/res/layout/activity_patch_text_actionbar_custom.xml b/Alkitab/src/main/res/layout/activity_patch_text_actionbar_custom.xml
index 182153a38..197f339b2 100644
--- a/Alkitab/src/main/res/layout/activity_patch_text_actionbar_custom.xml
+++ b/Alkitab/src/main/res/layout/activity_patch_text_actionbar_custom.xml
@@ -1,7 +1,7 @@
+ layout="@layout/left_drawer_reading_plan" />
\ No newline at end of file
diff --git a/Alkitab/src/main/res/layout/activity_search.xml b/Alkitab/src/main/res/layout/activity_search.xml
index 1c9d93eeb..eabc7f863 100644
--- a/Alkitab/src/main/res/layout/activity_search.xml
+++ b/Alkitab/src/main/res/layout/activity_search.xml
@@ -1,5 +1,6 @@
-
-
+ app:iconifiedByDefault="false" />
-
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Alkitab/src/main/res/layout/activity_search_book_filter.xml b/Alkitab/src/main/res/layout/activity_search_book_filter.xml
index 1ff284a1c..6681f27dc 100644
--- a/Alkitab/src/main/res/layout/activity_search_book_filter.xml
+++ b/Alkitab/src/main/res/layout/activity_search_book_filter.xml
@@ -5,135 +5,14 @@
android:layout_height="match_parent"
android:orientation="vertical">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ android:layout_weight="1" />
-
@@ -86,10 +85,10 @@
android:text="mk dummy 1000 M, 2 L" />
+ android:text="monkey (You will lose your data)" />
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/Alkitab/src/main/res/layout/activity_settings.xml b/Alkitab/src/main/res/layout/activity_settings.xml
new file mode 100644
index 000000000..43a1ebb32
--- /dev/null
+++ b/Alkitab/src/main/res/layout/activity_settings.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
diff --git a/Alkitab/src/main/res/layout/activity_song_view.xml b/Alkitab/src/main/res/layout/activity_song_view.xml
index 2c132e326..d34f2a485 100644
--- a/Alkitab/src/main/res/layout/activity_song_view.xml
+++ b/Alkitab/src/main/res/layout/activity_song_view.xml
@@ -11,9 +11,5 @@
+ layout="@layout/left_drawer_songs" />
\ No newline at end of file
diff --git a/Alkitab/src/main/res/layout/activity_song_view_content.xml b/Alkitab/src/main/res/layout/activity_song_view_content.xml
index 9d780dbe8..0d6be1bef 100644
--- a/Alkitab/src/main/res/layout/activity_song_view_content.xml
+++ b/Alkitab/src/main/res/layout/activity_song_view_content.xml
@@ -21,7 +21,7 @@
diff --git a/Alkitab/src/main/res/layout/activity_sync_login.xml b/Alkitab/src/main/res/layout/activity_sync_login.xml
index 39f009833..1d60957a0 100644
--- a/Alkitab/src/main/res/layout/activity_sync_login.xml
+++ b/Alkitab/src/main/res/layout/activity_sync_login.xml
@@ -1,5 +1,5 @@
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/Alkitab/src/main/res/layout/activity_versions.xml b/Alkitab/src/main/res/layout/activity_versions.xml
index 9fbe50d77..fae74bd03 100644
--- a/Alkitab/src/main/res/layout/activity_versions.xml
+++ b/Alkitab/src/main/res/layout/activity_versions.xml
@@ -7,13 +7,13 @@
-
+ android:layout_height="?actionBarSize" />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Alkitab/src/main/res/layout/buttonbar_cancelok.xml b/Alkitab/src/main/res/layout/buttonbar_cancelok.xml
index 2340bbef6..9ff82fe42 100644
--- a/Alkitab/src/main/res/layout/buttonbar_cancelok.xml
+++ b/Alkitab/src/main/res/layout/buttonbar_cancelok.xml
@@ -11,7 +11,7 @@
android:showDividers="beginning">
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Alkitab/src/main/res/layout/dialog_edit_bookmark.xml b/Alkitab/src/main/res/layout/dialog_edit_bookmark.xml
index 24c54ca34..212de4bf4 100644
--- a/Alkitab/src/main/res/layout/dialog_edit_bookmark.xml
+++ b/Alkitab/src/main/res/layout/dialog_edit_bookmark.xml
@@ -1,5 +1,5 @@
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/Alkitab/src/main/res/layout/dialog_version_add_from_url.xml b/Alkitab/src/main/res/layout/dialog_version_add_from_url.xml
index 37eeec09d..e002119e1 100644
--- a/Alkitab/src/main/res/layout/dialog_version_add_from_url.xml
+++ b/Alkitab/src/main/res/layout/dialog_version_add_from_url.xml
@@ -1,5 +1,5 @@
-
@@ -31,4 +31,4 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/FileChooser/src/main/res/layout/filechooser_activity_filechooser.xml b/Alkitab/src/main/res/layout/filechooser_activity_filechooser.xml
similarity index 100%
rename from FileChooser/src/main/res/layout/filechooser_activity_filechooser.xml
rename to Alkitab/src/main/res/layout/filechooser_activity_filechooser.xml
diff --git a/FileChooser/src/main/res/layout/filechooser_activity_folderchooser.xml b/Alkitab/src/main/res/layout/filechooser_activity_folderchooser.xml
similarity index 100%
rename from FileChooser/src/main/res/layout/filechooser_activity_folderchooser.xml
rename to Alkitab/src/main/res/layout/filechooser_activity_folderchooser.xml
diff --git a/Alkitab/src/main/res/layout/fragment_goto_dialer.xml b/Alkitab/src/main/res/layout/fragment_goto_dialer.xml
index d92633219..0ebf4b446 100644
--- a/Alkitab/src/main/res/layout/fragment_goto_dialer.xml
+++ b/Alkitab/src/main/res/layout/fragment_goto_dialer.xml
@@ -1,32 +1,40 @@
-
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center_horizontal"
+ android:orientation="vertical">
-
+
+
+
+
+
+
+
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ android:gravity="center"
+ android:orientation="horizontal">
+ tools:text="123" />
+ tools:text="123" />
-
-
-
+ android:layout_height="1dp"
+ android:src="#1effffff"
+ android:layout_marginLeft="32dp"
+ android:layout_marginRight="32dp" />
-
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Alkitab/src/main/res/layout/fragment_goto_direct.xml b/Alkitab/src/main/res/layout/fragment_goto_direct.xml
index f640072ea..9e7c073cc 100644
--- a/Alkitab/src/main/res/layout/fragment_goto_direct.xml
+++ b/Alkitab/src/main/res/layout/fragment_goto_direct.xml
@@ -1,31 +1,40 @@
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:paddingTop="16dp">
-
+
-
-
+
-
+
+
+
+
\ No newline at end of file
diff --git a/Alkitab/src/main/res/layout/fragment_goto_grid.xml b/Alkitab/src/main/res/layout/fragment_goto_grid.xml
index 51986233a..6bc727f43 100644
--- a/Alkitab/src/main/res/layout/fragment_goto_grid.xml
+++ b/Alkitab/src/main/res/layout/fragment_goto_grid.xml
@@ -4,14 +4,10 @@
android:layout_width="match_parent"
android:layout_height="wrap_content">
-
+ android:layout_height="wrap_content" />
+ tools:text="*Selected book" />
+ tools:text="*chap" />
-
+ android:layout_height="wrap_content" />
-
+ android:layout_height="wrap_content" />
diff --git a/Alkitab/src/main/res/layout/item_goto_grid_cell.xml b/Alkitab/src/main/res/layout/item_goto_grid_cell.xml
new file mode 100644
index 000000000..16efb148e
--- /dev/null
+++ b/Alkitab/src/main/res/layout/item_goto_grid_cell.xml
@@ -0,0 +1,7 @@
+
+
\ No newline at end of file
diff --git a/Alkitab/src/main/res/layout/item_pericope_header.xml b/Alkitab/src/main/res/layout/item_pericope_header.xml
index 5764e3ea8..b70ad1992 100644
--- a/Alkitab/src/main/res/layout/item_pericope_header.xml
+++ b/Alkitab/src/main/res/layout/item_pericope_header.xml
@@ -1,7 +1,6 @@
diff --git a/Alkitab/src/main/res/layout/item_verse.xml b/Alkitab/src/main/res/layout/item_verse.xml
index ffbd3b0be..ce1133b0c 100644
--- a/Alkitab/src/main/res/layout/item_verse.xml
+++ b/Alkitab/src/main/res/layout/item_verse.xml
@@ -1,6 +1,5 @@
diff --git a/Alkitab/src/main/res/layout/item_version.xml b/Alkitab/src/main/res/layout/item_version.xml
index 0a301d4b3..3f6deea8c 100644
--- a/Alkitab/src/main/res/layout/item_version.xml
+++ b/Alkitab/src/main/res/layout/item_version.xml
@@ -50,7 +50,7 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Alkitab/src/main/res/layout/left_drawer_devotion.xml b/Alkitab/src/main/res/layout/left_drawer_devotion.xml
index 599fcd8e5..42ffecc35 100644
--- a/Alkitab/src/main/res/layout/left_drawer_devotion.xml
+++ b/Alkitab/src/main/res/layout/left_drawer_devotion.xml
@@ -4,10 +4,12 @@
class="yuku.alkitab.base.widget.LeftDrawer$Devotion"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="240dp"
- android:background="#263238"
- android:elevation="4dp"
+ android:id="@+id/left_drawer"
+ android:layout_width="@dimen/left_drawer_width"
android:layout_height="match_parent"
+ android:layout_gravity="start"
+ android:background="#263238"
+ android:elevation="4dp"
tools:ignore="Overdraw">
@@ -21,7 +23,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content" />
-
@@ -34,11 +36,11 @@
android:textAppearance="?android:textAppearanceSmall"
tools:text="*Info Bla bla bla, bla bla, bla bla, bla bla, bla bla, blablabla, blablablabla." />
-
+