diff --git a/app/src/main/java/it/niedermann/owncloud/notes/android/activity/EditNoteActivity.java b/app/src/main/java/it/niedermann/owncloud/notes/android/activity/EditNoteActivity.java index 4db29f06..12b42594 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/android/activity/EditNoteActivity.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/android/activity/EditNoteActivity.java @@ -252,7 +252,9 @@ public class EditNoteActivity extends AppCompatActivity implements BaseNoteFragm ActionBar actionBar = Objects.requireNonNull(getSupportActionBar()); if (note != null) { actionBar.setTitle(note.getTitle()); - if (!note.getCategory().isEmpty()) { + if (note.getCategory().isEmpty()) { + actionBar.setSubtitle(null); + } else { actionBar.setSubtitle(NoteUtil.extendCategory(note.getCategory())); } } else { diff --git a/app/src/main/java/it/niedermann/owncloud/notes/android/fragment/CategoryAdapter.java b/app/src/main/java/it/niedermann/owncloud/notes/android/fragment/CategoryAdapter.java index 7859a4a4..8a129c6c 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/android/fragment/CategoryAdapter.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/android/fragment/CategoryAdapter.java @@ -1,11 +1,13 @@ package it.niedermann.owncloud.notes.android.fragment; +import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import androidx.annotation.NonNull; +import androidx.appcompat.widget.AppCompatImageView; import androidx.recyclerview.widget.RecyclerView; import java.util.ArrayList; @@ -14,19 +16,22 @@ import java.util.List; import butterknife.BindView; import butterknife.ButterKnife; import it.niedermann.owncloud.notes.R; -import it.niedermann.owncloud.notes.android.fragment.CategoryDialogFragment.CategoryDialogListener; -import it.niedermann.owncloud.notes.model.NavigationAdapter; +import it.niedermann.owncloud.notes.model.NavigationAdapter.NavigationItem; import it.niedermann.owncloud.notes.util.NoteUtil; public class CategoryAdapter extends RecyclerView.Adapter { + private static final String clearItemId = "clear_item"; + private static final String addItemId = "add_item"; @NonNull - private List categories = new ArrayList<>(); + private List categories = new ArrayList<>(); @NonNull - private CategoryDialogListener categoryListener; + private CategoryListener listener; + private Context context; - CategoryAdapter(@NonNull CategoryDialogListener categoryListener) { - this.categoryListener = categoryListener; + CategoryAdapter(@NonNull Context context, @NonNull CategoryListener categoryListener) { + this.context = context; + this.listener = categoryListener; } @NonNull @@ -38,10 +43,30 @@ public class CategoryAdapter extends RecyclerView.Adapter categoryListener.onCategoryChosen(NoteUtil.extendCategory(category.label))); - categoryViewHolder.category.setText(category.label); + categoryViewHolder.categoryWrapper.setOnClickListener((v) -> { + switch (category.id) { + case addItemId: { + listener.onCategoryAdded(); + break; + } + case clearItemId: { + listener.onCategoryCleared(); + break; + } + default: { + listener.onCategoryChosen(category.label); + } + } + }); + categoryViewHolder.category.setText(NoteUtil.extendCategory(category.label)); + if (category.count > 0) { + categoryViewHolder.count.setText(String.valueOf(category.count)); + } else { + categoryViewHolder.count.setVisibility(View.GONE); + } + categoryViewHolder.icon.setImageDrawable(context.getResources().getDrawable(category.icon)); } @Override @@ -50,17 +75,49 @@ public class CategoryAdapter extends RecyclerView.Adapter categories) { + void setCategoryList(List categories, String currentSearchString) { this.categories = categories; + NavigationItem clearItem = new NavigationItem(clearItemId, context.getString(R.string.no_category), 0, R.drawable.ic_clear_grey_24dp); + this.categories.add(0, clearItem); + if (currentSearchString != null && currentSearchString.trim().length() > 0) { + boolean currentSearchStringIsInCategories = false; + for (NavigationItem category : categories) { + if (currentSearchString.equals(category.label)) { + currentSearchStringIsInCategories = true; + break; + } + } + if (!currentSearchStringIsInCategories) { + NavigationItem addItem = new NavigationItem(addItemId, context.getString(R.string.add_category, currentSearchString.trim()), 0, R.drawable.ic_add_blue_24dp); + this.categories.add(addItem); + } + } notifyDataSetChanged(); } + + public interface CategoryListener { + void onCategoryChosen(String category); + + void onCategoryAdded(); + + void onCategoryCleared(); + } } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/android/fragment/CategoryDialogFragment.java b/app/src/main/java/it/niedermann/owncloud/notes/android/fragment/CategoryDialogFragment.java index 2c7d0155..ebecfa7d 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/android/fragment/CategoryDialogFragment.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/android/fragment/CategoryDialogFragment.java @@ -15,6 +15,7 @@ import android.widget.EditText; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatDialogFragment; +import androidx.fragment.app.Fragment; import androidx.recyclerview.widget.RecyclerView; import java.util.List; @@ -36,6 +37,7 @@ public class CategoryDialogFragment extends AppCompatDialogFragment { private static final String TAG = CategoryDialogFragment.class.getSimpleName(); private static final String STATE_CATEGORY = "category"; + private NoteSQLiteOpenHelper db; private CategoryDialogListener listener; /** @@ -79,6 +81,7 @@ public class CategoryDialogFragment extends AppCompatDialogFragment { } else { throw new IllegalArgumentException("Calling activity or target fragment must implement " + CategoryDialogListener.class.getCanonicalName()); } + db = NoteSQLiteOpenHelper.getInstance(getActivity()); } @NonNull @@ -95,9 +98,24 @@ public class CategoryDialogFragment extends AppCompatDialogFragment { editCategory.setText(savedInstanceState.getString(STATE_CATEGORY)); } - adapter = new CategoryAdapter((String category) -> { - listener.onCategoryChosen(category); - dismiss(); + adapter = new CategoryAdapter(Objects.requireNonNull(getContext()), new CategoryAdapter.CategoryListener() { + @Override + public void onCategoryChosen(String category) { + listener.onCategoryChosen(category); + dismiss(); + } + + @Override + public void onCategoryAdded() { + listener.onCategoryChosen(editCategory.getText().toString()); + dismiss(); + } + + @Override + public void onCategoryCleared() { + listener.onCategoryChosen(""); + dismiss(); + } }); recyclerView.setAdapter(adapter); @@ -110,12 +128,12 @@ public class CategoryDialogFragment extends AppCompatDialogFragment { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { - new LoadCategoriesTask().execute(editCategory.getText().toString()); + // Nothing to do here... } @Override public void afterTextChanged(Editable s) { - // Nothing to do here.... + new LoadCategoriesTask().execute(editCategory.getText().toString()); } }); @@ -137,6 +155,7 @@ public class CategoryDialogFragment extends AppCompatDialogFragment { @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); + editCategory.requestFocus(); if (getDialog().getWindow() != null) { getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE); } else { @@ -146,17 +165,17 @@ public class CategoryDialogFragment extends AppCompatDialogFragment { private class LoadCategoriesTask extends AsyncTask> { + String currentSearchString; + @Override protected List doInBackground(String... searchText) { - NoteSQLiteOpenHelper db = NoteSQLiteOpenHelper.getInstance(getActivity()); - return (searchText[0] == null || searchText[0].length() == 0) - ? db.getCategories(accountId) - : db.searchCategories(accountId, searchText[0]); + currentSearchString = searchText[0]; + return db.searchCategories(accountId, currentSearchString); } @Override protected void onPostExecute(List categories) { - adapter.setCategoryList(categories); + adapter.setCategoryList(categories, currentSearchString); } } } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/model/CategoryAdapter.java b/app/src/main/java/it/niedermann/owncloud/notes/model/CategoryAdapter.java deleted file mode 100644 index a8209153..00000000 --- a/app/src/main/java/it/niedermann/owncloud/notes/model/CategoryAdapter.java +++ /dev/null @@ -1,71 +0,0 @@ -package it.niedermann.owncloud.notes.model; - -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.RecyclerView; - -import java.util.ArrayList; -import java.util.List; - -import butterknife.BindView; -import butterknife.ButterKnife; -import it.niedermann.owncloud.notes.R; - -public class CategoryAdapter extends RecyclerView.Adapter { - - private List categoryList; - - public CategoryAdapter() { - this.categoryList = new ArrayList<>(); - } - - /** - * Updates the item list and notifies respective view to update. - * - * @param categoryList List of items to be set - */ - public void setCategoryList(@NonNull List categoryList) { - this.categoryList = categoryList; - notifyDataSetChanged(); - } - - /** - * Adds the given note to the top of the list. - * - * @param category Category that should be added. - */ - public void add(@NonNull String category) { - categoryList.add(0, category); - notifyItemInserted(0); - notifyItemChanged(0); - } - - @Override - public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - return new CategoryViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.dialog_change_category_single, parent, false)); - } - - @Override - public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) { - ((CategoryViewHolder) holder).title.setText(categoryList.get(position)); - } - - @Override - public int getItemCount() { - return categoryList.size(); - } - - static class CategoryViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.title) - TextView title; - - CategoryViewHolder(View view) { - super(view); - ButterKnife.bind(this, view); - } - } -} \ No newline at end of file diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/NoteSQLiteOpenHelper.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/NoteSQLiteOpenHelper.java index 6435bb7e..e1d4d2c1 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/NoteSQLiteOpenHelper.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/NoteSQLiteOpenHelper.java @@ -635,8 +635,8 @@ public class NoteSQLiteOpenHelper extends SQLiteOpenHelper { Cursor cursor = db.query( table_notes, new String[]{key_category, "COUNT(*)"}, - key_status + " != ? AND " + key_account_id + " = ? AND " + key_category + " LIKE ?", - new String[]{DBStatus.LOCAL_DELETED.getTitle(), "" + accountId, "%" + search + "%"}, + key_status + " != ? AND " + key_account_id + " = ? AND " + key_category + " LIKE ? AND " + key_category + " != \"\"", + new String[]{DBStatus.LOCAL_DELETED.getTitle(), String.valueOf(accountId), "%" + (search == null ? search : search.trim()) + "%"}, key_category, null, key_category); diff --git a/app/src/main/res/drawable/ic_clear_grey_24dp.xml b/app/src/main/res/drawable/ic_clear_grey_24dp.xml new file mode 100644 index 00000000..c02b28cd --- /dev/null +++ b/app/src/main/res/drawable/ic_clear_grey_24dp.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/layout/dialog_change_category.xml b/app/src/main/res/layout/dialog_change_category.xml index 0a66b0c3..61720591 100644 --- a/app/src/main/res/layout/dialog_change_category.xml +++ b/app/src/main/res/layout/dialog_change_category.xml @@ -1,24 +1,29 @@ - + android:layout_height="wrap_content"> + + + diff --git a/app/src/main/res/layout/dialog_change_category_single.xml b/app/src/main/res/layout/dialog_change_category_single.xml deleted file mode 100644 index 9a845a99..00000000 --- a/app/src/main/res/layout/dialog_change_category_single.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/drawer_layout.xml b/app/src/main/res/layout/drawer_layout.xml index 2ab35b41..d628df3f 100644 --- a/app/src/main/res/layout/drawer_layout.xml +++ b/app/src/main/res/layout/drawer_layout.xml @@ -107,21 +107,24 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> - - + + + + android:background="?android:selectableItemBackground" + android:clickable="true" + android:focusable="true" + android:padding="16dp"> + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 129ab77e..78f63ec4 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -144,6 +144,8 @@ Deleted %1$d notes Restored %1$d notes Read only + No category + Add %1$s