Add New file creation menu option
This commit is contained in:
parent
6f844994da
commit
f82330a92f
12 changed files with 214 additions and 49 deletions
|
@ -49,6 +49,11 @@ android {
|
|||
dexOptions {
|
||||
jumboMode true
|
||||
}
|
||||
testOptions {
|
||||
unitTests {
|
||||
includeAndroidResources = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ext {
|
||||
|
@ -72,6 +77,7 @@ dependencies {
|
|||
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
|
||||
compile 'io.reactivex.rxjava2:rxjava:2.1.0'
|
||||
testCompile 'junit:junit:4.12'
|
||||
testImplementation "org.robolectric:robolectric:3.6.1"
|
||||
androidTestCompile 'com.android.support.test.espresso:espresso-core:3.0.1'
|
||||
androidTestCompile 'com.android.support.test:runner:1.0.1'
|
||||
androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.3'
|
||||
|
|
|
@ -7,9 +7,11 @@ import android.preference.PreferenceManager;
|
|||
|
||||
import com.wbrawner.simplemarkdown.view.activity.SettingsActivity;
|
||||
|
||||
/**
|
||||
* Created by billy on 1/15/2018.
|
||||
*/
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.util.Locale;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class Utils {
|
||||
|
||||
|
@ -22,10 +24,53 @@ public class Utils {
|
|||
);
|
||||
}
|
||||
|
||||
public static String getDefaultFileName(Context context) {
|
||||
File docsDir = new File(Utils.getDocsPath(context));
|
||||
Pattern defaultFilePattern = Pattern.compile("Untitled(-([0-9]+))*.md");
|
||||
File[] files = docsDir.listFiles();
|
||||
String defaultFileName = "Untitled.md";
|
||||
if (files != null && files.length > 0) {
|
||||
int count = 0;
|
||||
for (File file : files) {
|
||||
if (!file.isFile()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Matcher fileMatcher = defaultFilePattern.matcher(file.getName());
|
||||
if (!fileMatcher.find()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (file.getName().equals("Untitled.md")) {
|
||||
if (count == 0) {
|
||||
count = 1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
String defaultFileCount = fileMatcher.group(2);
|
||||
int fileCount = Integer.parseInt(defaultFileCount);
|
||||
if (fileCount >= count) {
|
||||
count = fileCount + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (count > 0) {
|
||||
defaultFileName = String.format(
|
||||
Locale.ENGLISH,
|
||||
"Untitled-%d.md",
|
||||
count
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return defaultFileName;
|
||||
}
|
||||
|
||||
public static boolean isAutosaveEnabled(Context context) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
return prefs.getBoolean(
|
||||
"autosave",
|
||||
SettingsActivity.KEY_AUTOSAVE,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
|
|
@ -36,6 +36,9 @@ public class MarkdownFile {
|
|||
|
||||
public MarkdownFile(String name, String path, String content) {
|
||||
this.name = name;
|
||||
if (path == null || path.isEmpty()) {
|
||||
path = defaultRootDir;
|
||||
}
|
||||
this.path = path;
|
||||
this.content = content;
|
||||
}
|
||||
|
@ -125,6 +128,7 @@ public class MarkdownFile {
|
|||
try {
|
||||
this.name = markdownFile.getName();
|
||||
this.path = markdownFile.getParentFile().getAbsolutePath();
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String line;
|
||||
reader = new BufferedReader(new FileReader(markdownFile));
|
||||
|
@ -158,6 +162,10 @@ public class MarkdownFile {
|
|||
|
||||
public int save(String path) {
|
||||
int code;
|
||||
if (path == null) {
|
||||
path = this.getFullPath();
|
||||
}
|
||||
|
||||
File markdownFile = new File(path);
|
||||
if (!markdownFile.exists()) {
|
||||
try {
|
||||
|
@ -192,10 +200,4 @@ public class MarkdownFile {
|
|||
this.path = markdownFile.getParentFile().getAbsolutePath();
|
||||
return code;
|
||||
}
|
||||
|
||||
public int save() {
|
||||
if (this.name.isEmpty())
|
||||
return PARAMETERS_MISSING;
|
||||
return save(this.getFullPath());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,10 +9,6 @@ import com.wbrawner.simplemarkdown.view.MarkdownPreviewView;
|
|||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* Created by billy on 8/22/17.
|
||||
*/
|
||||
|
||||
public interface MarkdownPresenter {
|
||||
File getFile();
|
||||
void loadMarkdown();
|
||||
|
@ -21,10 +17,10 @@ public interface MarkdownPresenter {
|
|||
void loadMarkdown(File file);
|
||||
void loadFromUri(Context context, Uri fileUri);
|
||||
void loadTempMarkdown(InputStream in, OnTempFileLoadedListener listener);
|
||||
void newFile(String path);
|
||||
void setEditView(MarkdownEditView editView);
|
||||
void setPreviewView(MarkdownPreviewView previewView);
|
||||
void saveMarkdown();
|
||||
void saveMarkdown(String filePath);
|
||||
void saveMarkdown(MarkdownSavedListener listener, String filePath);
|
||||
void onMarkdownEdited();
|
||||
void onMarkdownEdited(String markdown);
|
||||
String getFileName();
|
||||
|
@ -35,8 +31,12 @@ public interface MarkdownPresenter {
|
|||
String getMarkdown();
|
||||
void setMarkdown(String markdown);
|
||||
|
||||
public abstract class OnTempFileLoadedListener {
|
||||
abstract class OnTempFileLoadedListener {
|
||||
public abstract void onSuccess(String markdown);
|
||||
public abstract void onError(int code);
|
||||
}
|
||||
|
||||
interface MarkdownSavedListener {
|
||||
void saveComplete();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,6 +63,7 @@ public class MarkdownPresenterImpl implements MarkdownPresenter {
|
|||
int result = this.file.load(file);
|
||||
if (editView != null) {
|
||||
if (result == MarkdownFile.SUCCESS) {
|
||||
editView.setTitle(this.file.getName());
|
||||
editView.setMarkdown(getMarkdown());
|
||||
onMarkdownEdited();
|
||||
} else {
|
||||
|
@ -104,6 +105,16 @@ public class MarkdownPresenterImpl implements MarkdownPresenter {
|
|||
fileHandler.post(fileLoader);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void newFile(String newName) {
|
||||
if (this.editView != null) {
|
||||
this.file.setContent(this.editView.getMarkdown());
|
||||
this.editView.setTitle(newName);
|
||||
this.editView.setMarkdown("");
|
||||
}
|
||||
this.file = new MarkdownFile(newName, "", "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEditView(MarkdownEditView editView) {
|
||||
this.editView = editView;
|
||||
|
@ -115,10 +126,15 @@ public class MarkdownPresenterImpl implements MarkdownPresenter {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void saveMarkdown(String filePath) {
|
||||
public void saveMarkdown(MarkdownSavedListener listener, String filePath) {
|
||||
Runnable fileSaver = () -> {
|
||||
int code;
|
||||
code = file.save(filePath);
|
||||
|
||||
if (listener != null) {
|
||||
listener.saveComplete();
|
||||
}
|
||||
|
||||
if (editView != null) {
|
||||
if (code == MarkdownFile.SUCCESS) {
|
||||
editView.showFileSavedMessage();
|
||||
|
@ -130,11 +146,6 @@ public class MarkdownPresenterImpl implements MarkdownPresenter {
|
|||
fileHandler.post(fileSaver);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveMarkdown() {
|
||||
file.save();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMarkdownEdited(String markdown) {
|
||||
setMarkdown(markdown);
|
||||
|
|
|
@ -1,13 +1,9 @@
|
|||
package com.wbrawner.simplemarkdown.view;
|
||||
|
||||
/**
|
||||
* Created by billy on 8/22/17.
|
||||
*/
|
||||
|
||||
public interface MarkdownEditView {
|
||||
String getMarkdown();
|
||||
void setMarkdown(String markdown);
|
||||
|
||||
void setTitle(String title);
|
||||
void showFileSavedMessage();
|
||||
void showFileSavedError(int code);
|
||||
void showFileLoadedMessage();
|
||||
|
|
|
@ -2,24 +2,18 @@ package com.wbrawner.simplemarkdown.view.activity;
|
|||
|
||||
import android.Manifest;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Build;
|
||||
import android.os.Environment;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.design.widget.TabLayout;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.os.Bundle;
|
||||
import android.text.InputType;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.wbrawner.simplemarkdown.MarkdownApplication;
|
||||
|
@ -56,6 +50,7 @@ public class MainActivity extends AppCompatActivity
|
|||
TabLayout tabLayout;
|
||||
|
||||
private static final String TAG = MainActivity.class.getSimpleName();
|
||||
private NewFileHandler newFileHandler;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
|
@ -74,13 +69,14 @@ public class MainActivity extends AppCompatActivity
|
|||
== Configuration.ORIENTATION_LANDSCAPE) {
|
||||
tabLayout.setVisibility(View.GONE);
|
||||
}
|
||||
newFileHandler = new NewFileHandler();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
if (Utils.isAutosaveEnabled(this)) {
|
||||
presenter.saveMarkdown();
|
||||
presenter.saveMarkdown(null, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -142,6 +138,7 @@ public class MainActivity extends AppCompatActivity
|
|||
}
|
||||
break;
|
||||
case R.id.action_new:
|
||||
presenter.saveMarkdown(newFileHandler, null);
|
||||
break;
|
||||
case R.id.action_help:
|
||||
showInfoActivity(R.id.action_help);
|
||||
|
@ -262,7 +259,7 @@ public class MainActivity extends AppCompatActivity
|
|||
break;
|
||||
}
|
||||
String path = data.getStringExtra(EXTRA_FILE_PATH);
|
||||
presenter.saveMarkdown(path);
|
||||
presenter.saveMarkdown(null, path);
|
||||
setTitle(presenter.getFileName());
|
||||
break;
|
||||
}
|
||||
|
@ -293,4 +290,12 @@ public class MainActivity extends AppCompatActivity
|
|||
super.onResume();
|
||||
setTitle(presenter.getFileName());
|
||||
}
|
||||
|
||||
private class NewFileHandler implements MarkdownPresenter.MarkdownSavedListener {
|
||||
@Override
|
||||
public void saveComplete() {
|
||||
String newFile = Utils.getDefaultFileName(MainActivity.this);
|
||||
presenter.newFile(newFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import com.wbrawner.simplemarkdown.R;
|
|||
|
||||
public class SettingsActivity extends AppCompatActivity {
|
||||
|
||||
public static final String KEY_AUTOSAVE = "autosave";
|
||||
public static final String KEY_DOCS_PATH = "defaultRootDir";
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,27 +1,16 @@
|
|||
package com.wbrawner.simplemarkdown.view.activity;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.provider.OpenableColumns;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.wbrawner.simplemarkdown.MarkdownApplication;
|
||||
import com.wbrawner.simplemarkdown.R;
|
||||
import com.wbrawner.simplemarkdown.Utils;
|
||||
import com.wbrawner.simplemarkdown.presentation.MarkdownPresenter;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* Created by billy on 8/23/17.
|
||||
*/
|
||||
|
||||
public class SplashActivity extends AppCompatActivity {
|
||||
|
||||
@Inject
|
||||
|
@ -31,10 +20,16 @@ public class SplashActivity extends AppCompatActivity {
|
|||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
((MarkdownApplication) getApplication()).getComponent().inject(this);
|
||||
|
||||
String defaultName = Utils.getDefaultFileName(this);
|
||||
|
||||
Intent intent = getIntent();
|
||||
if (intent != null && intent.getData() != null) {
|
||||
presenter.loadFromUri(getApplicationContext(), intent.getData());
|
||||
} else {
|
||||
presenter.setFileName(defaultName);
|
||||
}
|
||||
|
||||
startActivity(new Intent(this, MainActivity.class));
|
||||
finish();
|
||||
}
|
||||
|
|
|
@ -87,6 +87,11 @@ public class EditFragment extends Fragment implements MarkdownEditView {
|
|||
return markdownEditor.getText().toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTitle(String title) {
|
||||
getActivity().setTitle(title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showFileSavedMessage() {
|
||||
String location = Utils.getDocsPath(getActivity()) + presenter.getFileName();
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/action_new"
|
||||
android:visible="false"
|
||||
android:orderInCategory="150"
|
||||
android:title="@string/action_new"
|
||||
app:showAsAction="never" />
|
||||
|
|
100
app/src/test/java/com/wbrawner/simplemarkdown/UtilsTest.java
Normal file
100
app/src/test/java/com/wbrawner/simplemarkdown/UtilsTest.java
Normal file
|
@ -0,0 +1,100 @@
|
|||
package com.wbrawner.simplemarkdown;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
|
||||
import com.wbrawner.simplemarkdown.view.activity.SettingsActivity;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@SuppressWarnings("ResultOfMethodCallIgnored")
|
||||
public class UtilsTest {
|
||||
private Context context;
|
||||
private SharedPreferences sharedPreferences;
|
||||
private String rootDir;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
context = RuntimeEnvironment.application.getApplicationContext();
|
||||
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
sharedPreferences.edit().clear().apply();
|
||||
rootDir = System.getProperty("java.io.tmpdir") + "/SimpleMarkdown";
|
||||
new File(rootDir).mkdir();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
rmdir(new File(rootDir));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getDocsPath() throws Exception {
|
||||
sharedPreferences.edit().putString(SettingsActivity.KEY_DOCS_PATH, rootDir).apply();
|
||||
assertEquals(rootDir, Utils.getDocsPath(context));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getDefaultFileName() throws Exception {
|
||||
sharedPreferences.edit().putString(SettingsActivity.KEY_DOCS_PATH, rootDir).apply();
|
||||
|
||||
new File(rootDir, "dummy.md").createNewFile();
|
||||
new File(rootDir, "dummy1.md").createNewFile();
|
||||
new File(rootDir, "Untitled-a.md").createNewFile();
|
||||
|
||||
String firstDefaultName = Utils.getDefaultFileName(context);
|
||||
assertEquals("Untitled.md", firstDefaultName);
|
||||
File firstFile = new File(rootDir, firstDefaultName);
|
||||
firstFile.createNewFile();
|
||||
|
||||
String secondDefaultName = Utils.getDefaultFileName(context);
|
||||
assertEquals("Untitled-1.md", secondDefaultName);
|
||||
File secondFile = new File(rootDir, secondDefaultName);
|
||||
secondFile.createNewFile();
|
||||
|
||||
String thirdDefaultName = Utils.getDefaultFileName(context);
|
||||
assertEquals("Untitled-2.md", thirdDefaultName);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getDefaultFileNameDoubleDigitTest() throws IOException {
|
||||
sharedPreferences.edit().putString(SettingsActivity.KEY_DOCS_PATH, rootDir).apply();
|
||||
|
||||
for (int i = 0; i < 11; i++) {
|
||||
new File(rootDir, "Untitled-" + i + ".md").createNewFile();
|
||||
}
|
||||
assertTrue(new File(rootDir, "Untitled-10.md").exists());
|
||||
String defaultName = Utils.getDefaultFileName(context);
|
||||
assertEquals("Untitled-11.md", defaultName);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isAutosaveEnabled() throws Exception {
|
||||
assertTrue(Utils.isAutosaveEnabled(context));
|
||||
sharedPreferences.edit().putBoolean(SettingsActivity.KEY_AUTOSAVE, false).apply();
|
||||
assertFalse(Utils.isAutosaveEnabled(context));
|
||||
}
|
||||
|
||||
private void rmdir(File dir) {
|
||||
for (File file : dir.listFiles()) {
|
||||
if (file.isFile()) {
|
||||
file.delete();
|
||||
} else {
|
||||
rmdir(file);
|
||||
}
|
||||
}
|
||||
|
||||
dir.delete();
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue