2 * Copyright © 2021 Damyan Ivanov.
3 * This file is part of MoLe.
4 * MoLe is free software: you can distribute it and/or modify it
5 * under the term of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your opinion), any later version.
9 * MoLe is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License terms for details.
14 * You should have received a copy of the GNU General Public License
15 * along with MoLe. If not, see <https://www.gnu.org/licenses/>.
18 package net.ktnx.mobileledger.ui;
20 import android.app.Dialog;
21 import android.content.Context;
22 import android.os.Bundle;
23 import android.view.LayoutInflater;
24 import android.view.View;
26 import androidx.annotation.NonNull;
27 import androidx.annotation.Nullable;
28 import androidx.annotation.StringRes;
29 import androidx.appcompat.app.AppCompatDialogFragment;
30 import androidx.lifecycle.ViewModelProvider;
31 import androidx.recyclerview.widget.GridLayoutManager;
32 import androidx.recyclerview.widget.LinearLayoutManager;
33 import androidx.recyclerview.widget.RecyclerView;
35 import net.ktnx.mobileledger.R;
36 import net.ktnx.mobileledger.databinding.FragmentTemplateDetailSourceSelectorListBinding;
37 import net.ktnx.mobileledger.model.TemplateDetailSource;
38 import net.ktnx.mobileledger.utils.Logger;
39 import net.ktnx.mobileledger.utils.Misc;
41 import java.util.ArrayList;
42 import java.util.regex.Matcher;
43 import java.util.regex.Pattern;
46 * A fragment representing a list of Items.
48 * Activities containing this fragment MUST implement the {@link OnSourceSelectedListener}
51 public class TemplateDetailSourceSelectorFragment extends AppCompatDialogFragment
52 implements OnSourceSelectedListener {
54 public static final int DEFAULT_COLUMN_COUNT = 1;
55 public static final String ARG_COLUMN_COUNT = "column-count";
56 public static final String ARG_PATTERN = "pattern";
57 public static final String ARG_TEST_TEXT = "test-text";
58 private int mColumnCount = DEFAULT_COLUMN_COUNT;
59 private ArrayList<TemplateDetailSource> mSources;
60 private TemplateDetailSourceSelectorModel model;
61 private OnSourceSelectedListener onSourceSelectedListener;
66 * Mandatory empty constructor for the fragment manager to instantiate the
67 * fragment (e.g. upon screen orientation changes).
69 public TemplateDetailSourceSelectorFragment() {
71 @SuppressWarnings("unused")
72 public static TemplateDetailSourceSelectorFragment newInstance() {
73 return newInstance(DEFAULT_COLUMN_COUNT, null, null);
75 public static TemplateDetailSourceSelectorFragment newInstance(int columnCount,
76 @Nullable String pattern,
77 @Nullable String testText) {
78 TemplateDetailSourceSelectorFragment fragment = new TemplateDetailSourceSelectorFragment();
79 Bundle args = new Bundle();
80 args.putInt(ARG_COLUMN_COUNT, columnCount);
82 args.putString(ARG_PATTERN, pattern);
84 args.putString(ARG_TEST_TEXT, testText);
85 fragment.setArguments(args);
89 public void onCreate(Bundle savedInstanceState) {
90 super.onCreate(savedInstanceState);
92 if (getArguments() != null) {
93 mColumnCount = getArguments().getInt(ARG_COLUMN_COUNT, DEFAULT_COLUMN_COUNT);
94 final String patternText = getArguments().getString(ARG_PATTERN);
95 final String testText = getArguments().getString(ARG_TEST_TEXT);
96 if (Misc.emptyIsNull(patternText) == null) {
97 mPatternProblem = R.string.missing_pattern_error;
100 if (Misc.emptyIsNull(testText) == null) {
101 mPatternProblem = R.string.missing_test_text;
104 Pattern pattern = Pattern.compile(patternText);
105 Matcher matcher = pattern.matcher(testText);
106 Logger.debug("templates",
107 String.format("Trying to match pattern '%s' against text '%s'",
108 patternText, testText));
109 if (matcher.find()) {
110 if (matcher.groupCount() >= 0) {
111 ArrayList<TemplateDetailSource> list = new ArrayList<>();
112 for (short g = 1; g <= matcher.groupCount(); g++) {
113 list.add(new TemplateDetailSource(g, matcher.group(g)));
118 mPatternProblem = R.string.pattern_without_groups;
122 mPatternProblem = R.string.pattern_does_not_match;
130 public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
131 Context context = requireContext();
132 Dialog csd = new Dialog(context);
133 FragmentTemplateDetailSourceSelectorListBinding b =
134 FragmentTemplateDetailSourceSelectorListBinding.inflate(
135 LayoutInflater.from(context));
136 csd.setContentView(b.getRoot());
137 csd.setTitle(R.string.choose_template_detail_source_label);
139 if (mSources != null && !mSources.isEmpty()) {
140 RecyclerView recyclerView = b.list;
142 if (mColumnCount <= 1) {
143 recyclerView.setLayoutManager(new LinearLayoutManager(context));
146 recyclerView.setLayoutManager(new GridLayoutManager(context, mColumnCount));
148 model = new ViewModelProvider(this).get(TemplateDetailSourceSelectorModel.class);
149 if (onSourceSelectedListener != null)
150 model.setOnSourceSelectedListener(onSourceSelectedListener);
151 model.setSourcesList(mSources);
153 TemplateDetailSourceSelectorRecyclerViewAdapter adapter =
154 new TemplateDetailSourceSelectorRecyclerViewAdapter();
155 model.groups.observe(this, adapter::submitList);
157 recyclerView.setAdapter(adapter);
158 adapter.setSourceSelectedListener(this);
161 b.list.setVisibility(View.GONE);
162 b.templateError.setText(
163 (mPatternProblem != 0) ? mPatternProblem : R.string.pattern_without_groups);
164 b.templateError.setVisibility(View.VISIBLE);
167 b.literalButton.setOnClickListener(v -> onSourceSelected(true, (short) -1));
171 public void setOnSourceSelectedListener(OnSourceSelectedListener listener) {
172 onSourceSelectedListener = listener;
175 model.setOnSourceSelectedListener(listener);
177 public void resetOnSourceSelectedListener() {
178 model.resetOnSourceSelectedListener();
181 public void onSourceSelected(boolean literal, short group) {
183 model.triggerOnSourceSelectedListener(literal, group);
184 if (onSourceSelectedListener != null)
185 onSourceSelectedListener.onSourceSelected(literal, group);