From 0c1abb3c9c8a19d9e2eecaf515bbfbb5f9f07bb0 Mon Sep 17 00:00:00 2001 From: Jessie Chatham Spencer Date: Thu, 15 Jun 2017 08:44:44 +0000 Subject: [PATCH] Added support for all versioning types in the app UI. Addressing #718 (#896) * Merge branch 'Fix718' Merged fixes for issues #718, added functionality for all the file versioning types in the app UI. * Basic theme is working * GOt dialog working with setREsult. * Addressed issues raised and fixed orientation change bug. Adressed issues radied by nutomic: - Changed the String concatenation so it uses String.format. - Made members variables private that were not previously private by mistake. - Changed name from FolderPathTextView to FolderPathTextViewFragment. - Fixed typo in NumberPickerFragment - Now uses TImeUnit for time conversion - Changed from DialogFragment to a dialog themed Activity inorder to have correct themeing. About the orientation change bug. When the dialog themed activity was open and the orientation was changed, it would cause the background activity(The FolderActivity) to recreate itself. In the process of recreating itself it would reset the mFolder variable and then reinitialise it in the OnApiChange listener. However the result from the Dialog was returned before the mFolder had been reinitialised and was still null, so inbetween the result being returned and the mFolder variable being reinitialised the new file versioning configuration had to be stored and then applied to the mFolder variable in the onApiChange listener. The file versioning configuration is temporarily stored in the mVersioning variable which is an instance of Folder.versioning. This error only occurred when using an Activity as a dialog and using the startActivityForResult method for initialisling the activity. Before when using a dialogfragment and an interface to callback to the parent activity, everything happend in the correct order. * Fixed versioning dialog lag. The initial updateFragmentView() is called in onCreate() and the fragment is only updated when a new file versioning type is selected. * Removed FolderPathTextViewFragment The fragment is removed, and a helper method has been added to FolderPickerActivity to create an intent to the the FolderPickerActivity for result. --- build.gradle | 1 + src/main/AndroidManifest.xml | 10 +- .../activities/FolderActivity.java | 173 ++++++++++++------ .../activities/FolderPickerActivity.java | 13 ++ .../activities/VersioningDialogActivity.java | 134 ++++++++++++++ .../fragments/NumberPickerFragment.java | 39 ++++ .../dialog/ExternalVersioningFragment.java | 74 ++++++++ .../dialog/KeepVersionsDialogFragment.java | 88 --------- .../dialog/NoVersioningFragment.java | 19 ++ .../dialog/SimpleVersioningFragment.java | 61 ++++++ .../dialog/StaggeredVersioningFragment.java | 97 ++++++++++ .../dialog/TrashCanVersioningFragment.java | 57 ++++++ .../res/layout/activity_versioning_dialog.xml | 11 ++ .../layout/fragment_directory_text_view.xml | 10 + .../layout/fragment_external_versioning.xml | 30 +++ src/main/res/layout/fragment_folder.xml | 33 +++- .../res/layout/fragment_no_versioning.xml | 12 ++ .../res/layout/fragment_simple_versioning.xml | 46 +++++ .../layout/fragment_staggered_versioning.xml | 70 +++++++ .../layout/fragment_trashcan_versioning.xml | 47 +++++ .../res/layout/fragment_versioning_dialog.xml | 44 +++++ src/main/res/layout/numberpicker_fragment.xml | 5 + src/main/res/values/strings.xml | 42 +++++ 23 files changed, 963 insertions(+), 153 deletions(-) create mode 100644 src/main/java/com/nutomic/syncthingandroid/activities/VersioningDialogActivity.java create mode 100644 src/main/java/com/nutomic/syncthingandroid/fragments/NumberPickerFragment.java create mode 100644 src/main/java/com/nutomic/syncthingandroid/fragments/dialog/ExternalVersioningFragment.java delete mode 100644 src/main/java/com/nutomic/syncthingandroid/fragments/dialog/KeepVersionsDialogFragment.java create mode 100644 src/main/java/com/nutomic/syncthingandroid/fragments/dialog/NoVersioningFragment.java create mode 100644 src/main/java/com/nutomic/syncthingandroid/fragments/dialog/SimpleVersioningFragment.java create mode 100644 src/main/java/com/nutomic/syncthingandroid/fragments/dialog/StaggeredVersioningFragment.java create mode 100644 src/main/java/com/nutomic/syncthingandroid/fragments/dialog/TrashCanVersioningFragment.java create mode 100644 src/main/res/layout/activity_versioning_dialog.xml create mode 100644 src/main/res/layout/fragment_directory_text_view.xml create mode 100644 src/main/res/layout/fragment_external_versioning.xml create mode 100644 src/main/res/layout/fragment_no_versioning.xml create mode 100644 src/main/res/layout/fragment_simple_versioning.xml create mode 100644 src/main/res/layout/fragment_staggered_versioning.xml create mode 100644 src/main/res/layout/fragment_trashcan_versioning.xml create mode 100644 src/main/res/layout/fragment_versioning_dialog.xml create mode 100644 src/main/res/layout/numberpicker_fragment.xml diff --git a/build.gradle b/build.gradle index af9ed675..6ea54708 100644 --- a/build.gradle +++ b/build.gradle @@ -28,6 +28,7 @@ dependencies { compile 'com.google.guava:guava:20.0' compile 'com.annimon:stream:1.1.7' compile 'com.android.volley:volley:1.0.0' + compile 'com.android.support.constraint:constraint-layout:1.0.2' androidTestCompile 'com.android.support.test:rules:0.5' androidTestCompile 'com.android.support:support-annotations:25.3.1' } diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml index ec6fe710..0b4f1cca 100644 --- a/src/main/AndroidManifest.xml +++ b/src/main/AndroidManifest.xml @@ -132,6 +132,14 @@ + + + - + \ No newline at end of file diff --git a/src/main/java/com/nutomic/syncthingandroid/activities/FolderActivity.java b/src/main/java/com/nutomic/syncthingandroid/activities/FolderActivity.java index b181c98b..06c62097 100644 --- a/src/main/java/com/nutomic/syncthingandroid/activities/FolderActivity.java +++ b/src/main/java/com/nutomic/syncthingandroid/activities/FolderActivity.java @@ -3,7 +3,6 @@ package com.nutomic.syncthingandroid.activities; import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; -import android.content.DialogInterface; import android.content.Intent; import android.os.Build; import android.os.Bundle; @@ -27,14 +26,17 @@ import android.widget.Toast; import com.google.common.base.Objects; import com.google.gson.Gson; import com.nutomic.syncthingandroid.R; -import com.nutomic.syncthingandroid.fragments.dialog.KeepVersionsDialogFragment; import com.nutomic.syncthingandroid.model.Device; import com.nutomic.syncthingandroid.model.Folder; import com.nutomic.syncthingandroid.service.SyncthingService; import com.nutomic.syncthingandroid.util.TextWatcherAdapter; +import org.w3c.dom.Text; + import java.util.List; import java.util.Random; +import java.util.Map; +import java.util.concurrent.TimeUnit; import static android.support.v4.view.MarginLayoutParamsCompat.setMarginEnd; import static android.support.v4.view.MarginLayoutParamsCompat.setMarginStart; @@ -42,7 +44,6 @@ import static android.util.TypedValue.COMPLEX_UNIT_DIP; import static android.view.Gravity.CENTER_VERTICAL; import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; import static com.nutomic.syncthingandroid.service.SyncthingService.State.ACTIVE; -import static java.lang.String.valueOf; /** * Shows folder details and allows changing them. @@ -59,15 +60,13 @@ public class FolderActivity extends SyncthingActivity public static final String EXTRA_DEVICE_ID = "com.nutomic.syncthingandroid.activities.FolderActivity.DEVICE_ID"; - - private static final int DIRECTORY_REQUEST_CODE = 234; - private static final String TAG = "EditFolderFragment"; - public static final String KEEP_VERSIONS_DIALOG_TAG = "KeepVersionsDialogFragment"; private static final String IS_SHOWING_DELETE_DIALOG = "DELETE_FOLDER_DIALOG_STATE"; private static final String IS_SHOW_DISCARD_DIALOG = "DISCARD_FOLDER_DIALOG_STATE"; + private static final int FILE_VERSIONING_DIALOG_REQUEST = 3454; + private Folder mFolder; private EditText mLabelView; @@ -75,7 +74,8 @@ public class FolderActivity extends SyncthingActivity private TextView mPathView; private SwitchCompat mFolderMasterView; private ViewGroup mDevicesContainer; - private TextView mVersioningKeepView; + private TextView mVersioningDescriptionView; + private TextView mVersioningTypeView; private boolean mIsCreateMode; private boolean mFolderNeedsToUpdate; @@ -83,7 +83,7 @@ public class FolderActivity extends SyncthingActivity private Dialog mDeleteDialog; private Dialog mDiscardDialog; - private final KeepVersionsDialogFragment mKeepVersionsDialogFragment = new KeepVersionsDialogFragment(); + private Folder.Versioning mVersioning; private final TextWatcher mTextWatcher = new TextWatcherAdapter() { @Override @@ -117,33 +117,6 @@ public class FolderActivity extends SyncthingActivity } }; - private final KeepVersionsDialogFragment.OnValueChangeListener mOnValueChangeListener = - new KeepVersionsDialogFragment.OnValueChangeListener() { - @Override - public void onValueChange(int intValue) { - if (intValue == 0) { - mFolder.versioning = new Folder.Versioning(); - mVersioningKeepView.setText(R.string.off); - } else { - mFolder.versioning.type = "simple"; - mFolder.versioning.params.put("keep", valueOf(intValue)); - mVersioningKeepView.setText(valueOf(intValue)); - } - mFolderNeedsToUpdate = true; - } - }; - - private final View.OnClickListener mPathViewClickListener = new View.OnClickListener() { - @Override - public void onClick(View v) { - Intent intent = new Intent(FolderActivity.this, FolderPickerActivity.class); - if (!TextUtils.isEmpty(mFolder.path)) { - intent.putExtra(FolderPickerActivity.EXTRA_INITIAL_DIRECTORY, mFolder.path); - } - startActivityForResult(intent, DIRECTORY_REQUEST_CODE); - } - }; - @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -155,14 +128,16 @@ public class FolderActivity extends SyncthingActivity mLabelView = (EditText) findViewById(R.id.label); mIdView = (EditText) findViewById(R.id.id); - mPathView = (TextView) findViewById(R.id.directory); + mPathView = (TextView) findViewById(R.id.directoryTextView); mFolderMasterView = (SwitchCompat) findViewById(R.id.master); - mVersioningKeepView = (TextView) findViewById(R.id.versioningKeep); + mVersioningDescriptionView = (TextView) findViewById(R.id.versioningDescription); + mVersioningTypeView = (TextView) findViewById(R.id.versioningType); mDevicesContainer = (ViewGroup) findViewById(R.id.devicesContainer); - mPathView.setOnClickListener(mPathViewClickListener); - findViewById(R.id.versioningContainer).setOnClickListener(v -> - mKeepVersionsDialogFragment.show(getFragmentManager(), KEEP_VERSIONS_DIALOG_TAG)); + mPathView.setOnClickListener(view -> + startActivityForResult(FolderPickerActivity.createIntent(this, mFolder.path), FolderPickerActivity.DIRECTORY_REQUEST_CODE)); + + findViewById(R.id.versioningContainer).setOnClickListener(v -> showVersioningDialog()); if (mIsCreateMode) { if (savedInstanceState != null) { @@ -186,6 +161,33 @@ public class FolderActivity extends SyncthingActivity showDeleteDialog(); } } + + if (savedInstanceState != null){ + if (savedInstanceState.getBoolean(IS_SHOWING_DELETE_DIALOG)){ + showDeleteDialog(); + } + } + } + + private void showVersioningDialog() { + Intent intent = new Intent(this, VersioningDialogActivity.class); + intent.putExtras(getVersioningBundle()); + startActivityForResult(intent, FILE_VERSIONING_DIALOG_REQUEST); + } + + private Bundle getVersioningBundle() { + Bundle bundle = new Bundle(); + for (Map.Entry entry: mFolder.versioning.params.entrySet()){ + bundle.putString(entry.getKey(), entry.getValue()); + } + + if (TextUtils.isEmpty(mFolder.versioning.type)){ + bundle.putString("type", "none"); + } else{ + bundle.putString("type", mFolder.versioning.type); + } + + return bundle; } @Override @@ -262,20 +264,32 @@ public class FolderActivity extends SyncthingActivity mFolderNeedsToUpdate = true; } + attemptToApplyVersioningConfig(); + updateViewsAndSetListeners(); } + // If the FolderActivity gets recreated after the VersioningDialogActivity is closed, then the result from the VersioningDialogActivity will be received before + // the mFolder variable has been recreated, so the versioning config will be stored in the mVersioning variable until the mFolder variable has been + // recreated in the onApiChange(). This has been observed to happen after the screen orientation has changed while the VersioningDialogActivity was open. + private void attemptToApplyVersioningConfig() { + if (mFolder != null && mVersioning != null){ + mFolder.versioning = mVersioning; + mVersioning = null; + } + } + private void updateViewsAndSetListeners() { mLabelView.removeTextChangedListener(mTextWatcher); mIdView.removeTextChangedListener(mTextWatcher); mPathView.removeTextChangedListener(mTextWatcher); mFolderMasterView.setOnCheckedChangeListener(null); - mKeepVersionsDialogFragment.setOnValueChangeListener(null); // Update views mLabelView.setText(mFolder.label); mIdView.setText(mFolder.id); mPathView.setText(mFolder.path); + updateVersioningDescription(); mFolderMasterView.setChecked(Objects.equal(mFolder.type, "readonly")); List devicesList = getApi().getDevices(false); @@ -288,22 +302,11 @@ public class FolderActivity extends SyncthingActivity } } - boolean versioningEnabled = Objects.equal(mFolder.versioning.type, "simple"); - int versions = 0; - if (versioningEnabled) { - versions = Integer.valueOf(mFolder.versioning.params.get("keep")); - mVersioningKeepView.setText(valueOf(versions)); - } else { - mVersioningKeepView.setText(R.string.off); - } - mKeepVersionsDialogFragment.setValue(versions); - // Keep state updated mLabelView.addTextChangedListener(mTextWatcher); mIdView.addTextChangedListener(mTextWatcher); mPathView.addTextChangedListener(mTextWatcher); mFolderMasterView.setOnCheckedChangeListener(mCheckedListener); - mKeepVersionsDialogFragment.setOnValueChangeListener(mOnValueChangeListener); } @Override @@ -365,10 +368,12 @@ public class FolderActivity extends SyncthingActivity @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { - if (resultCode == Activity.RESULT_OK && requestCode == DIRECTORY_REQUEST_CODE) { + if (resultCode == Activity.RESULT_OK && requestCode == FolderPickerActivity.DIRECTORY_REQUEST_CODE) { mFolder.path = data.getStringExtra(FolderPickerActivity.EXTRA_RESULT_DIRECTORY); mPathView.setText(mFolder.path); mFolderNeedsToUpdate = true; + } else if (resultCode == Activity.RESULT_OK && requestCode == FILE_VERSIONING_DIALOG_REQUEST) { + updateVersioning(data.getExtras()); } } @@ -460,4 +465,64 @@ public class FolderActivity extends SyncthingActivity .setNegativeButton(android.R.string.cancel, null) .create(); } + + private void updateVersioning(Bundle arguments) { + if (mFolder != null){ + mVersioning = mFolder.versioning; + } else { + mVersioning = new Folder.Versioning(); + } + + String type = arguments.getString("type"); + arguments.remove("type"); + + if (type.equals("none")){ + mVersioning = new Folder.Versioning(); + } else { + for (String key : arguments.keySet()) { + mVersioning.params.put(key, arguments.getString(key)); + } + mVersioning.type = type; + } + + attemptToApplyVersioningConfig(); + updateVersioningDescription(); + mFolderNeedsToUpdate = true; + } + + private void updateVersioningDescription() { + if (mFolder == null){ + return; + } + + if (TextUtils.isEmpty(mFolder.versioning.type)) { + setVersioningDescription(getString(R.string.none), ""); + return; + } + + switch (mFolder.versioning.type) { + case "simple": + setVersioningDescription(getString(R.string.type_simple), + getString(R.string.simple_versioning_info, mFolder.versioning.params.get("keep"))); + break; + case "trashcan": + setVersioningDescription(getString(R.string.type_trashcan), + getString(R.string.trashcan_versioning_info, mFolder.versioning.params.get("cleanoutDays"))); + break; + case "staggered": + int maxAge = (int) TimeUnit.SECONDS.toDays(Long.valueOf(mFolder.versioning.params.get("maxAge"))); + setVersioningDescription(getString(R.string.type_staggered), + getString(R.string.staggered_versioning_info, maxAge, mFolder.versioning.params.get("versionsPath"))); + break; + case "external": + setVersioningDescription(getString(R.string.type_external), + getString(R.string.external_versioning_info, mFolder.versioning.params.get("command"))); + break; + } + } + + private void setVersioningDescription(String type, String description) { + mVersioningTypeView.setText(type); + mVersioningDescriptionView.setText(description); + } } diff --git a/src/main/java/com/nutomic/syncthingandroid/activities/FolderPickerActivity.java b/src/main/java/com/nutomic/syncthingandroid/activities/FolderPickerActivity.java index a8cd47ce..61bd7bfb 100644 --- a/src/main/java/com/nutomic/syncthingandroid/activities/FolderPickerActivity.java +++ b/src/main/java/com/nutomic/syncthingandroid/activities/FolderPickerActivity.java @@ -14,6 +14,7 @@ import android.os.IBinder; import android.preference.PreferenceManager; import android.support.annotation.NonNull; import android.support.v4.content.ContextCompat; +import android.text.TextUtils; import android.view.Menu; import android.view.MenuItem; import android.view.View; @@ -50,6 +51,8 @@ public class FolderPickerActivity extends SyncthingActivity public static final String EXTRA_RESULT_DIRECTORY = "com.nutomic.syncthingandroid.activities.FolderPickerActivity.RESULT_DIRECTORY"; + public static final int DIRECTORY_REQUEST_CODE = 234; + private ListView mListView; private FileAdapter mFilesAdapter; @@ -61,6 +64,16 @@ public class FolderPickerActivity extends SyncthingActivity */ private File mLocation; + public static Intent createIntent(Context context, String currentPath) { + Intent intent = new Intent(context, FolderPickerActivity.class); + + if (!TextUtils.isEmpty(currentPath)) { + intent.putExtra(FolderPickerActivity.EXTRA_INITIAL_DIRECTORY, currentPath); + } + + return intent; + } + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); diff --git a/src/main/java/com/nutomic/syncthingandroid/activities/VersioningDialogActivity.java b/src/main/java/com/nutomic/syncthingandroid/activities/VersioningDialogActivity.java new file mode 100644 index 00000000..aa00bedc --- /dev/null +++ b/src/main/java/com/nutomic/syncthingandroid/activities/VersioningDialogActivity.java @@ -0,0 +1,134 @@ +package com.nutomic.syncthingandroid.activities; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentTransaction; +import android.support.v7.app.AppCompatActivity; +import android.view.View; +import android.widget.AdapterView; +import android.widget.Button; +import android.widget.Spinner; +import com.nutomic.syncthingandroid.R; +import com.nutomic.syncthingandroid.fragments.dialog.ExternalVersioningFragment; +import com.nutomic.syncthingandroid.fragments.dialog.NoVersioningFragment; +import com.nutomic.syncthingandroid.fragments.dialog.SimpleVersioningFragment; +import com.nutomic.syncthingandroid.fragments.dialog.StaggeredVersioningFragment; +import com.nutomic.syncthingandroid.fragments.dialog.TrashCanVersioningFragment; + +import java.util.Arrays; +import java.util.List; + +public class VersioningDialogActivity extends AppCompatActivity { + + private Fragment mCurrentFragment; + + private List mTypes = Arrays.asList("none", "trashcan", "simple", "staggered", "external"); + + private Bundle mArguments; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.fragment_versioning_dialog); + + if (savedInstanceState != null) { + mArguments = savedInstanceState.getBundle("arguments"); + } else { + mArguments = getIntent().getExtras(); + } + + updateFragmentView(mTypes.indexOf(getIntent().getExtras().getString("type"))); + initiateFinishBtn(); + initiateSpinner(); + } + + private void initiateFinishBtn() { + Button finishBtn = (Button) findViewById(R.id.finish_btn); + finishBtn.setOnClickListener(v -> { + saveConfiguration(); + finish(); + }); + } + + private void saveConfiguration() { + Intent intent = new Intent(); + intent.putExtras(mCurrentFragment.getArguments()); + setResult(Activity.RESULT_OK, intent); + } + + private void initiateSpinner() { + Spinner versioningTypeSpinner = (Spinner) findViewById(R.id.versioningTypeSpinner); + versioningTypeSpinner.setSelection(mTypes.indexOf(getIntent().getExtras().getString("type"))); + versioningTypeSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + if (position != mTypes.indexOf(getIntent().getExtras().getString("type"))) { + updateVersioningType(position); + updateFragmentView(position); + } + } + + @Override + public void onNothingSelected(AdapterView parent) { + + } + }); + } + + private void updateVersioningType(int position) { + mArguments.putString("type", mTypes.get(position)); + } + + private void updateFragmentView(int selection) { + if (mCurrentFragment != null){ + mArguments = mCurrentFragment.getArguments(); + } + + mCurrentFragment = getFragment(selection); + FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); + + //This Activtiy (VersioningDialogActivity) contains all the file versioning parameters that have been passed from the FolderActivity in the intent extras, so we simply + // pass that to the currentfragment. + mCurrentFragment.setArguments(mArguments); + transaction.replace(R.id.versioningFragmentContainer, mCurrentFragment); + transaction.commit(); + } + + private Fragment getFragment(int selection) { + Fragment fragment = null; + + switch (selection) { + case 0: + fragment = new NoVersioningFragment(); + break; + case 1: + fragment = new TrashCanVersioningFragment(); + break; + case 2: + fragment = new SimpleVersioningFragment(); + break; + case 3: + fragment = new StaggeredVersioningFragment(); + break; + case 4: + fragment = new ExternalVersioningFragment(); + break; + } + + return fragment; + } + + @Override + protected void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + outState.putBundle("arguments", mCurrentFragment.getArguments()); + } + + @Override + public void onBackPressed() { + saveConfiguration(); + super.onBackPressed(); + } +} \ No newline at end of file diff --git a/src/main/java/com/nutomic/syncthingandroid/fragments/NumberPickerFragment.java b/src/main/java/com/nutomic/syncthingandroid/fragments/NumberPickerFragment.java new file mode 100644 index 00000000..74f1bd48 --- /dev/null +++ b/src/main/java/com/nutomic/syncthingandroid/fragments/NumberPickerFragment.java @@ -0,0 +1,39 @@ +package com.nutomic.syncthingandroid.fragments; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.NumberPicker; + +import com.nutomic.syncthingandroid.R; + +/** + * Simply displays a numberpicker and allows easy access to configure it with the public functions. + */ + +public class NumberPickerFragment extends Fragment { + + private NumberPicker mNumberPicker; + + @Nullable + @Override + public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + mNumberPicker = (NumberPicker) inflater.inflate(R.layout.numberpicker_fragment, container, false); + mNumberPicker.setWrapSelectorWheel(false); + + return mNumberPicker; + } + + public void setOnValueChangedLisenter(NumberPicker.OnValueChangeListener onValueChangeListener){ + mNumberPicker.setOnValueChangedListener(onValueChangeListener); + } + + public void updateNumberPicker(int maxValue, int minValue, int currentValue){ + mNumberPicker.setMaxValue(maxValue); + mNumberPicker.setMinValue(minValue); + mNumberPicker.setValue(currentValue); + } +} diff --git a/src/main/java/com/nutomic/syncthingandroid/fragments/dialog/ExternalVersioningFragment.java b/src/main/java/com/nutomic/syncthingandroid/fragments/dialog/ExternalVersioningFragment.java new file mode 100644 index 00000000..7d51f846 --- /dev/null +++ b/src/main/java/com/nutomic/syncthingandroid/fragments/dialog/ExternalVersioningFragment.java @@ -0,0 +1,74 @@ +package com.nutomic.syncthingandroid.fragments.dialog; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import com.nutomic.syncthingandroid.R; + +/** + * Contains the configuration options for external file versioning. + */ + +public class ExternalVersioningFragment extends Fragment { + + private View mView; + + private Bundle mArguments; + + @Nullable + @Override + public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + mView = inflater.inflate(R.layout.fragment_external_versioning, container, false); + mArguments = getArguments(); + fillArguments(); + initateTextView(); + return mView; + } + + private void fillArguments() { + if (missingParameters()){ + mArguments.putString("command", ""); + } + } + + private boolean missingParameters() { + return !mArguments.containsKey("command"); + } + + private void initateTextView() { + TextView commandTextView = (TextView) mView.findViewById(R.id.commandTextView); + + commandTextView.setText(getCommand()); + commandTextView.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + + } + + @Override + public void onTextChanged(CharSequence command, int start, int before, int count) { + updateCommand(command.toString()); + } + + @Override + public void afterTextChanged(Editable s) { + + } + }); + } + + private void updateCommand(String command) { + mArguments.putString("command", command); + } + + private String getCommand() { + return mArguments.containsKey("command") ? mArguments.getString("command") : "" ; + } +} diff --git a/src/main/java/com/nutomic/syncthingandroid/fragments/dialog/KeepVersionsDialogFragment.java b/src/main/java/com/nutomic/syncthingandroid/fragments/dialog/KeepVersionsDialogFragment.java deleted file mode 100644 index 5e1971c0..00000000 --- a/src/main/java/com/nutomic/syncthingandroid/fragments/dialog/KeepVersionsDialogFragment.java +++ /dev/null @@ -1,88 +0,0 @@ -package com.nutomic.syncthingandroid.fragments.dialog; - -import android.app.Dialog; -import android.app.DialogFragment; -import android.content.DialogInterface; -import android.os.Bundle; -import android.support.annotation.NonNull; -import android.support.v7.app.AlertDialog; -import android.util.Log; -import android.widget.FrameLayout.LayoutParams; -import android.widget.NumberPicker; - -import com.nutomic.syncthingandroid.R; - -import static android.view.Gravity.CENTER; -import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; - -public class KeepVersionsDialogFragment extends DialogFragment { - - private static String KEEP_VERSION_VALUE = "KEEP_VERSION_KEY"; - - private OnValueChangeListener mOnValueChangeListener; - - private NumberPicker mNumberPickerView; - - private int mValue; - - private final DialogInterface.OnClickListener mDialogButtonListener = new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - switch (which) { - case DialogInterface.BUTTON_POSITIVE: - mValue = mNumberPickerView.getValue(); - if (mOnValueChangeListener != null) - mOnValueChangeListener.onValueChange(mValue); - break; - } - } - }; - - @NonNull - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - if (savedInstanceState != null) { - setValue(savedInstanceState.getInt(KEEP_VERSION_VALUE)); - } - - mNumberPickerView = createNumberPicker(); - return new AlertDialog.Builder(getActivity()) - .setTitle(R.string.keep_versions) - .setView(mNumberPickerView) - .setPositiveButton(android.R.string.ok, mDialogButtonListener) - .setNegativeButton(android.R.string.cancel, null) - .create(); - } - - @Override - public void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - outState.putInt(KEEP_VERSION_VALUE, mNumberPickerView.getValue()); - } - - public void setOnValueChangeListener(OnValueChangeListener onValueChangeListener) { - mOnValueChangeListener = onValueChangeListener; - } - - public void setValue(int value) { - this.mValue = value; - - if (mNumberPickerView != null) { - mNumberPickerView.setValue(value); - } - } - - private NumberPicker createNumberPicker() { - NumberPicker picker = new NumberPicker(getActivity()); - picker.setLayoutParams(new LayoutParams(WRAP_CONTENT, WRAP_CONTENT, CENTER)); - picker.setMinValue(0); - picker.setMaxValue(5); - picker.setValue(mValue); - picker.setWrapSelectorWheel(false); - return picker; - } - - public interface OnValueChangeListener { - void onValueChange(int value); - } -} diff --git a/src/main/java/com/nutomic/syncthingandroid/fragments/dialog/NoVersioningFragment.java b/src/main/java/com/nutomic/syncthingandroid/fragments/dialog/NoVersioningFragment.java new file mode 100644 index 00000000..849267bf --- /dev/null +++ b/src/main/java/com/nutomic/syncthingandroid/fragments/dialog/NoVersioningFragment.java @@ -0,0 +1,19 @@ +package com.nutomic.syncthingandroid.fragments.dialog; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import com.nutomic.syncthingandroid.R; + +public class NoVersioningFragment extends Fragment { + + @Nullable + @Override + public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + return inflater.inflate(R.layout.fragment_no_versioning, container, false); + } +} diff --git a/src/main/java/com/nutomic/syncthingandroid/fragments/dialog/SimpleVersioningFragment.java b/src/main/java/com/nutomic/syncthingandroid/fragments/dialog/SimpleVersioningFragment.java new file mode 100644 index 00000000..5d030a5b --- /dev/null +++ b/src/main/java/com/nutomic/syncthingandroid/fragments/dialog/SimpleVersioningFragment.java @@ -0,0 +1,61 @@ +package com.nutomic.syncthingandroid.fragments.dialog; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentManager; +import android.support.v4.app.FragmentTransaction; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.NumberPicker; + +import com.nutomic.syncthingandroid.R; +import com.nutomic.syncthingandroid.fragments.NumberPickerFragment; + +/** + * Contains the configuration options for simple file versioning. + */ + +public class SimpleVersioningFragment extends Fragment { + + private View mView; + + private Bundle mArguments; + + @Nullable + @Override + public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + mView = inflater.inflate(R.layout.fragment_simple_versioning, container, false); + mArguments = getArguments(); + fillArguments(); + updateNumberPicker(); + return mView; + } + + private void fillArguments() { + if (missingParameters()){ + mArguments.putString("keep", "5"); + } + } + + private boolean missingParameters() { + return !mArguments.containsKey("keep"); + } + + //a NumberPickerFragment is nested in the fragment_simple_versioning layout, the values for it are update below. + private void updateNumberPicker() { + NumberPickerFragment numberPicker = (NumberPickerFragment) getChildFragmentManager().findFragmentByTag("numberpicker_simple_versioning"); + numberPicker.updateNumberPicker(100000, 1, getKeepVersions()); + numberPicker.setOnValueChangedLisenter((picker, oldVal, newVal) -> updateKeepVersions((String.valueOf(newVal)))); + } + + private void updateKeepVersions(String newValue) { + mArguments.putString("keep", newValue); + } + + private int getKeepVersions() { + return Integer.valueOf(mArguments.getString("keep")); + } + +} diff --git a/src/main/java/com/nutomic/syncthingandroid/fragments/dialog/StaggeredVersioningFragment.java b/src/main/java/com/nutomic/syncthingandroid/fragments/dialog/StaggeredVersioningFragment.java new file mode 100644 index 00000000..76c5e334 --- /dev/null +++ b/src/main/java/com/nutomic/syncthingandroid/fragments/dialog/StaggeredVersioningFragment.java @@ -0,0 +1,97 @@ +package com.nutomic.syncthingandroid.fragments.dialog; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import com.nutomic.syncthingandroid.R; +import com.nutomic.syncthingandroid.activities.FolderPickerActivity; +import com.nutomic.syncthingandroid.fragments.NumberPickerFragment; + +import java.util.concurrent.TimeUnit; + + +/** + * Contains the configuration options for Staggered file versioning. + */ + +public class StaggeredVersioningFragment extends Fragment { + + private View mView; + + private Bundle mArguments; + + private TextView mPathView; + + @Nullable + @Override + public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + mView = inflater.inflate(R.layout.fragment_staggered_versioning, container, false); + mArguments = getArguments(); + fillArguments(); + updateNumberPicker(); + initiateVersionsPathTextView(); + return mView; + } + + private void fillArguments() { + if (missingParameters()) { + mArguments.putString("maxAge", "0"); + mArguments.putString("versionsPath", ""); + } + } + + private boolean missingParameters() { + return !mArguments.containsKey("maxAge"); + } + + //The maxAge parameter is displayed in days but stored in seconds since Syncthing needs it in seconds. + //A NumberPickerFragment is nested in the fragment_staggered_versioning layout, the values for it are update below. + private void updateNumberPicker() { + NumberPickerFragment numberPicker = (NumberPickerFragment) getChildFragmentManager().findFragmentByTag("numberpicker_staggered_versioning"); + numberPicker.updateNumberPicker(100, 0, getMaxAgeInDays()); + numberPicker.setOnValueChangedLisenter((picker, oldVal, newVal) -> updatePreference("maxAge", (String.valueOf(TimeUnit.DAYS.toSeconds(newVal))))); + } + + private void initiateVersionsPathTextView() { + mPathView = (TextView) mView.findViewById(R.id.directoryTextView); + String currentPath = getVersionsPath(); + + mPathView.setText(currentPath); + mPathView.setOnClickListener(view -> + startActivityForResult(FolderPickerActivity.createIntent(getContext(), currentPath), FolderPickerActivity.DIRECTORY_REQUEST_CODE)); + } + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == Activity.RESULT_OK && requestCode == FolderPickerActivity.DIRECTORY_REQUEST_CODE ) { + updatePath(data.getStringExtra(FolderPickerActivity.EXTRA_RESULT_DIRECTORY)); + } + } + + private void updatePath(String directory) { + mPathView.setText(directory); + updatePreference("versionsPath", directory); + } + + private String getVersionsPath() { + return mArguments.getString("versionsPath"); + } + + private void updatePreference(String key, String newValue) { + getArguments().putString(key, newValue); + } + + private int getMaxAgeInDays() { + return (int) TimeUnit.SECONDS.toDays(Long.valueOf(mArguments.getString("maxAge"))); + } +} diff --git a/src/main/java/com/nutomic/syncthingandroid/fragments/dialog/TrashCanVersioningFragment.java b/src/main/java/com/nutomic/syncthingandroid/fragments/dialog/TrashCanVersioningFragment.java new file mode 100644 index 00000000..57b31cd3 --- /dev/null +++ b/src/main/java/com/nutomic/syncthingandroid/fragments/dialog/TrashCanVersioningFragment.java @@ -0,0 +1,57 @@ +package com.nutomic.syncthingandroid.fragments.dialog; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import com.nutomic.syncthingandroid.R; +import com.nutomic.syncthingandroid.fragments.NumberPickerFragment; + +/** + * Contains the configuration options for trashcan file versioning. + */ + +public class TrashCanVersioningFragment extends Fragment { + + private View mView; + + private Bundle mArguments; + + @Nullable + @Override + public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + mView = inflater.inflate(R.layout.fragment_trashcan_versioning, container, false); + mArguments = getArguments(); + fillArguments(); + updateNumberPicker(); + return mView; + } + + private void fillArguments() { + if (missingParameters()) { + mArguments.putString("cleanoutDays", "0"); + } + } + + private boolean missingParameters() { + return !mArguments.containsKey("cleanoutDays"); + } + + //a NumberPickerFragment is nested in the fragment_trashcan_versioning layout, the values for it are update below. + private void updateNumberPicker() { + NumberPickerFragment numberPicker = (NumberPickerFragment) getChildFragmentManager().findFragmentByTag("numberpicker_trashcan_versioning"); + numberPicker.updateNumberPicker(100, 0, getCleanoutDays()); + numberPicker.setOnValueChangedLisenter((picker, oldVal, newVal) -> updateCleanoutDays((String.valueOf(newVal)))); + } + + private int getCleanoutDays() { + return Integer.valueOf(mArguments.getString("cleanoutDays")); + } + + private void updateCleanoutDays(String newValue) { + mArguments.putString("cleanoutDays", newValue); + } +} diff --git a/src/main/res/layout/activity_versioning_dialog.xml b/src/main/res/layout/activity_versioning_dialog.xml new file mode 100644 index 00000000..ce32308d --- /dev/null +++ b/src/main/res/layout/activity_versioning_dialog.xml @@ -0,0 +1,11 @@ + + + + + + diff --git a/src/main/res/layout/fragment_directory_text_view.xml b/src/main/res/layout/fragment_directory_text_view.xml new file mode 100644 index 00000000..0d7d4075 --- /dev/null +++ b/src/main/res/layout/fragment_directory_text_view.xml @@ -0,0 +1,10 @@ + + diff --git a/src/main/res/layout/fragment_external_versioning.xml b/src/main/res/layout/fragment_external_versioning.xml new file mode 100644 index 00000000..e99ee5f2 --- /dev/null +++ b/src/main/res/layout/fragment_external_versioning.xml @@ -0,0 +1,30 @@ + + + + + + + + + \ No newline at end of file diff --git a/src/main/res/layout/fragment_folder.xml b/src/main/res/layout/fragment_folder.xml index 882c13d7..c51140c1 100644 --- a/src/main/res/layout/fragment_folder.xml +++ b/src/main/res/layout/fragment_folder.xml @@ -45,14 +45,14 @@ android:inputType="textCapWords" /> + android:hint="@string/directory"/> + + android:orientation="vertical" + android:gravity="center_vertical"> + android:text="@string/file_versioning" /> + + + diff --git a/src/main/res/layout/fragment_no_versioning.xml b/src/main/res/layout/fragment_no_versioning.xml new file mode 100644 index 00000000..b1885bb1 --- /dev/null +++ b/src/main/res/layout/fragment_no_versioning.xml @@ -0,0 +1,12 @@ + + + + + \ No newline at end of file diff --git a/src/main/res/layout/fragment_simple_versioning.xml b/src/main/res/layout/fragment_simple_versioning.xml new file mode 100644 index 00000000..2a11f57b --- /dev/null +++ b/src/main/res/layout/fragment_simple_versioning.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/res/layout/fragment_staggered_versioning.xml b/src/main/res/layout/fragment_staggered_versioning.xml new file mode 100644 index 00000000..39c484d9 --- /dev/null +++ b/src/main/res/layout/fragment_staggered_versioning.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/res/layout/fragment_trashcan_versioning.xml b/src/main/res/layout/fragment_trashcan_versioning.xml new file mode 100644 index 00000000..34998638 --- /dev/null +++ b/src/main/res/layout/fragment_trashcan_versioning.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/res/layout/fragment_versioning_dialog.xml b/src/main/res/layout/fragment_versioning_dialog.xml new file mode 100644 index 00000000..879cb81e --- /dev/null +++ b/src/main/res/layout/fragment_versioning_dialog.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + +