diff --git a/app/src/main/java/acr/browser/lightning/activity/BrowserActivity.java b/app/src/main/java/acr/browser/lightning/activity/BrowserActivity.java index 81c0c73..30ee04a 100644 --- a/app/src/main/java/acr/browser/lightning/activity/BrowserActivity.java +++ b/app/src/main/java/acr/browser/lightning/activity/BrowserActivity.java @@ -9,6 +9,7 @@ import android.animation.LayoutTransition; import android.animation.ValueAnimator; import android.animation.ValueAnimator.AnimatorUpdateListener; import android.app.Activity; +import android.app.Dialog; import android.content.ClipData; import android.content.ClipboardManager; import android.content.Context; @@ -16,7 +17,6 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.content.res.Configuration; -import android.content.res.Resources.Theme; import android.database.Cursor; import android.database.sqlite.SQLiteException; import android.graphics.Bitmap; @@ -95,7 +95,6 @@ import android.widget.TextView; import android.widget.TextView.OnEditorActionListener; import android.widget.VideoView; -import java.io.BufferedOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; @@ -119,7 +118,6 @@ import acr.browser.lightning.R; import acr.browser.lightning.constant.BookmarkPage; import acr.browser.lightning.constant.Constants; import acr.browser.lightning.constant.HistoryPage; -import acr.browser.lightning.constant.StartPage; import acr.browser.lightning.controller.BrowserController; import acr.browser.lightning.database.BookmarkManager; import acr.browser.lightning.database.HistoryDatabase; @@ -324,7 +322,7 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse mSearch.setOnTouchListener(search.new TouchListener()); mSystemBrowser = getSystemBrowser(); - Thread initialize = new Thread(new Runnable() { + new Thread(new Runnable() { @Override public void run() { @@ -346,8 +344,7 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse initializeSearchSuggestions(mSearch); } - }); - initialize.run(); + }).run(); View view = findViewById(R.id.bookmark_back_button); view.setOnClickListener(new OnClickListener() { @@ -817,9 +814,8 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse * adapter doesn't always change when notifyDataChanged gets called. */ private void notifyBookmarkDataSetChanged() { - if (mBookmarkAdapter == null) - return; - mBookmarkAdapter.notifyDataSetChanged(); + if (mBookmarkAdapter != null) + mBookmarkAdapter.notifyDataSetChanged(); } private void addBookmark(String title, String url) { @@ -836,8 +832,7 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse private void setBookmarkDataSet(List items, boolean animate) { mBookmarkList.clear(); mBookmarkList.addAll(items); - if (mBookmarkAdapter != null) - mBookmarkAdapter.notifyDataSetChanged(); + notifyBookmarkDataSetChanged(); final int resource; if (mBookmarkManager.isRootFolder()) resource = R.drawable.ic_action_star; @@ -876,10 +871,11 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse startRotation.setDuration(250); finishRotation.setDuration(250); - if (animate) + if (animate) { mBookmarkTitleImage.startAnimation(startRotation); - else + } else { mBookmarkTitleImage.setImageResource(resource); + } } /** @@ -979,7 +975,7 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse @Override public void onItemClick(AdapterView parent, View view, int position, long id) { if (mBookmarkList.get(position).getIsFolder()) { - setBookmarkDataSet(mBookmarkManager.getBookmarksFromFolder(mBookmarkList.get(position).getUrl(), true), true); + setBookmarkDataSet(mBookmarkManager.getBookmarksFromFolder(mBookmarkList.get(position).getTitle(), true), true); return; } if (mCurrentView != null) { @@ -1001,49 +997,10 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse @Override public boolean onItemLongClick(AdapterView arg0, View arg1, final int position, long arg3) { - - if (mBookmarkList.get(position).getIsFolder()) - return true; - AlertDialog.Builder builder = new AlertDialog.Builder(mActivity); - builder.setTitle(mActivity.getResources().getString(R.string.action_bookmarks)); - builder.setMessage(getResources().getString(R.string.dialog_bookmark)) - .setCancelable(true) - .setPositiveButton(getResources().getString(R.string.action_new_tab), - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int id) { - newTab(mBookmarkList.get(position).getUrl(), false); - mDrawerLayout.closeDrawers(); - } - }) - .setNegativeButton(getResources().getString(R.string.action_delete), - new DialogInterface.OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - if (mBookmarkManager.deleteBookmark(mBookmarkList.get(position))) { - mBookmarkList.remove(position); - notifyBookmarkDataSetChanged(); - mSearchAdapter.refreshBookmarks(); - openBookmarks(); - if (mCurrentView != null) { - updateBookmarkIndicator(mCurrentView.getUrl()); - } - } - } - }) - .setNeutralButton(getResources().getString(R.string.action_edit), - new DialogInterface.OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - editBookmark(position); - } - }); - AlertDialog alert = builder.create(); - alert.show(); + longPressBookmarkLink(mBookmarkList.get(position).getUrl()); return true; } + } /** @@ -1107,6 +1064,49 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse editBookmarkDialog.show(); } + /** + * Show a dialog to rename a folder + * + * @param id the position of the HistoryItem (folder) in the bookmark list + */ + private synchronized void renameFolder(final int id) { + final AlertDialog.Builder editFolderDialog = new AlertDialog.Builder(mActivity); + editFolderDialog.setTitle(R.string.title_rename_folder); + final EditText getTitle = new EditText(mActivity); + getTitle.setHint(R.string.hint_title); + getTitle.setText(mBookmarkList.get(id).getTitle()); + getTitle.setSingleLine(); + LinearLayout layout = new LinearLayout(mActivity); + layout.setOrientation(LinearLayout.VERTICAL); + int padding = Utils.convertDpToPixels(10); + layout.setPadding(padding, padding, padding, padding); + layout.addView(getTitle); + editFolderDialog.setView(layout); + editFolderDialog.setPositiveButton(getResources().getString(R.string.action_ok), + new DialogInterface.OnClickListener() { + + @Override + public void onClick(DialogInterface dialog, int which) { + String oldTitle = mBookmarkList.get(id).getTitle(); + String newTitle = getTitle.getText().toString(); + + mBookmarkManager.renameFolder(oldTitle, newTitle); + + setBookmarkDataSet(mBookmarkManager.getBookmarksFromFolder(null, true), false); + + Collections.sort(mBookmarkList, new SortIgnoreCase()); + if (mCurrentView != null && mCurrentView.getUrl().startsWith(Constants.FILE) + && mCurrentView.getUrl().endsWith(BookmarkPage.FILENAME)) { + openBookmarkPage(mWebView); + } + if (mCurrentView != null) { + updateBookmarkIndicator(mCurrentView.getUrl()); + } + } + }); + editFolderDialog.show(); + } + /** * displays the WebView contained in the LightningView Also handles the * removal of previous views @@ -1366,7 +1366,6 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse finish(); } - @SuppressWarnings("deprecation") private void clearHistory() { this.deleteDatabase(HistoryDatabase.DATABASE_NAME); WebViewDatabase m = WebViewDatabase.getInstance(this); @@ -1385,7 +1384,6 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse Utils.trimCache(this); } - @SuppressWarnings("deprecation") private void clearCookies() { // TODO Break out web storage deletion into its own option/action // TODO clear web storage for all sites that are visited in Incognito mode @@ -2528,7 +2526,51 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse } } + private void longPressFolder(String url) { + final int position = BookmarkManager.getIndexOfBookmark(mBookmarkList, url); + if (position == -1) { + return; + } + DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + switch (which) { + case DialogInterface.BUTTON_POSITIVE: + renameFolder(position); + break; + + case DialogInterface.BUTTON_NEGATIVE: + mBookmarkManager.deleteFolder(mBookmarkList.get(position).getTitle()); + + setBookmarkDataSet(mBookmarkManager.getBookmarksFromFolder(null, true), false); + + Collections.sort(mBookmarkList, new SortIgnoreCase()); + if (mCurrentView != null && mCurrentView.getUrl().startsWith(Constants.FILE) + && mCurrentView.getUrl().endsWith(BookmarkPage.FILENAME)) { + openBookmarkPage(mWebView); + } + if (mCurrentView != null) { + updateBookmarkIndicator(mCurrentView.getUrl()); + } + break; + } + } + }; + + AlertDialog.Builder builder = new AlertDialog.Builder(mActivity); + builder.setTitle(R.string.action_folder) + .setMessage(R.string.dialog_folder) + .setCancelable(true) + .setPositiveButton(R.string.action_rename, dialogClickListener) + .setNegativeButton(R.string.action_delete, dialogClickListener) + .show(); + } + private void longPressBookmarkLink(final String url) { + if (url.startsWith(Constants.FOLDER)) { + longPressFolder(url); + return; + } final int position = BookmarkManager.getIndexOfBookmark(mBookmarkList, url); if (position == -1) { return; @@ -2541,7 +2583,6 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse newTab(mBookmarkList.get(position).getUrl(), false); mDrawerLayout.closeDrawers(); break; - case DialogInterface.BUTTON_NEGATIVE: if (mBookmarkManager.deleteBookmark(mBookmarkList.get(position))) { mBookmarkList.remove(position); @@ -2553,7 +2594,6 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse } } break; - case DialogInterface.BUTTON_NEUTRAL: editBookmark(position); break; @@ -2562,8 +2602,8 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse }; AlertDialog.Builder builder = new AlertDialog.Builder(mActivity); - builder.setTitle(R.string.action_bookmarks); - builder.setMessage(R.string.dialog_bookmark) + builder.setTitle(R.string.action_bookmarks) + .setMessage(R.string.dialog_bookmark) .setCancelable(true) .setPositiveButton(R.string.action_new_tab, dialogClickListener) .setNegativeButton(R.string.action_delete, dialogClickListener) @@ -2596,8 +2636,8 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse }; AlertDialog.Builder builder = new AlertDialog.Builder(mActivity); - builder.setTitle(R.string.action_history); - builder.setMessage(R.string.dialog_history_long_press) + builder.setTitle(R.string.action_history) + .setMessage(R.string.dialog_history_long_press) .setCancelable(true) .setPositiveButton(R.string.action_new_tab, dialogClickListener) .setNegativeButton(R.string.action_delete, dialogClickListener) @@ -2814,7 +2854,7 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse public void onReceive(Context context, Intent intent) { super.onReceive(context, intent); boolean isConnected = isConnected(context); - Log.d("Lightning", "Network Connected: " + String.valueOf(isConnected)); + Log.d(Constants.TAG, "Network Connected: " + String.valueOf(isConnected)); for (int n = 0; n < mWebViewList.size(); n++) { WebView view = mWebViewList.get(n).getWebView(); if (view != null) diff --git a/app/src/main/java/acr/browser/lightning/database/BookmarkManager.java b/app/src/main/java/acr/browser/lightning/database/BookmarkManager.java index ee4619e..3f5d9fb 100644 --- a/app/src/main/java/acr/browser/lightning/database/BookmarkManager.java +++ b/app/src/main/java/acr/browser/lightning/database/BookmarkManager.java @@ -5,9 +5,11 @@ import android.content.Context; import android.database.Cursor; import android.os.Environment; import android.provider.Browser; +import android.support.annotation.NonNull; import org.json.JSONException; import org.json.JSONObject; +import org.w3c.dom.ls.LSInput; import java.io.BufferedReader; import java.io.BufferedWriter; @@ -19,11 +21,13 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Set; import acr.browser.lightning.R; +import acr.browser.lightning.constant.Constants; import acr.browser.lightning.preference.PreferenceManager; import acr.browser.lightning.utils.Utils; @@ -126,38 +130,52 @@ public class BookmarkManager { * @param deleteItem the bookmark item to delete */ public synchronized boolean deleteBookmark(HistoryItem deleteItem) { - List list; if (deleteItem == null || deleteItem.getIsFolder()) { return false; } mBookmarkSearchSet.remove(deleteItem.getUrl()); mBookmarkList.remove(deleteItem); - list = getAllBookmarks(false); - File bookmarksFile = new File(mContext.getFilesDir(), FILE_BOOKMARKS); - boolean bookmarkDeleted = false; - BufferedWriter fileWriter = null; - String url = deleteItem.getUrl(); - try { - fileWriter = new BufferedWriter(new FileWriter(bookmarksFile, false)); - JSONObject object = new JSONObject(); - for (HistoryItem item : list) { - if (!item.getUrl().equalsIgnoreCase(url)) { - object.put(TITLE, item.getTitle()); - object.put(URL, item.getUrl()); - object.put(FOLDER, item.getFolder()); - object.put(ORDER, item.getOrder()); - fileWriter.write(object.toString()); - fileWriter.newLine(); - } else { - bookmarkDeleted = true; - } + overwriteBookmarks(mBookmarkList); + return true; + } + + /** + * renames a folder and moves all it's contents to that folder + * + * @param oldName the folder to be renamed + * @param newName the new name of the folder + */ + public synchronized void renameFolder(@NonNull String oldName, @NonNull String newName) { + if (newName.length() == 0) { + return; + } + for (int n = 0; n < mBookmarkList.size(); n++) { + if (mBookmarkList.get(n).getFolder().equals(oldName)) { + mBookmarkList.get(n).setFolder(newName); + } else if (mBookmarkList.get(n).getIsFolder() && mBookmarkList.get(n).getTitle().equals(oldName)) { + mBookmarkList.get(n).setTitle(newName); + mBookmarkList.get(n).setUrl(Constants.FOLDER + newName); } - } catch (IOException | JSONException e) { - e.printStackTrace(); - } finally { - Utils.close(fileWriter); } - return bookmarkDeleted; + overwriteBookmarks(mBookmarkList); + } + + /** + * Delete the folder and move all bookmarks to the top level + * + * @param name the name of the folder to be deleted + */ + public synchronized void deleteFolder(@NonNull String name) { + Iterator iterator = mBookmarkList.iterator(); + while (iterator.hasNext()) { + HistoryItem item = iterator.next(); + if (!item.getIsFolder() && item.getFolder().equals(name)) { + item.setFolder(""); + } else if (item.getTitle().equals(name)) { + iterator.remove(); + } + } + overwriteBookmarks(mBookmarkList); } /** @@ -167,7 +185,6 @@ public class BookmarkManager { * @param newItem This is the new item that will overwrite the old item */ public synchronized void editBookmark(HistoryItem oldItem, HistoryItem newItem) { - List list; if (oldItem == null || newItem == null || oldItem.getIsFolder()) { return; } @@ -185,33 +202,7 @@ public class BookmarkManager { if (newItem.getTitle().length() == 0) { newItem.setTitle(mContext.getString(R.string.untitled)); } - list = getAllBookmarks(false); - File bookmarksFile = new File(mContext.getFilesDir(), FILE_BOOKMARKS); - BufferedWriter fileWriter = null; - try { - fileWriter = new BufferedWriter(new FileWriter(bookmarksFile, false)); - JSONObject object = new JSONObject(); - final String url = oldItem.getUrl(); - for (HistoryItem item : list) { - if (!item.getUrl().equalsIgnoreCase(url)) { - object.put(TITLE, item.getTitle()); - object.put(URL, item.getUrl()); - object.put(FOLDER, item.getFolder()); - object.put(ORDER, item.getOrder()); - } else { - object.put(TITLE, newItem.getTitle()); - object.put(URL, newItem.getUrl()); - object.put(FOLDER, newItem.getFolder()); - object.put(ORDER, newItem.getOrder()); - } - fileWriter.write(object.toString()); - fileWriter.newLine(); - } - } catch (IOException | JSONException e) { - e.printStackTrace(); - } finally { - Utils.close(fileWriter); - } + overwriteBookmarks(mBookmarkList); } /** @@ -380,7 +371,7 @@ public class BookmarkManager { if (!folderName.isEmpty() && !folderMap.contains(folderName)) { HistoryItem item = new HistoryItem(); item.setTitle(folderName); - item.setUrl(folderName); + item.setUrl(Constants.FOLDER + folderName); item.setIsFolder(true); folderMap.add(folderName); folders.add(item); @@ -431,9 +422,7 @@ public class BookmarkManager { Utils.showSnackbar(activity, number + " " + mContext.getResources().getString(R.string.message_import)); } else { - String title = activity.getResources().getString(R.string.title_error); - String message = activity.getResources().getString(R.string.dialog_import_error); - Utils.createInformativeDialog(activity, title, message); + Utils.createInformativeDialog(activity, R.string.title_error, R.string.dialog_import_error); } } @@ -468,9 +457,7 @@ public class BookmarkManager { Utils.showSnackbar(activity, number + " " + message); } catch (IOException | JSONException e) { e.printStackTrace(); - String title = activity.getResources().getString(R.string.title_error); - String message = activity.getResources().getString(R.string.import_bookmark_error); - Utils.createInformativeDialog(activity, title, message); + Utils.createInformativeDialog(activity, R.string.title_error, R.string.import_bookmark_error); } finally { Utils.close(bookmarksReader); } @@ -483,13 +470,14 @@ public class BookmarkManager { * * @param list the list of bookmarks to overwrite the old ones with */ - public synchronized void overwriteBookmarks(List list) { + private synchronized void overwriteBookmarks(List list) { File bookmarksFile = new File(mContext.getFilesDir(), FILE_BOOKMARKS); BufferedWriter bookmarkWriter = null; try { bookmarkWriter = new BufferedWriter(new FileWriter(bookmarksFile, false)); JSONObject object = new JSONObject(); - for (HistoryItem item : list) { + for (int n = 0; n < list.size(); n++) { + HistoryItem item = list.get(n); if (!item.getIsFolder()) { object.put(TITLE, item.getTitle()); object.put(URL, item.getUrl()); diff --git a/app/src/main/java/acr/browser/lightning/fragment/GeneralSettingsFragment.java b/app/src/main/java/acr/browser/lightning/fragment/GeneralSettingsFragment.java index 9e3c240..c55d4ab 100644 --- a/app/src/main/java/acr/browser/lightning/fragment/GeneralSettingsFragment.java +++ b/app/src/main/java/acr/browser/lightning/fragment/GeneralSettingsFragment.java @@ -565,9 +565,7 @@ public class GeneralSettingsFragment extends PreferenceFragment implements Prefe mPreferences.setFlashSupport(0); } if (!Utils.isFlashInstalled(mActivity) && cbFlash.isChecked()) { - Utils.createInformativeDialog(mActivity, - mActivity.getResources().getString(R.string.title_warning), - mActivity.getResources().getString(R.string.dialog_adobe_not_installed)); + Utils.createInformativeDialog(mActivity, R.string.title_warning, R.string.dialog_adobe_not_installed); cbFlash.setEnabled(false); mPreferences.setFlashSupport(0); } diff --git a/app/src/main/java/acr/browser/lightning/object/SearchAdapter.java b/app/src/main/java/acr/browser/lightning/object/SearchAdapter.java index 750ae67..2114b39 100644 --- a/app/src/main/java/acr/browser/lightning/object/SearchAdapter.java +++ b/app/src/main/java/acr/browser/lightning/object/SearchAdapter.java @@ -82,21 +82,9 @@ public class SearchAdapter extends BaseAdapter implements Filterable { } }); - int color = mDarkTheme ? ThemeUtils.getIconDarkThemeColor(context) : ThemeUtils.getIconLightThemeColor(context); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - mSearchDrawable = context.getDrawable(R.drawable.ic_search); - mBookmarkDrawable = context.getDrawable(R.drawable.ic_bookmark); - mHistoryDrawable = context.getDrawable(R.drawable.ic_history); - } else { - mSearchDrawable = context.getResources().getDrawable(R.drawable.ic_search); - mBookmarkDrawable = context.getResources().getDrawable(R.drawable.ic_bookmark); - mHistoryDrawable = context.getResources().getDrawable(R.drawable.ic_history); - } - if (mSearchDrawable != null && mBookmarkDrawable != null && mHistoryDrawable != null) { - mSearchDrawable.setColorFilter(color, PorterDuff.Mode.SRC_IN); - mBookmarkDrawable.setColorFilter(color, PorterDuff.Mode.SRC_IN); - mHistoryDrawable.setColorFilter(color, PorterDuff.Mode.SRC_IN); - } + mSearchDrawable = ThemeUtils.getThemedDrawable(context, R.drawable.ic_search, mDarkTheme); + mBookmarkDrawable = ThemeUtils.getThemedDrawable(context, R.drawable.ic_bookmark, mDarkTheme); + mHistoryDrawable = ThemeUtils.getThemedDrawable(context, R.drawable.ic_history, mDarkTheme); delete.start(); } diff --git a/app/src/main/java/acr/browser/lightning/utils/ThemeUtils.java b/app/src/main/java/acr/browser/lightning/utils/ThemeUtils.java index ad1084c..6b541ec 100644 --- a/app/src/main/java/acr/browser/lightning/utils/ThemeUtils.java +++ b/app/src/main/java/acr/browser/lightning/utils/ThemeUtils.java @@ -71,6 +71,22 @@ public class ThemeUtils { return resultBitmap; } + @Nullable + public static Drawable getThemedDrawable(@NonNull Context context, @DrawableRes int res, boolean dark){ + int color = dark ? getIconDarkThemeColor(context) : getIconLightThemeColor(context); + final Drawable drawable; + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { + drawable = context.getResources().getDrawable(res); + } else { + drawable = context.getDrawable(res); + } + if (drawable == null) + return null; + drawable.mutate(); + drawable.setColorFilter(color, PorterDuff.Mode.SRC_IN); + return drawable; + } + @Nullable public static Drawable getLightThemedDrawable(@NonNull Context context, @DrawableRes int res){ final Drawable drawable; diff --git a/app/src/main/java/acr/browser/lightning/utils/Utils.java b/app/src/main/java/acr/browser/lightning/utils/Utils.java index 6ef4f22..e637422 100644 --- a/app/src/main/java/acr/browser/lightning/utils/Utils.java +++ b/app/src/main/java/acr/browser/lightning/utils/Utils.java @@ -62,7 +62,7 @@ public final class Utils { return intent; } - public static void createInformativeDialog(Context context, String title, String message) { + public static void createInformativeDialog(Context context, @StringRes int title, @StringRes int message) { AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setTitle(title); builder.setMessage(message) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7c906ec..c0f723d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -205,4 +205,8 @@ Light Theme Black Theme (AMOLED) Folder Name + Folder + Rename + Rename Folder + What would you like to do with this folder?