Back to project page Text-Edit-for-Android.
The source code is released under:
GNU General Public License
If you think the Android project Text-Edit-for-Android listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
package org.paulmach.textedit; /*from w ww . ja v a 2 s . c o m*/ import java.io.BufferedWriter; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; import java.util.List; import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; import android.app.SearchManager; import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.content.DialogInterface.OnCancelListener; import android.graphics.Typeface; import android.net.Uri; import android.os.Bundle; import android.os.ParcelFileDescriptor; import android.preference.PreferenceManager; import android.provider.SearchRecentSuggestions; import android.text.Editable; import android.text.TextWatcher; import android.text.util.Linkify; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.Window; import android.widget.AdapterView; import android.widget.AutoCompleteTextView; import android.widget.EditText; import android.widget.ListView; import android.widget.ScrollView; import android.widget.TextView; import android.widget.Toast; import android.widget.AdapterView.OnItemClickListener; public class pmTextEdit extends Activity { // menu option ids private final static int MENU_SAVE_ID = Menu.FIRST; private final static int MENU_SAVEAS_ID = Menu.FIRST + 1; private final static int MENU_OPEN_ID = Menu.FIRST + 2; private final static int MENU_OPENRECENT_ID = Menu.FIRST + 3; private final static int MENU_OPTIONS_ID = Menu.FIRST + 4; private final static int MENU_NEW_ID = Menu.FIRST + 5; private final static int MENU_EMAIL = Menu.FIRST + 6; private final static int MENU_SEARCH = Menu.FIRST + 7; private final static int MENU_ATTACHMENT = Menu.FIRST + 8; // dialog ids private final static int DIALOG_SAVE_FILE = 1; private final static int DIALOG_OPEN_FILE = 2; private final static int DIALOG_SHOULD_SAVE = 3; private final static int DIALOG_OVERWRITE = 4; private final static int DIALOG_SAVE_ERROR = 5; private final static int DIALOG_SAVE_ERROR_PERMISSIONS = 6; private final static int DIALOG_SAVE_ERROR_SDCARD = 7; private final static int DIALOG_READ_ERROR = 8; private final static int DIALOG_NOTFOUND_ERROR = 9; private final static int DIALOG_SHOULD_SAVE_INTENT = 13; private final static int DIALOG_MODIFIED = 14; private final static int DIALOG_SAVE_FILE_AUTOCOMPLETE = 10; private final static int DIALOG_OPEN_FILE_AUTOCOMPLETE = 11; private final static int DIALOG_RECENT_FILE_DIALOG = 12; // file format ids private final static int FILEFORMAT_NL = 1; private final static int FILEFORMAT_CR = 2; private final static int FILEFORMAT_CRNL = 3; // other activities private final static int REQUEST_CODE_PREFERENCES = 1; private final static int REQUEST_FILE_BROWSER_OPEN = 2; private final static int REQUEST_FILE_BROWSER_SAVE = 3; // some global variables protected static EditText text = null; protected static TextView title = null; protected CharSequence filename = ""; protected long lastModified = 0; protected boolean untitled = true; static private List<String> items = null; static private List<String> recentItems = null; protected EditText saveDialog_fne = null; protected EditText openDialog_fne = null; protected AlertDialog openRecentDialog; protected ListView openRecentListView; protected static FileViewArrayAdapter recentFilesAdapter; private boolean backFromFileBrowser = false; private CharSequence fileBrowserReturnFile; // some state variables private boolean autoComplete = true; private boolean creatingFile = false; private boolean savingFile = false; private boolean openingFile = false; private boolean openingError = false; private boolean openingRecent = false; private boolean sendingAttachment = false; private static CharSequence temp_filename = ""; private boolean fromIntent = false; private boolean openingIntent = false; private Intent newIntent = null; private boolean fromSearch = false; private String queryString = ""; private CharSequence errorFname = "File"; private boolean errorSaving = false; private int fileformat; /**************************************************************** * onCreate() */ public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //Hide the title bar try { requestWindowFeature(Window.FEATURE_NO_TITLE); } catch (Exception e) {} updateOptions(); Intent intent = getIntent(); newIntent(intent); } // end onCreate() /**************************************************************** * onNewIntent() */ public void onNewIntent(Intent intent) { super.onNewIntent(intent); newIntent(intent); } /**************************************************************** * newIntent() */ public void newIntent(Intent intent) { setIntent(intent); // search action if (Intent.ACTION_SEARCH.equals(intent.getAction())) { String query = intent.getStringExtra(SearchManager.QUERY); SearchRecentSuggestions suggestions = new SearchRecentSuggestions(this, SearchSuggestions.AUTHORITY, SearchSuggestions.MODE); suggestions.saveRecentQuery(query, null); int number = intent.getIntExtra("number", 0); number++; intent.putExtra("number", number); if (number == 1) { fromSearch = true; queryString = query; } } else { // opening something action Uri mUri = intent.getData(); if (mUri != null) { myResume(); // this is so we know if this intent was already displayed int number = intent.getIntExtra("number", 0); number++; intent.putExtra("number", number); // when you revist the app, from rotate or otherwise, the intent is still // with the app. So we don't want to reopen every time // I don't know if this is the best way to do this or not, but it works for me. if (!mUri.getPath().equals(filename) && number <= 1) { // set stuff up fromIntent = true; // figure out what to do if (!mUri.getPath().equals(filename) && isTextChanged()) { openingIntent = true; newIntent = intent; showDialog(DIALOG_SHOULD_SAVE_INTENT); } else if (!mUri.getPath().equals(filename)) { openFile(mUri); } } } } } /**************************************************************** * onSaveInstanceState() */ public void onSaveInstanceState(Bundle savedInstanceState) { // Save UI state changes to the savedInstanceState. // This bundle will be passed to onCreate if the process is // killed and restarted. savedInstanceState.putBoolean("creatingFile", creatingFile); savedInstanceState.putBoolean("savingFile", savingFile); savedInstanceState.putBoolean("openingFile", openingFile); savedInstanceState.putBoolean("openingError", openingError); savedInstanceState.putBoolean("openingRecent", openingRecent); savedInstanceState.putBoolean("openingIntent", openingIntent); savedInstanceState.putBoolean("sendingAttachment", sendingAttachment); savedInstanceState.putString("temp_filename", temp_filename.toString()); super.onSaveInstanceState(savedInstanceState); } // end onSaveInstanceState() /**************************************************************** * onRestoreInstanceState() */ public void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); // Restore UI state from the savedInstanceState. // This bundle has also been passed to onCreate. creatingFile = savedInstanceState.getBoolean("creatingFile"); savingFile = savedInstanceState.getBoolean("savingFile"); openingFile = savedInstanceState.getBoolean("openingFile"); openingError = savedInstanceState.getBoolean("openingError"); openingRecent = savedInstanceState.getBoolean("openingRecent"); openingIntent = savedInstanceState.getBoolean("openingIntent"); sendingAttachment = savedInstanceState.getBoolean("sendingAttachment"); temp_filename = savedInstanceState.getString("temp_filename"); } // onRestoreInstanceState() /**************************************************************** * createNew() * create a new file */ public void createNew() { // set the new context setContentView(R.layout.edit); // update options done below text = (EditText) findViewById(R.id.note); title = (TextView) findViewById(R.id.notetitle); text.setText(""); title.setText(R.string.newFileName); // clear the saved text SharedPreferences.Editor editor = getPreferences(MODE_PRIVATE).edit(); if (editor != null) { editor.putInt("mode", 1); editor.putString("text", ""); editor.putInt("text-quotes", 0); editor.putString("fntext", title.getText().toString()); editor.putInt("fntext-quotes", countQuotes(title.getText().toString())); editor.putString("filename", ""); editor.putInt("filename-quotes", 0); editor.putInt("selection-start", -1); editor.putInt("selection-end", -1); editor.commit(); } fileformat = FILEFORMAT_NL; filename = ""; lastModified = 0; untitled = true; creatingFile = false; updateOptions(); text.requestFocus(); } // end createNew(); /**************************************************************** * openFile(Uri mUri) * opens a file, duh */ public void openFile(Uri mUri) { File ft = new File(mUri.getPath()); if (ft.isFile()) { openFile(mUri.getPath()); return; } // figure out file name int count = 0; SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getBaseContext()); String location = sharedPref.getString("defaultdir", "/sdcard/"); File f = new File(location + "/attachment"); while (f.isFile()) { count++; f = new File(location + "/attachment" + count); } // now read in the file try { ParcelFileDescriptor pfd = getContentResolver().openFileDescriptor(mUri, "r"); FileReader fis = new FileReader(pfd.getFileDescriptor()); char[] buffer; buffer = new char[1100]; // made it bigger just in case StringBuffer result = new StringBuffer(); int read = 0; do { read = fis.read(buffer); if (read >= 0) { result.append(buffer, 0, read); } } while (read >= 0); openFile((CharSequence) f.toString(), result); removeRecentFile((CharSequence) f.toString()); // indicate it hasn't been saved // put a little star in the title if the file is changed if (!isTextChanged()) { CharSequence temp = title.getText(); title.setText("* " + temp); } } catch (Exception e) { // error reading file errorFname = "attachment"; openingError = true; showDialog(DIALOG_READ_ERROR); } } /**************************************************************** * openFile(CharSequence fname) * opens a file, duh */ public void openFile(CharSequence fname) { openingFile = false; StringBuffer result = new StringBuffer(); try { // open file FileReader f = new FileReader(fname.toString()); File file = new File(fname.toString()); if (f == null) { throw(new FileNotFoundException()); } if (file.isDirectory()) { throw(new IOException()); } // if the file has nothing in it there will be an exception here // that actually isn't a problem if (file.length() != 0 && !file.isDirectory()) { // using just FileReader now. Works better with weird file encoding // Thanks to Ondrej Bojar <obo@cuni.cz> for finding the bug. // read in the file // do it this way because we need that newline at // the end of the file if there is one char[] buffer; buffer = new char[1100]; // made it bigger just in case int read = 0; do { read = f.read(buffer, 0, 1000); if (read >= 0) { result.append(buffer, 0, read); } } while (read >= 0); } } catch (FileNotFoundException e) { // file not found errorFname = fname; openingError = true; showDialog(DIALOG_NOTFOUND_ERROR); } catch (IOException e) { // error reading file errorFname = fname; openingError = true; showDialog(DIALOG_READ_ERROR); } catch (Exception e) { errorFname = fname; openingError = true; showDialog(DIALOG_READ_ERROR); } // now figure out the file format, nl, cr, crnl if (!openingError) { openFile(fname, result); } errorSaving = false; if (text != null) text.requestFocus(); } // end openFile(CharSequence fname) /**************************************************************** * openFile(CharSequence fname, StringBuffer result) * opens a file, duh */ public void openFile(CharSequence fname, StringBuffer result) { try { // have to do this first because it resets fileformat createNew(); // to clear everything out String newText = result.toString(); if (newText.indexOf("\r\n", 0) != -1) { fileformat = FILEFORMAT_CRNL; newText = newText.replace("\r", ""); } else if(newText.indexOf("\r", 0) != -1) { fileformat = FILEFORMAT_CR; newText = newText.replace("\r", "\n"); } else { fileformat = FILEFORMAT_NL; } // Okay, now we can set everything up text.setText(newText); title.setText(fname); File f = new File(fname.toString()); lastModified = f.lastModified(); filename = fname; untitled = false; addRecentFile(fname); openingRecent = false; // this is just incase we get an error } catch (Exception e) { errorFname = fname; openingError = true; showDialog(DIALOG_READ_ERROR); } openingIntent = false; temp_filename = ""; } // end openFile(CharSequence fname, StringBuffer result) /**************************************************************** * saveNote() * What to do when saving note */ public void saveNote(CharSequence fname) { errorSaving = false; // actually save the file here try { File f = new File(fname.toString()); if ( (f.exists() && !f.canWrite()) || (!f.exists() && !f.getParentFile().canWrite())) { creatingFile = false; openingFile = false; errorSaving = true; if (fname.toString().indexOf("/sdcard/") == 0) showDialog(DIALOG_SAVE_ERROR_SDCARD); else showDialog(DIALOG_SAVE_ERROR_PERMISSIONS); text.requestFocus(); f = null; return; } f = null; // hopefully this gets garbage collected // Create file FileWriter fstream = new FileWriter(fname.toString()); BufferedWriter out = new BufferedWriter(fstream); if (fileformat == FILEFORMAT_CR) { out.write(text.getText().toString().replace("\n", "\r")); } else if (fileformat == FILEFORMAT_CRNL) { out.write(text.getText().toString().replace("\n", "\r\n")); } else { out.write(text.getText().toString()); } out.close(); // give a nice little message Toast.makeText(this, R.string.onSaveMessage, Toast.LENGTH_SHORT).show(); // the filename is the new title title.setText(fname); filename = fname; untitled = false; lastModified = (new File(filename.toString())).lastModified(); temp_filename = ""; addRecentFile(fname); } catch (Exception e) { //Catch exception if any creatingFile = false; openingFile = false; if (fname.toString().indexOf("/sdcard/") == 0) showDialog(DIALOG_SAVE_ERROR_SDCARD); else showDialog(DIALOG_SAVE_ERROR); errorSaving = true; } text.requestFocus(); } // end saveNote() /**************************************************************** * updateOptions() * start options app */ protected void updateOptions() { boolean value; // load the preferences SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this); autoComplete = sharedPref.getBoolean("autocomplete", false); /******************************** * Auto correct and auto case */ boolean autocorrect = sharedPref.getBoolean("autocorrect", false); boolean autocase = sharedPref.getBoolean("autocase", false); if (autocorrect && autocase) { setContentView(R.layout.edit_autotext_autocase); } else if (autocorrect) { setContentView(R.layout.edit_autotext); } else if (autocase) { setContentView(R.layout.edit_autocase); } else { setContentView(R.layout.edit); } text = (EditText) findViewById(R.id.note); title = (TextView) findViewById(R.id.notetitle); text.addTextChangedListener(new TextWatcher() { public void onTextChanged(CharSequence one, int a, int b, int c) { // put a little star in the title if the file is changed if (!isTextChanged()) { CharSequence temp = title.getText(); title.setText("* " + temp); } } // complete the interface public void afterTextChanged(Editable s) { } public void beforeTextChanged(CharSequence s, int start, int count, int after) { } }); /******************************** * links clickable */ boolean linksclickable = sharedPref.getBoolean("linksclickable", false); if (linksclickable) text.setAutoLinkMask(Linkify.ALL); else text.setAutoLinkMask(0); /******************************** * show/hide filename */ value = sharedPref.getBoolean("hidefilename", false); if (value) title.setVisibility(View.GONE); else title.setVisibility(View.VISIBLE); /******************************** * line wrap */ value = sharedPref.getBoolean("linewrap", true); text.setHorizontallyScrolling(!value); // setup the scroll view correctly ScrollView scroll = (ScrollView) findViewById(R.id.scroll); if (scroll != null) { scroll.setFillViewport(true); scroll.setHorizontalScrollBarEnabled(!value); } /******************************** * font face */ String font = sharedPref.getString("font", "Monospace"); if (font.equals("Serif")) text.setTypeface(Typeface.SERIF); else if (font.equals("Sans Serif")) text.setTypeface(Typeface.SANS_SERIF); else text.setTypeface(Typeface.MONOSPACE); /******************************** * font size */ String fontsize = sharedPref.getString("fontsize", "Medium"); if (fontsize.equals("Extra Small")) text.setTextSize(12.0f); else if (fontsize.equals("Small")) text.setTextSize(16.0f); else if (fontsize.equals("Medium")) text.setTextSize(20.0f); else if (fontsize.equals("Large")) text.setTextSize(24.0f); else if (fontsize.equals("Huge")) text.setTextSize(28.0f); else text.setTextSize(20.0f); /******************************** * Colors */ int bgcolor = sharedPref.getInt("bgcolor", 0xFF000000); text.setBackgroundColor(bgcolor); int fontcolor = sharedPref.getInt("fontcolor", 0xFFCCCCCC); text.setTextColor(fontcolor); title.setTextColor(bgcolor); title.setBackgroundColor(fontcolor); text.setLinksClickable(true); } // updateOptions() /**************************************************************** * onActivityResult() * results of a launched activity */ protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); // preferences returned to update the editor if (requestCode == REQUEST_CODE_PREFERENCES) { updateOptions(); } else if (requestCode == REQUEST_FILE_BROWSER_OPEN && data != null) { fileBrowserReturnFile = data.getAction(); backFromFileBrowser = true; if (autoComplete) showDialog(DIALOG_OPEN_FILE_AUTOCOMPLETE); else showDialog(DIALOG_OPEN_FILE); } else if (requestCode == REQUEST_FILE_BROWSER_SAVE && data != null) { fileBrowserReturnFile = data.getAction(); backFromFileBrowser = true; if (autoComplete) showDialog(DIALOG_SAVE_FILE_AUTOCOMPLETE); else showDialog(DIALOG_SAVE_FILE); } } // end onActivityResult() /**************************************************************** * onPause() * What happens when you pause the app */ protected void onPause() { super.onPause(); // save the preferences SharedPreferences.Editor editor = getPreferences(MODE_PRIVATE).edit(); if (editor != null && text != null) { String t; t = text.getText().toString(); editor.putString("text", t); editor.putInt("text-quotes", countQuotes(t)); t = title.getText().toString(); editor.putString("fntext", t); editor.putInt("fntext-quotes", countQuotes(t)); if (filename != null) t = filename.toString(); else t = ""; editor.putString("filename", t); editor.putLong("lastModified", lastModified); editor.putInt("filename-quotes", countQuotes(t)); editor.putInt("selection-start", text.getSelectionStart()); editor.putInt("selection-end", text.getSelectionEnd()); editor.putInt("fileformat", fileformat); editor.putBoolean("openingIntent", openingIntent); editor.commit(); } } // end onPause() /**************************************************************** * onResume() * What happens when you resume the app */ protected void onResume() { super.onResume(); if (!fromIntent) myResume(); fromIntent = false; } private void myResume() { try { // make sure the correct options are being used updateOptions(); // load the previous text SharedPreferences prefs = getPreferences(MODE_PRIVATE); String restoredText = prefs.getString("text", null); String titleText = prefs.getString("fntext", null); openingIntent = prefs.getBoolean("openingIntent", false); int selectionStart = prefs.getInt("selection-start", -1); int selectionEnd = prefs.getInt("selection-end", -1); lastModified = prefs.getLong("lastModified", lastModified); filename = prefs.getString("filename", null); if (filename == null || filename == "") untitled = true; else untitled = false; fileformat = prefs.getInt("fileformat", FILEFORMAT_NL); // clear double quote problem if (restoredText != null) { int nq = prefs.getInt("text-quotes", 0); if (nq != 0 && countQuotes(restoredText) == 2*nq) restoredText = restoredText.replaceAll("\"\"", "\""); } if (titleText != null) { int nq = prefs.getInt("fntext-quotes", 0); if (nq != 0 && countQuotes(titleText) == 2*nq) titleText = titleText.replaceAll("\"\"", "\""); } if (filename != null) { int nq = prefs.getInt("filename-quotes", 0); if (nq != 0 && countQuotes(filename.toString()) == 2*nq) filename = filename.toString().replaceAll("\"\"", "\""); } if (restoredText != null && text != null) { text.setText(restoredText); if (selectionStart != -1 && selectionEnd != -1) { text.setSelection(selectionStart, selectionEnd); } } if (titleText != null && title != null) { title.setText(titleText); } if (text != null) text.requestFocus(); // for some reason I have to reset the text at the end to get the caret at the beginning // this has to happen at the end for some reason. I think it needs a little bit of delay. if (text != null && (selectionStart == 0 && selectionEnd == 0)) { if (restoredText != null) { text.setText(restoredText); } if (titleText != null && title != null) { title.setText(titleText); } } // search search search if (fromSearch) { int start; String t = text.getText().toString().toLowerCase(); start = t.indexOf(queryString.toLowerCase(), selectionStart+1); if (start == -1) // loop search start = t.indexOf(queryString.toLowerCase(), 0); if (start != -1) { text.setSelection(start, start + queryString.length()); } else { Toast.makeText(this, "\"" + queryString + "\" not found", Toast.LENGTH_SHORT).show(); } fromSearch = false; } } catch (Exception e) { createNew(); } // figure out if the the file has been previously modified if (!creatingFile && !savingFile && !openingFile && !openingError && !openingRecent && !openingIntent && !sendingAttachment) { if (lastModified != 0 && lastModified != (new File(filename.toString())).lastModified()) { showDialog(DIALOG_MODIFIED); } } } // end onResume() /**************************************************************** * onPrepareDialog() * This function is called EVERY time a dialog is displayed */ protected void onPrepareDialog(int id, Dialog dialog) { switch (id) { // just update the messages for errors case DIALOG_NOTFOUND_ERROR: dialog.setTitle(errorFname + " not found"); break; case DIALOG_READ_ERROR: dialog.setTitle("Error reading " + errorFname); break; // need to have an intuitive starting option for save and open case DIALOG_SAVE_FILE_AUTOCOMPLETE: case DIALOG_SAVE_FILE: if (backFromFileBrowser) { saveDialog_fne.setText(fileBrowserReturnFile); backFromFileBrowser = false; } else if (temp_filename.length() != 0) { saveDialog_fne.setText(temp_filename); } else if (!errorSaving) { if (filename == "" || untitled) { // get default directory SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getBaseContext()); String location = sharedPref.getString("defaultdir", "/sdcard/"); File f = new File(location); if (f.toString().equals("/")) saveDialog_fne.setText("/"); else if (f.isDirectory()) saveDialog_fne.setText(f.toString() + "/"); else if (f.getParent().toString().equals("/")) saveDialog_fne.setText("/"); else saveDialog_fne.setText(f.getParent() + "/"); } else { saveDialog_fne.setText(filename); } } if (saveDialog_fne.getText().length() == 0) { if (filename == "" || untitled) { saveDialog_fne.setText(R.string.defaultFilePath); } else { saveDialog_fne.setText(filename); } } saveDialog_fne.setSelection(saveDialog_fne.getText().length(),saveDialog_fne.getText().length()); break; case DIALOG_OPEN_FILE_AUTOCOMPLETE: case DIALOG_OPEN_FILE: if (openingError) { File f = new File(errorFname.toString()); if (f.toString().equals("/")) openDialog_fne.setText("/"); else if (f.isDirectory()) openDialog_fne.setText(f.toString() + "/"); else if (f.getParent().toString().equals("/")) openDialog_fne.setText("/"); else openDialog_fne.setText(f.getParent() + "/"); openingError = false; } else if (backFromFileBrowser) { openDialog_fne.setText(fileBrowserReturnFile); backFromFileBrowser = false; } else if (filename == "" || untitled) { // get default directory SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getBaseContext()); String location = sharedPref.getString("defaultdir", "/sdcard/"); File f = new File(location); if (f.toString().equals("/")) openDialog_fne.setText("/"); else if (f.isDirectory()) openDialog_fne.setText(f.toString() + "/"); else if (f.getParent().toString().equals("/")) openDialog_fne.setText("/"); else openDialog_fne.setText(f.getParent() + "/"); } else { File f = new File(filename.toString()); if (f == null) openDialog_fne.setText(R.string.defaultFilePath); else { if (f.getParent().equals("/")) openDialog_fne.setText("/"); else openDialog_fne.setText(f.getParent() + "/"); } } openDialog_fne.setSelection(openDialog_fne.getText().length(),openDialog_fne.getText().length()); break; case DIALOG_RECENT_FILE_DIALOG: { // make sure we have the most recent recent files in this dialog readRecentFiles(); recentFilesAdapter.notifyDataSetChanged(); openRecentListView.setSelection(0); } } } // onPrepareDialog() /**************************************************************** * onCreateDialog() * This function is called the FIRST time a dialog is displayed */ protected Dialog onCreateDialog(int id) { switch (id) { case DIALOG_SAVE_FILE_AUTOCOMPLETE: case DIALOG_SAVE_FILE: { int layoutid; if (autoComplete) layoutid = R.layout.dialog_savefile; else layoutid = R.layout.dialog_savefile_noauto; // create the layout we want LayoutInflater factory = LayoutInflater.from(this); final View textEntryView = factory.inflate(layoutid, null); saveDialog_fne = (EditText) textEntryView.findViewById(R.id.filename_edit); if (autoComplete) { // textwatcher to update the autocomplete option TextWatcher tw = new TextWatcher() { public void onTextChanged(CharSequence s, int start, int before, int count) { AutoCompleteTextView acView = (AutoCompleteTextView) textEntryView.findViewById(R.id.filename_edit); getFileList(s, acView); // this makes the updated file list } public void afterTextChanged(Editable s) { } public void beforeTextChanged(CharSequence s, int start, int count, int after) { } }; AutoCompleteTextView acView = (AutoCompleteTextView) textEntryView.findViewById(R.id.filename_edit); acView.addTextChangedListener(tw); acView.setThreshold(1); // just a little property // need to do this so the textWatcher activates // for some reason it doesn't work initially if we don't do this acView.setText(""); } // the actual dialog being created return new AlertDialog.Builder(this) .setIcon(android.R.drawable.ic_dialog_info) .setTitle("Save File") .setView(textEntryView) .setPositiveButton("Save", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { // what to do when positive clicked TextView v = (TextView) textEntryView.findViewById(R.id.filename_edit); File f = new File(v.getText().toString()); boolean exists = f.exists(); boolean isdir = f.isDirectory(); boolean canwrite = f.canWrite(); if (exists && !isdir && canwrite) { temp_filename = v.getText(); showDialog(DIALOG_OVERWRITE); } else { // this will handle some of the other errors. saveNote(v.getText()); savingFile = false; if (!errorSaving && openingRecent) showDialog(DIALOG_RECENT_FILE_DIALOG); if (!errorSaving && creatingFile) createNew(); if (!errorSaving && openingFile) { if (autoComplete) { showDialog(DIALOG_OPEN_FILE_AUTOCOMPLETE); } else { showDialog(DIALOG_OPEN_FILE); } } if (!errorSaving && sendingAttachment) sendAttachment(); if (!errorSaving && openingIntent && getIntent().getData() != null) openFile(getIntent().getData()); } } }) .setNeutralButton("Browser", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { // figure out the default file from what is open File f = null; String location = "/sdcard/"; try { if (openingFile) f = new File(openDialog_fne.getText().toString()); else if (savingFile) f = new File(saveDialog_fne.getText().toString()); } catch (Exception e) { } if (f != null) location = f.toString(); // start the file browser activity Intent intent = new Intent(getBaseContext(), FileBrowser.class); intent.setAction(location); startActivityForResult(intent, REQUEST_FILE_BROWSER_SAVE); } }) .setNegativeButton("Cancel", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { // User clicked cancel so do some stuff creatingFile = false; openingFile = false; errorSaving = false; openingRecent = false; savingFile = false; sendingAttachment = false; if (openingIntent) openFile(getIntent().getData()); } }) .create(); } case DIALOG_OPEN_FILE_AUTOCOMPLETE: case DIALOG_OPEN_FILE: { int layoutid; if (autoComplete) layoutid = R.layout.dialog_savefile; else layoutid = R.layout.dialog_savefile_noauto; // create the layout we want LayoutInflater factory = LayoutInflater.from(this); final View textEntryView = factory.inflate(layoutid, null); openDialog_fne = (EditText) textEntryView.findViewById(R.id.filename_edit); if (autoComplete) { // textwatcher to update the autocomplete option TextWatcher tw = new TextWatcher() { public void onTextChanged(CharSequence s, int start, int before, int count) { AutoCompleteTextView acView = (AutoCompleteTextView) textEntryView.findViewById(R.id.filename_edit); getFileList(s, acView); // this makes the updated file list } public void afterTextChanged(Editable s) { } public void beforeTextChanged(CharSequence s, int start, int count, int after) { } }; AutoCompleteTextView acView = (AutoCompleteTextView) textEntryView.findViewById(R.id.filename_edit); acView.addTextChangedListener(tw); acView.setThreshold(1); // just a little property // need to do this so the textWatcher activates // for some reason it doesn't work initially if we don't do this acView.setText(""); } // the actual dialog being created return new AlertDialog.Builder(this) .setIcon(android.R.drawable.ic_dialog_info) .setTitle("Open File") .setView(textEntryView) .setPositiveButton("Open", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { // what to do when positive clicked TextView v = (TextView) textEntryView.findViewById(R.id.filename_edit); openFile(v.getText()); } }) .setNeutralButton("Browser", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { // figure out the default file based on what is open File f = null; String location = "/sdcard/"; try { if (openingFile) f = new File(openDialog_fne.getText().toString()); else if (savingFile) f = new File(saveDialog_fne.getText().toString()); } catch (Exception e) { } if (f != null) location = f.toString(); // launch the activity Intent intent = new Intent(getBaseContext(), FileBrowser.class); intent.setAction(location); startActivityForResult(intent, REQUEST_FILE_BROWSER_OPEN); } }) .setNegativeButton("Cancel", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { // User clicked cancel so do some stuff creatingFile = false; openingFile = false; openingRecent = false; savingFile = false; sendingAttachment = false; } }) .create(); } case DIALOG_RECENT_FILE_DIALOG: { // read the file list readRecentFiles(); // update the files list recentFilesAdapter = new FileViewArrayAdapter(getBaseContext(), recentItems); // custom listview so that we can put the list back up to the top automatically // in the on prepare LayoutInflater factory = LayoutInflater.from(this); openRecentListView = (ListView) factory.inflate(R.layout.openrecent_list, null); openRecentListView.setAdapter(recentFilesAdapter); openRecentListView.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { openFile(recentItems.get(arg2)); openRecentDialog.dismiss(); }}); openRecentDialog = new AlertDialog.Builder(this) .setIcon(R.drawable.ic_dialog_menu_generic) .setTitle(R.string.openRecent) .setView(openRecentListView) .setInverseBackgroundForced(true) .setOnCancelListener(new OnCancelListener() { public void onCancel(DialogInterface dialog) { openingRecent = false; }}) .create(); return openRecentDialog; } case DIALOG_SAVE_ERROR_PERMISSIONS: { return new AlertDialog.Builder(this) .setIcon(R.drawable.alert_dialog_icon) .setTitle(R.string.accessDenied) .setPositiveButton("Continue", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { // what to do when positive clicked if (!openingRecent) { if (autoComplete) showDialog(DIALOG_SAVE_FILE_AUTOCOMPLETE); else showDialog(DIALOG_SAVE_FILE); } } }) .create(); } case DIALOG_SAVE_ERROR_SDCARD: { return new AlertDialog.Builder(this) .setIcon(R.drawable.alert_dialog_icon) .setMessage(R.string.accessDeniedSDcard) // .setTitle(R.string.accessDeniedSDcard) .setPositiveButton("Continue", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { // what to do when positive clicked // if (!openingRecent) { if (autoComplete) showDialog(DIALOG_SAVE_FILE_AUTOCOMPLETE); else showDialog(DIALOG_SAVE_FILE); } } }) .create(); } case DIALOG_SAVE_ERROR: { return new AlertDialog.Builder(this) .setIcon(R.drawable.alert_dialog_icon) .setMessage(R.string.savingError) // .setTitle(R.string.savingError) .setPositiveButton("Continue", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { // what to do when positive clicked // if (!openingRecent) { if (autoComplete) showDialog(DIALOG_SAVE_FILE_AUTOCOMPLETE); else showDialog(DIALOG_SAVE_FILE); } } }) .create(); } case DIALOG_NOTFOUND_ERROR: { return new AlertDialog.Builder(this) .setIcon(R.drawable.alert_dialog_icon) .setTitle(errorFname + " not found") .setPositiveButton("Continue", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { // what to do when positive clicked // do nothing, just letting the user know if (openingRecent) { removeRecentFile(errorFname); } else { if (autoComplete) showDialog(DIALOG_OPEN_FILE_AUTOCOMPLETE); else showDialog(DIALOG_OPEN_FILE); } } }) .create(); } case DIALOG_READ_ERROR: { return new AlertDialog.Builder(this) .setIcon(R.drawable.alert_dialog_icon) .setTitle("Error reading " + errorFname) .setPositiveButton("Continue", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { // what to do when positive clicked // do nothing, just letting the user know if (!openingIntent) { if (autoComplete) showDialog(DIALOG_OPEN_FILE_AUTOCOMPLETE); else showDialog(DIALOG_OPEN_FILE); } } }) .create(); } case DIALOG_SHOULD_SAVE_INTENT: case DIALOG_SHOULD_SAVE: { int t; if (id == DIALOG_SHOULD_SAVE_INTENT) t = R.string.shouldSaveIntent; else t = R.string.shouldSave; return new AlertDialog.Builder(this) .setIcon(R.drawable.alert_dialog_icon) .setTitle(t) .setPositiveButton("Yes", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { savingFile = true; if (untitled) { if (autoComplete) showDialog(DIALOG_SAVE_FILE_AUTOCOMPLETE); else showDialog(DIALOG_SAVE_FILE); } else { saveNote(filename); if (!errorSaving && openingRecent) showDialog(DIALOG_RECENT_FILE_DIALOG); if (!errorSaving && creatingFile) createNew(); if (!errorSaving && openingFile) { if (autoComplete) showDialog(DIALOG_OPEN_FILE_AUTOCOMPLETE); else showDialog(DIALOG_OPEN_FILE); } if (!errorSaving && openingIntent) { Uri mUri; if (newIntent != null) mUri = newIntent.getData(); else mUri = getIntent().getData(); openFile(mUri); } if (!errorSaving && sendingAttachment) sendAttachment(); } } }) .setNegativeButton("No", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { sendingAttachment = false; if (creatingFile) createNew(); if (openingRecent) showDialog(DIALOG_RECENT_FILE_DIALOG); if (openingFile) { if (autoComplete) showDialog(DIALOG_OPEN_FILE_AUTOCOMPLETE); else showDialog(DIALOG_OPEN_FILE); } if (openingIntent) { Uri mUri; if (newIntent != null) mUri = newIntent.getData(); else mUri = getIntent().getData(); if (mUri != null && !mUri.getPath().equals(filename)) openFile(mUri); } } }) .create(); } case DIALOG_MODIFIED: { return new AlertDialog.Builder(this) .setIcon(R.drawable.alert_dialog_icon) .setTitle(R.string.externalModify) .setPositiveButton("Yes", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { openFile(filename); } }) .setNegativeButton("No", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { lastModified = (new File(filename.toString())).lastModified(); } }) .create(); } case DIALOG_OVERWRITE: { return new AlertDialog.Builder(this) .setIcon(R.drawable.alert_dialog_icon) .setTitle(R.string.shouldOverwrite) .setPositiveButton("Continue", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { saveNote(temp_filename); if (!errorSaving && openingRecent) showDialog(DIALOG_RECENT_FILE_DIALOG); if (!errorSaving && creatingFile) createNew(); if (!errorSaving && openingFile) { if (autoComplete) showDialog(DIALOG_OPEN_FILE_AUTOCOMPLETE); else showDialog(DIALOG_OPEN_FILE); } if (!errorSaving && sendingAttachment) sendAttachment(); if (!errorSaving && openingIntent) openFile(getIntent().getData()); if (!errorSaving) temp_filename = ""; } }) .setNegativeButton("Cancel", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { if (autoComplete) showDialog(DIALOG_SAVE_FILE_AUTOCOMPLETE); else showDialog(DIALOG_SAVE_FILE); } }) .create(); } } return null; } // end onCreateDialog() /**************************************************************** * menu Functions */ public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); menu.add(0, MENU_NEW_ID, 0, "New File").setShortcut('0', 'n').setIcon(R.drawable.icon_new); menu.add(0, MENU_SAVE_ID, 0, "Save").setShortcut('0', 's').setIcon(R.drawable.icon_save); menu.add(0, MENU_SAVEAS_ID, 0, "Save As").setIcon(R.drawable.icon_saveas); menu.add(0, MENU_OPEN_ID, 0, "Open").setShortcut('0', 'o').setIcon(R.drawable.icon_open); menu.add(0, MENU_OPENRECENT_ID, 0, "Recent").setShortcut('0', 'r').setIcon(R.drawable.icon_openrecent); menu.add(0, MENU_EMAIL, 0, "Email Text").setShortcut('0', 'e'); menu.add(0, MENU_SEARCH, 0, "Search Text").setShortcut('0', 'f'); menu.add(0, MENU_ATTACHMENT, 0, "Email as Attachment"); menu.add(0, MENU_OPTIONS_ID, 0, "Options").setIcon(R.drawable.icon_options); return true; } // end onCreateOptionsMenu() public boolean onOptionsItemSelected(MenuItem item) { // Handle all of the possible menu actions. openingFile = false; creatingFile = false; switch (item.getItemId()) { case MENU_SAVE_ID: // Save savingFile = true; if (untitled) { if (autoComplete) showDialog(DIALOG_SAVE_FILE_AUTOCOMPLETE); else showDialog(DIALOG_SAVE_FILE); } else saveNote(filename); break; case MENU_SAVEAS_ID: // Save as savingFile = true; if (autoComplete) showDialog(DIALOG_SAVE_FILE_AUTOCOMPLETE); else showDialog(DIALOG_SAVE_FILE); break; case MENU_OPENRECENT_ID: // Open Recent List openingRecent = true; if (isTextChanged()) showDialog(DIALOG_SHOULD_SAVE); else showDialog(DIALOG_RECENT_FILE_DIALOG); break; case MENU_OPEN_ID: // Open openingFile = true; openingIntent = false; if (isTextChanged()) showDialog(DIALOG_SHOULD_SAVE); else { if (autoComplete) showDialog(DIALOG_OPEN_FILE_AUTOCOMPLETE); else showDialog(DIALOG_OPEN_FILE); } break; case MENU_OPTIONS_ID: // Options startActivityForResult(new Intent(this, EditPreferences.class), REQUEST_CODE_PREFERENCES); break; case MENU_NEW_ID: // Newfile creatingFile = true; if (isTextChanged()) showDialog(DIALOG_SHOULD_SAVE); else createNew(); break; case MENU_EMAIL: // Email Text Intent sendIntent = new Intent(Intent.ACTION_SEND); sendIntent.putExtra(Intent.EXTRA_TEXT, text.getText()); sendIntent.setType("message/rfc822"); startActivity(Intent.createChooser(sendIntent, "Send email with")); break; case MENU_SEARCH: // Trigger search this.onSearchRequested(); break; case MENU_ATTACHMENT: // Email Attachment sendingAttachment = true; if (isTextChanged()) showDialog(DIALOG_SHOULD_SAVE); else if (untitled) { Toast.makeText(this, R.string.onSendEmptyMessage, Toast.LENGTH_SHORT).show(); } else sendAttachment(); break; } return super.onOptionsItemSelected(item); } // end onOptionsItemSelected() /**************************************************************** * Random Functions */ public void sendAttachment() { Intent sIntent = new Intent(Intent.ACTION_SEND); sIntent.setType("message/rfc822"); sIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + filename)); startActivity(Intent.createChooser(sIntent, "Send attachment with:")); sendingAttachment = false; } // end sendAttachment() public static boolean isTextChanged() // checks if the text has been changed { CharSequence temp = title.getText(); try { // was getting error on the developer site, so added this to "catch" it if (temp.charAt(0) == '*') { return true; } } catch (Exception e) { return false; } return false; } // end isTextChanged() public static int countQuotes(String t) // count " in string { int i = -1; int count = -1; do { i = t.indexOf('"', i+1); count++; } while (i != -1); return count; } // end countQuotes() // returns a file list for out autocomplete open and save dialogs private static File prevFile = null; public void getFileList(CharSequence s, AutoCompleteTextView acView) { File f = new File(s.toString()); File pFile; // get the parent directory if (f.isDirectory() && s.charAt(s.length()-1) == '/') pFile = f; else pFile = f.getParentFile(); // if we have no text and give some defaults if (s.equals("")) pFile = new File("/"); if (pFile == null) pFile = new File("/"); // we the parent file is actually different then update it if (pFile != null && (prevFile == null || (prevFile != null && !prevFile.equals(pFile)))) { if (!pFile.canRead()) items.clear(); // no permission so no items else { File[] files = new File[0]; // get he file list if there is one if (pFile.isDirectory()) files = pFile.listFiles(); // add all the items if (items == null) items = new ArrayList<String>(); else items.clear(); int i, length = files.length; for(i = 0; i < length; i++) { if (files[i].isDirectory()) items.add(files[i].getPath() + "/"); else items.add(files[i].getPath()); } } // update the files list FileAutoCompleteArrayAdapter adapter = new FileAutoCompleteArrayAdapter(getBaseContext(), android.R.layout.simple_dropdown_item_1line, items); acView.setAdapter(adapter); } prevFile = pFile; } // end getFileList() /**************************************************************** * Recent Files Functions */ protected void readRecentFiles() { int i; SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); int numFiles = prefs.getInt("rf_numfiles", 0); // clear the current list if (recentItems == null) recentItems = new ArrayList<String>(); recentItems.clear(); // start adding stuff for(i = 0; i < numFiles; i++) { recentItems.add(prefs.getString("rf_file" + i, i + "")); } } // end readRecentFiles() protected void addRecentFile(CharSequence f) { if (recentItems == null) readRecentFiles(); // remove from list if it is already there int i; int length = recentItems.size(); for(i = 0; i < length; i++) { String t = recentItems.get(i); if (t.equals(f.toString())) { recentItems.remove(i); i--; length--; } } // add the new file recentItems.add(0, f.toString()); // make sure there are 7 max if (recentItems.size() > 7) recentItems.remove(7); // save this list in the preferences SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(this).edit(); //SharedPreferences.Editor editor = getPreferences(MODE_PRIVATE).edit(); for(i = 0; i < recentItems.size(); i++) { editor.putString("rf_file" + i, recentItems.get(i)); } editor.putInt("rf_numfiles", recentItems.size()); editor.commit(); } // end addRecentFile() protected void removeRecentFile(CharSequence f) { if (recentItems == null) readRecentFiles(); // remove from list if it is already there int i; int length = recentItems.size(); for(i = 0; i < length; i++) { String t = recentItems.get(i); if (t.equals(f.toString())) { recentItems.remove(i); i--; length--; } } // save this list in the preferences SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(this).edit(); //SharedPreferences.Editor editor = getPreferences(MODE_PRIVATE).edit(); for(i = 0; i < recentItems.size(); i++) { editor.putString("rf_file" + i, recentItems.get(i)); } editor.putInt("rf_numfiles", recentItems.size()); editor.commit(); } // end removeRecentFile(); } // end class pmTextEdit