Great Update to the source

This commit is contained in:
Vlad Mihalachi
2014-09-25 14:19:23 +02:00
parent ec5645c2a4
commit 276b831ceb
382 changed files with 21651 additions and 3801 deletions

View File

@@ -0,0 +1,32 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Turbo Editor.
*
* Turbo Editor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Turbo Editor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package sharedcode.turboeditor;
import android.app.Application;
import android.test.ApplicationTestCase;
/**
* <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
*/
public class ApplicationTest extends ApplicationTestCase<Application> {
public ApplicationTest() {
super(Application.class);
}
}

View File

@@ -0,0 +1,24 @@
<!--
~ Copyright (C) 2014 Vlad Mihalachi
~
~ This file is part of Turbo Editor.
~
~ Turbo Editor is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ Turbo Editor is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="sharedcode.turboeditor">
</manifest>

View File

@@ -0,0 +1,519 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Turbo Editor.
*
* Turbo Editor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Turbo Editor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package sharedcode.turboeditor.activity;
import android.app.ActionBar;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.app.ActivityOptionsCompat;
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.Toast;
import sharedcode.turboeditor.R;
import sharedcode.turboeditor.fragment.ChangelogDialogFragment;
import sharedcode.turboeditor.fragment.EditorFragment;
import sharedcode.turboeditor.fragment.NoFileOpenedFragment;
import sharedcode.turboeditor.preferences.SettingsFragment;
import sharedcode.turboeditor.util.AppInfoHelper;
import sharedcode.turboeditor.util.Constants;
import sharedcode.turboeditor.util.ProCheckUtils;
import sharedcode.turboeditor.views.CustomDrawerLayout;
import sharedcode.turboeditor.util.EventBusEvents;
import sharedcode.turboeditor.preferences.PreferenceHelper;
import sharedcode.turboeditor.util.ThemeHelper;
import org.apache.commons.io.FilenameUtils;
import org.sufficientlysecure.rootcommands.Shell;
import org.sufficientlysecure.rootcommands.Toolbox;
import java.io.File;
import de.greenrobot.event.EventBus;
public abstract class BaseHomeActivity extends Activity {
private static final int SELECT_FILE_CODE = 121;
private EditText editor;
/*
* This class provides a handy way to tie together the functionality of
* {@link DrawerLayout} and the framework <code>ActionBar</code> to implement the recommended
* design for navigation drawers.
*/
private ActionBarDrawerToggle mDrawerToggle;
/*
* The Drawer Layout
*/
private CustomDrawerLayout mDrawerLayout;
//region Activity facts
@Override
protected void onCreate(Bundle savedInstanceState) {
// set the windows background
ThemeHelper.setWindowsBackground(this);
// super!!
super.onCreate(savedInstanceState);
// setup the layout
setContentView(R.layout.activity_home);
// setup the navigation drawer
setupNavigationDrawer();
// Replace fragment
getFragmentManager()
.beginTransaction()
.replace(R.id.fragment_editor, new NoFileOpenedFragment())
.commit();
/* First Time we open this activity */
if (savedInstanceState == null) {
// Open
mDrawerLayout.openDrawer(Gravity.START);
// Set the default title
getActionBar().setTitle(getString(R.string.nome_app_turbo_editor));
}
// parse the intent
parseIntent(getIntent());
// show a dialog with the changelog
showChangeLog();
}
@Override
protected final void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
mDrawerToggle.syncState();
}
@Override
public void onResume() {
super.onResume();
// Register the Event Bus for events
EventBus.getDefault().registerSticky(this);
}
@Override
public void onPause() {
super.onPause();
// Unregister the Event Bus
EventBus.getDefault().unregister(this);
}
@Override
protected void onDestroy() {
try {
closeKeyBoard();
} catch (NullPointerException e) {
e.printStackTrace();
}
super.onDestroy();
}
@Override
public void onBackPressed() {
if (getFragmentManager().findFragmentById(R.id.fragment_editor) instanceof EditorFragment) {
// remove editor fragment
getFragmentManager()
.beginTransaction()
.replace(R.id.fragment_editor, new NoFileOpenedFragment())
.commit();
// Set the default title
getActionBar().setTitle(getString(R.string.nome_app_turbo_editor));
EventBus.getDefault().post(new EventBusEvents.ClosedAFile());
mDrawerLayout.openDrawer(Gravity.START);
mDrawerLayout.closeDrawer(Gravity.END);
} else {
displayInterstitial();
super.onBackPressed();
}
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
onBackPressed();
return true;
}
if (editor == null)
editor = (EditText) findViewById(R.id.editor);
// this will happen on first key pressed on hard-keyboard only. Once myInputField
// gets the focus again, it will automatically receive further key presses.
try{
if (editor != null && !editor.hasFocus()) {
editor.requestFocus();
editor.onKeyDown(keyCode, event);
}
} catch (NullPointerException ex){
}
return true;
}
@Override
public final void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mDrawerToggle.onConfigurationChanged(newConfig);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK && requestCode == SELECT_FILE_CODE) {
String path = data.getStringExtra("path");
File file = new File(path);
if (file.isFile() && file.exists()) {
EventBus.getDefault().postSticky(new EventBusEvents.NewFileToOpen(new File(path)));
} else if(file.isDirectory()) {
}
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
/* If we clicked on the Navigation Drawer Menu item */
if (mDrawerToggle.onOptionsItemSelected(item)) {
mDrawerLayout.closeDrawer(Gravity.RIGHT);
return true;
} else
return super.onOptionsItemSelected(item);
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
parseIntent(intent);
}
//endregion
//region Calls from the layout
public void OpenFile(View view) {
Intent subActivity = new Intent(BaseHomeActivity.this, SelectFileActivity.class);
subActivity.putExtra("action", SelectFileActivity.Actions.SelectFile);
Bundle scaleBundle = ActivityOptionsCompat.makeScaleUpAnimation(
view, 0, 0, view.getWidth(), view.getHeight()).toBundle();
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
startActivityForResult(subActivity, SELECT_FILE_CODE, scaleBundle);
else
startActivityForResult(subActivity, SELECT_FILE_CODE);
}
public void CreateFile(View view) {
onEvent(new EventBusEvents.NewFileToOpen(""));
onEvent(new EventBusEvents.AFileIsSelected("")); // simulate click on the list
}
public void OpenInfo(View view) {
Intent subActivity = new Intent(BaseHomeActivity.this, PreferenceAbout.class);
Bundle scaleBundle = ActivityOptionsCompat.makeScaleUpAnimation(
view, 0, 0, view.getWidth(), view.getHeight()).toBundle();
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
startActivity(subActivity, scaleBundle);
else
startActivity(subActivity);
}
public void OpenSettings(View view) {
mDrawerLayout.closeDrawer(Gravity.START);
mDrawerLayout.openDrawer(Gravity.END);
}
//endregion
//region Eventbus
public void onEvent(final EventBusEvents.NewFileToOpen event) {
new AsyncTask<Void, Void, Void>() {
File file;
String message;
String fileText;
ProgressDialog progressDialog;
@Override
protected void onPreExecute() {
super.onPreExecute();
// Close the drawer
mDrawerLayout.closeDrawer(Gravity.START);
file = event.getFile();
message = "";
progressDialog = new ProgressDialog(BaseHomeActivity.this);
progressDialog.setMessage(getString(R.string.please_wait));
progressDialog.show();
}
@Override
protected Void doInBackground(Void... params) {
try {
boolean isRoot = false;
if (!file.exists()) {
fileText = event.getFileText();
return null;
}
if (!file.canRead()) {
Shell shell = null;
shell = Shell.startRootShell();
Toolbox tb = new Toolbox(shell);
isRoot = tb.isRootAccessGiven();
}
if (isRoot) {
File tempFile = new File(getFilesDir(), "temp.root.file");
if (!tempFile.exists())
tempFile.createNewFile();
Shell shell = Shell.startRootShell();
Toolbox tb = new Toolbox(shell);
tb.copyFile(event.getFile().getAbsolutePath(), tempFile.getAbsolutePath(), false, false);
file = new File(tempFile.getAbsolutePath());
}
boolean autoencoding = PreferenceHelper.getAutoEncoding(BaseHomeActivity.this);
if (autoencoding) {
String encoding = sharedcode.turboeditor.util.FileUtils.getDetectedEncoding(file);
if (!TextUtils.isEmpty(encoding)) {
encoding = SettingsFragment.sCurrentEncoding;
} else {
SettingsFragment.sCurrentEncoding = encoding;
}
fileText = org.apache.commons.io.FileUtils.readFileToString(file, encoding);
} else {
fileText = org.apache.commons.io.FileUtils.readFileToString(file, SettingsFragment.sCurrentEncoding);
}
} catch (Exception e) {
message = e.getMessage();
fileText = "";
}
while (mDrawerLayout.isDrawerOpen(Gravity.START)) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
progressDialog.hide();
if (!message.isEmpty()) {
Toast.makeText(BaseHomeActivity.this, message, Toast.LENGTH_LONG).show();
EventBus.getDefault().post(new EventBusEvents.CannotOpenAFile());
} else {
getFragmentManager()
.beginTransaction()
.replace(R.id.fragment_editor, EditorFragment.newInstance(event.getFile().getAbsolutePath(), fileText))
.commit();
}
}
}.execute();
}
public void onEvent(EventBusEvents.SavedAFile event) {
try {
closeKeyBoard();
} catch (NullPointerException e) {
e.printStackTrace();
}
// Get intent, action and MIME type
final Intent intent = getIntent();
final String action = intent.getAction();
final String type = intent.getType();
if (Intent.ACTION_VIEW.equals(action)
|| Intent.ACTION_EDIT.equals(action)
|| Intent.ACTION_PICK.equals(action)
&& type != null) {
//This Activity was called by startActivityForResult
final Intent returnIntent = new Intent();
setResult(Activity.RESULT_OK, returnIntent);
// finish the activity
finish();
}
if (!ProCheckUtils.isPro(getApplicationContext()))
displayInterstitial();
}
public void onEvent(EventBusEvents.AFileIsSelected event){
String name = FilenameUtils.getName(event.getPath());
if(name.isEmpty())
getActionBar().setTitle(R.string.nome_app_turbo_editor);
else
getActionBar().setTitle(name);
}
/**
* When a file can't be opened
* Invoked by the EditorFragment
*
* @param event The event called
*/
public void onEvent(EventBusEvents.CannotOpenAFile event) {
//
mDrawerLayout.openDrawer(Gravity.LEFT);
//
getActionBar().setTitle(getString(R.string.nome_app_turbo_editor));
// Replace fragment
getFragmentManager()
.beginTransaction()
.replace(R.id.fragment_editor, new NoFileOpenedFragment())
.commit();
}
public void onEvent(EventBusEvents.APreferenceValueWasChanged event) {
if (event.getType() == EventBusEvents.APreferenceValueWasChanged.Type.THEME_CHANGE) {
ThemeHelper.setWindowsBackground(this);
}
}
//endregion
// closes the soft keyboard
private void closeKeyBoard() throws NullPointerException {
// Central system API to the overall input method framework (IMF) architecture
InputMethodManager inputManager =
(InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
// Base interface for a remotable object
IBinder windowToken = getCurrentFocus().getWindowToken();
// Hide type
int hideType = InputMethodManager.HIDE_NOT_ALWAYS;
// Hide the KeyBoard
inputManager.hideSoftInputFromWindow(windowToken, hideType);
}
/**
* Setup the navigation drawer
*/
private void setupNavigationDrawer() {
mDrawerLayout = (CustomDrawerLayout) findViewById(R.id.drawer_layout);
/* Action Bar */
final ActionBar ab = getActionBar();
ab.setDisplayHomeAsUpEnabled(true);
ab.setHomeButtonEnabled(true);
/* Navigation drawer */
mDrawerToggle =
new ActionBarDrawerToggle(
this,
mDrawerLayout,
R.drawable.ic_drawer,
R.string.nome_app_turbo_editor,
R.string.nome_app_turbo_editor) {
/**
* {@inheritDoc}
*/
@Override
public void onDrawerClosed(View view) {
invalidateOptionsMenu();
}
/**
* {@inheritDoc}
*/
@Override
public void onDrawerOpened(View drawerView) {
invalidateOptionsMenu();
try {
closeKeyBoard();
} catch (NullPointerException e) {
e.printStackTrace();
}
}
};
/* link the mDrawerToggle to the Drawer Layout */
mDrawerLayout.setDrawerListener(mDrawerToggle);
//mDrawerLayout.setFocusableInTouchMode(false);
}
/**
* Show a dialog with the changelog
*/
private void showChangeLog() {
final String currentVersion = AppInfoHelper.getCurrentVersion(this);
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
final String lastVersion = preferences.getString("last_version", currentVersion);
preferences.edit().putString("last_version", currentVersion).apply();
if (!lastVersion.equals(currentVersion)) {
ChangelogDialogFragment.showChangeLogDialog(getFragmentManager());
}
}
/**
* Parses the intent
*/
private void parseIntent(Intent intent) {
final String action = intent.getAction();
final String type = intent.getType();
if (Intent.ACTION_VIEW.equals(action)
|| Intent.ACTION_EDIT.equals(action)
|| Intent.ACTION_PICK.equals(action)
&& type != null) {
// Post event
EventBus.getDefault().postSticky(new EventBusEvents.NewFileToOpen(new File(intent.getData().getPath())));
}
else if (Intent.ACTION_SEND.equals(action) && type != null) {
if ("text/plain".equals(type)) {
onEvent(new EventBusEvents.NewFileToOpen(intent.getStringExtra(Intent.EXTRA_TEXT)));
onEvent(new EventBusEvents.AFileIsSelected("")); // simulate click on the list
}
}
}
public abstract void displayInterstitial();
}

View File

@@ -0,0 +1,80 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Turbo Editor.
*
* Turbo Editor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Turbo Editor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package sharedcode.turboeditor.activity;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import sharedcode.turboeditor.R;
import sharedcode.turboeditor.preferences.PreferenceHelper;
public class LicensesActivity extends Activity implements AdapterView.OnItemClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
boolean light = PreferenceHelper.getLightTheme(this);
if (light) {
setTheme(R.style.AppTheme_Light);
} else {
setTheme(R.style.AppTheme_Dark);
}
setContentView(R.layout.activity_licenses);
ListView listView = (ListView) findViewById(android.R.id.list);
listView.setOnItemClickListener(this);
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, getResources().getStringArray(R.array.open_source_libs));
listView.setAdapter(adapter);
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String openSourceLib = ((TextView) view.findViewById(android.R.id.text1)).getText().toString();
Intent browserIntent = null;
switch (openSourceLib) {
case "ChangeLog Library":
browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://github.com/gabrielemariotti/changeloglib?source=c#license"));
break;
case "EventBus":
browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://github.com/greenrobot/EventBus?source=c#license"));
break;
case "commons-io":
browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://commons.apache.org/proper/commons-io/"));
break;
case "RootCommands":
browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://github.com/dschuermann/superuser-commands"));
break;
case "Floating Action Button":
browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://github.com/makovkastar/FloatingActionButton"));
break;
}
if (browserIntent != null) {
startActivity(browserIntent);
}
}
}

View File

@@ -0,0 +1,166 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Turbo Editor.
*
* Turbo Editor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Turbo Editor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package sharedcode.turboeditor.activity;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import sharedcode.turboeditor.R;
import sharedcode.turboeditor.util.AppInfoHelper;
import sharedcode.turboeditor.util.Constants;
import sharedcode.turboeditor.util.ProCheckUtils;
public class PreferenceAbout extends Activity {
@Override
public void onCreate(final Bundle savedInstanceState) {
setTheme(R.style.AppTheme_Dark);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_about);
TextView changeLogText = (TextView) findViewById(R.id.changelog_text);
TextView proVersionText = (TextView) findViewById(R.id.pro_version_text);
try {
changeLogText.setText(String.format(getString(R.string.app_version), getPackageManager().getPackageInfo(getPackageName(), 0).versionName));
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
proVersionText.setVisibility(ProCheckUtils.isPro(getBaseContext()) ? View.GONE : View.VISIBLE);
}
@Override
protected void onDestroy() {
//checkout.stop();
super.onDestroy();
}
public void OpenPlayStore(View view) {
try {
if (Constants.FOR_AMAZON) {
String url = "amzn://apps/android?p=com.maskyn.fileeditor";
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url))
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
} else {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://search?q=pub:Maskyn"))
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
}
} catch (Exception e) {
}
}
public void GoToProVersion(View view) {
try {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=com.maskyn.fileeditorpro"))
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
} catch (Exception e) {
}
}
public void OpenGithub(View view) {
String url = "https://github.com/vmihalachi/TurboEditor";
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url))
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
}
public void SendFeedback(View view) {
String url = "http://forum.xda-developers.com/android/apps-games/app-turbo-editor-text-editor-t2832016";
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url))
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
}
public void SendMail(View view) {
Intent i = new Intent(Intent.ACTION_SEND);
i.setType("message/rfc822");
i.putExtra(Intent.EXTRA_EMAIL, new String[]{"maskyngames@gmail.com"});
i.putExtra(Intent.EXTRA_SUBJECT, AppInfoHelper.getApplicationName(getBaseContext()) + " " + AppInfoHelper.getCurrentVersion(getBaseContext()));
i.putExtra(Intent.EXTRA_TEXT, "");
try {
startActivity(Intent.createChooser(i, getString(R.string.nome_app_turbo_editor)));
} catch (android.content.ActivityNotFoundException ex) {
}
}
public void OpenTranslatePage(View view) {
String url = "http://crowdin.net/project/turbo-client";
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url))
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
}
public void OpenGooglePlusCommunity(View view) {
String url = "https://plus.google.com/u/0/communities/111974095419108178946";
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url))
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
}
/*void setupClickablePreferences() {
final Preference email = findPreference("aboutactivity_authoremail"),
changelog = findPreference("aboutactivity_changelog"),
open_source_licenses = findPreference("aboutactivity_open_source_licenses"),
market = findPreference("aboutactivity_authormarket");
if (email != null) {
email.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(final Preference preference) {
return false;
}
});
}
if (changelog != null) {
changelog.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(final Preference preference) {
ChangelogDialogFragment.showChangeLogDialog(getFragmentManager());
return false;
}
});
}
if (open_source_licenses != null) {
open_source_licenses.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(final Preference preference) {
startActivity(new Intent(PreferenceAbout.this, LicensesActivity.class));
return false;
}
});
}
if (market != null) {
market.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(final Preference preference) {
return false;
}
});
}
}*/
}

View File

@@ -0,0 +1,380 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Turbo Editor.
*
* Turbo Editor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Turbo Editor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package sharedcode.turboeditor.activity;
import android.app.Activity;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.PopupMenu;
import android.widget.SearchView;
import android.widget.TextView;
import android.widget.Toast;
import com.faizmalkani.floatingactionbutton.FloatingActionButton;
import sharedcode.turboeditor.R;
import sharedcode.turboeditor.adapter.AdapterDetailedList;
import sharedcode.turboeditor.fragment.EditDialogFragment;
import sharedcode.turboeditor.util.AlphanumComparator;
import sharedcode.turboeditor.util.Constants;
import sharedcode.turboeditor.preferences.PreferenceHelper;
import sharedcode.turboeditor.util.RootUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.sufficientlysecure.rootcommands.Shell;
import org.sufficientlysecure.rootcommands.Toolbox;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.concurrent.TimeoutException;
public class SelectFileActivity extends Activity implements SearchView.OnQueryTextListener, AdapterView.OnItemClickListener, EditDialogFragment.EditDialogListener {
private String currentFolder;
private ListView listView;
private boolean wantAFile;
private MenuItem mSearchViewMenuItem;
private SearchView mSearchView;
@Override
protected void onCreate(Bundle savedInstanceState) {
boolean light = PreferenceHelper.getLightTheme(this);
if (light) {
setTheme(R.style.AppTheme_Light);
} else {
setTheme(R.style.AppTheme_Dark);
}
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_select_file);
getActionBar().setDisplayHomeAsUpEnabled(true);
final Actions action = (Actions) getIntent().getExtras().getSerializable("action");
wantAFile = action == Actions.SelectFile;
listView = (ListView) findViewById(android.R.id.list);
listView.setOnItemClickListener(this);
listView.setTextFilterEnabled(true);
FloatingActionButton mFab = (FloatingActionButton)findViewById(R.id.fabbutton);
mFab.setColor(getResources().getColor(R.color.fab_light));
mFab.setDrawable(getResources().getDrawable(R.drawable.ic_fab_add));
mFab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
PopupMenu popup = new PopupMenu(SelectFileActivity.this, v);
popup.getMenuInflater().inflate(R.menu.popup_new_file, popup.getMenu());
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
final EditDialogFragment dialogFrag;
int i = item.getItemId();
if (i == R.id.im_new_file) {
dialogFrag = EditDialogFragment.newInstance(EditDialogFragment.Actions.NewFile);
dialogFrag.show(getFragmentManager().beginTransaction(), "dialog");
return true;
} else if (i == R.id.im_new_folder) {
dialogFrag = EditDialogFragment.newInstance(EditDialogFragment.Actions.NewFolder);
dialogFrag.show(getFragmentManager().beginTransaction(), "dialog");
return true;
} else {
return false;
}
}
});
popup.show();
}
});
mFab.listenTo(listView);
String lastNavigatedPath = PreferenceHelper.getWorkingFolder(this);
File file = new File(lastNavigatedPath);
if (!file.exists()) {
PreferenceHelper.setWorkingFolder(this, PreferenceHelper.SD_CARD_ROOT);
file = new File(PreferenceHelper.SD_CARD_ROOT);
}
new UpdateList().execute(file.getAbsolutePath());
}
@Override
public void onBackPressed() {
if (currentFolder.isEmpty() || currentFolder.equals("/")) {
finish();
} else {
File file = new File(currentFolder);
String parentFolder = file.getParent();
new UpdateList().execute(parentFolder);
}
}
public boolean onQueryTextChange(String newText) {
if (TextUtils.isEmpty(newText)) {
listView.clearTextFilter();
} else {
listView.setFilterText(newText);
}
return true;
}
public boolean onQueryTextSubmit(String query) {
return false;
}
void returnData(String path) {
final Intent returnIntent = new Intent();
returnIntent.putExtra("path", path);
setResult(RESULT_OK, returnIntent);
// finish the activity
finish();
}
@Override
public void onItemClick(AdapterView<?> parent,
View view, int position, long id) {
final String name = ((TextView) view.findViewById(android.R.id.text1)).getText().toString();
if (name.equals("..")) {
if (currentFolder.equals("/")) {
new UpdateList().execute(PreferenceHelper.getWorkingFolder(this));
} else {
File tempFile = new File(currentFolder);
if (tempFile.isFile()) {
tempFile = tempFile.getParentFile()
.getParentFile();
} else {
tempFile = tempFile.getParentFile();
}
new UpdateList().execute(tempFile.getAbsolutePath());
}
return;
} else if (name.equals(getString(R.string.home))) {
new UpdateList().execute(PreferenceHelper.getWorkingFolder(this));
return;
}
final File selectedFile = new File(currentFolder, name);
if (selectedFile.isFile() && wantAFile) {
returnData(selectedFile.getAbsolutePath());
} else if (selectedFile.isDirectory()) {
new UpdateList().execute(selectedFile.getAbsolutePath());
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_select_file, menu);
mSearchViewMenuItem = menu.findItem(R.id.im_search);
mSearchView = (SearchView) mSearchViewMenuItem.getActionView();
mSearchView.setIconifiedByDefault(true);
mSearchView.setOnQueryTextListener(this);
mSearchView.setSubmitButtonEnabled(false);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
// menu items
MenuItem imSetAsWorkingFolder = menu.findItem(R.id.im_set_as_working_folder);
MenuItem imIsWorkingFolder = menu.findItem(R.id.im_is_working_folder);
MenuItem imSelectFolder = menu.findItem(R.id.im_select_folder);
if(imSetAsWorkingFolder != null){
// set the imSetAsWorkingFolder visible only if the two folder dont concide
imSetAsWorkingFolder.setVisible(!currentFolder.equals(PreferenceHelper.getWorkingFolder(SelectFileActivity.this)));
}
if(imIsWorkingFolder != null) {
// set visible is the other is invisible
imIsWorkingFolder.setVisible(!imSetAsWorkingFolder.isVisible());
}
if(imSelectFolder != null) {
imSelectFolder.setVisible(!wantAFile);
}
return super.onPrepareOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int i = item.getItemId();
if (i == android.R.id.home) {
finish();
return true;
} else if (i == R.id.im_set_as_working_folder) {
PreferenceHelper.setWorkingFolder(SelectFileActivity.this, currentFolder);
invalidateOptionsMenu();
return true;
} else if (i == R.id.im_select_folder) {
returnData(currentFolder);
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onFinishEditDialog(final String inputText, final String hint, final EditDialogFragment.Actions actions) {
if (actions == EditDialogFragment.Actions.NewFile && !TextUtils.isEmpty(inputText)) {
File file = new File(currentFolder, inputText);
returnData(file.getAbsolutePath());
} else if (actions == EditDialogFragment.Actions.NewFolder && !TextUtils.isEmpty(inputText)) {
File file = new File(currentFolder, inputText);
file.mkdirs();
new UpdateList().execute(currentFolder);
}
}
public enum Actions {
SelectFile, SelectFolder
}
private class UpdateList extends AsyncTask<String, Void, LinkedList<AdapterDetailedList.FileDetail>> {
String exceptionMessage;
@Override
protected void onPreExecute() {
super.onPreExecute();
if (mSearchView != null) {
mSearchView.setIconified(true);
mSearchViewMenuItem.collapseActionView();
mSearchView.setQuery("", false);
}
}
/**
* {@inheritDoc}
*/
@Override
protected LinkedList<AdapterDetailedList.FileDetail> doInBackground(final String... params) {
try {
final String path = params[0];
if (TextUtils.isEmpty(path)) {
return null;
}
File tempFile = new File(path);
if (tempFile.isFile()) {
tempFile = tempFile.getParentFile();
}
String[] unopenableExtensions = {"apk", "mp3", "mp4", "png", "jpg", "jpeg"};
final LinkedList<AdapterDetailedList.FileDetail> fileDetails = new LinkedList<>();
final LinkedList<AdapterDetailedList.FileDetail> folderDetails = new LinkedList<>();
final ArrayList<File> files;
currentFolder = tempFile.getAbsolutePath();
boolean isRoot = false;
if (!tempFile.canRead()) {
try {
Shell shell = null;
shell = Shell.startRootShell();
Toolbox tb = new Toolbox(shell);
isRoot = tb.isRootAccessGiven();
} catch (IOException | TimeoutException e) {
e.printStackTrace();
isRoot = false;
}
}
files = RootUtils.getFileList(currentFolder, isRoot);
Collections.sort(files, getFileNameComparator());
if (files != null) {
for (final File f : files) {
if (f.isDirectory()) {
folderDetails.add(new AdapterDetailedList.FileDetail(f.getName(),
getString(R.string.folder),
""));
} else if (f.isFile()
&& !FilenameUtils.isExtension(f.getName().toLowerCase(), unopenableExtensions)
&& FileUtils.sizeOf(f) <= Constants.MAX_FILE_SIZE * FileUtils.ONE_KB) {
final long fileSize = f.length();
SimpleDateFormat format = new SimpleDateFormat("MMM dd, yyyy hh:mm a");
String date = format.format(f.lastModified());
fileDetails.add(new AdapterDetailedList.FileDetail(f.getName(),
FileUtils.byteCountToDisplaySize(fileSize), date));
}
}
}
folderDetails.addAll(fileDetails);
return folderDetails;
} catch (Exception e) {
exceptionMessage = e.getMessage();
return null;
}
}
/**
* {@inheritDoc}
*/
@Override
protected void onPostExecute(final LinkedList<AdapterDetailedList.FileDetail> names) {
if (names != null) {
boolean isRoot = currentFolder.equals("/");
AdapterDetailedList mAdapter = new AdapterDetailedList(getBaseContext(), names, isRoot);
listView.setAdapter(mAdapter);
} else if (exceptionMessage != null) {
Toast.makeText(SelectFileActivity.this, exceptionMessage, Toast.LENGTH_SHORT).show();
}
invalidateOptionsMenu();
super.onPostExecute(names);
}
public final Comparator<File> getFileNameComparator() {
return new AlphanumComparator() {
/**
* {@inheritDoc}
*/
@Override
public String getTheString(Object obj) {
return ((File) obj).getName()
.toLowerCase();
}
};
}
}
}

View File

@@ -0,0 +1,204 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Turbo Editor.
*
* Turbo Editor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Turbo Editor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package sharedcode.turboeditor.adapter;
import android.content.Context;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Filter;
import android.widget.ImageView;
import android.widget.TextView;
import sharedcode.turboeditor.R;
import sharedcode.turboeditor.util.MimeTypes;
import org.apache.commons.io.FilenameUtils;
import java.util.Arrays;
import java.util.LinkedList;
public class AdapterDetailedList extends
ArrayAdapter<AdapterDetailedList.FileDetail> {
// Layout Inflater
private final LayoutInflater inflater;
private final LinkedList<FileDetail> orig;
private CustomFilter customFilter;
// List of file details
private LinkedList<FileDetail> fileDetails;
public AdapterDetailedList(final Context context,
final LinkedList<FileDetail> fileDetails,
final boolean isRoot) {
super(context, R.layout.item_file_list, fileDetails);
this.fileDetails = fileDetails;
this.orig = fileDetails;
this.inflater = LayoutInflater.from(context);
if (!isRoot) {
this.fileDetails.addFirst(new FileDetail("..", context.getString(R.string.folder), ""));
} else {
this.fileDetails.addFirst(new FileDetail(context.getString(R.string.home), context.getString(R.string.folder), ""));
}
}
@Override
public View getView(final int position,
View convertView, final ViewGroup parent) {
if (convertView == null) {
convertView = this.inflater
.inflate(R.layout.item_file_list,
null);
final ViewHolder hold = new ViewHolder();
hold.nameLabel = (TextView) convertView.findViewById(android.R.id.text1);
hold.detailLabel = (TextView) convertView.findViewById(android.R.id.text2);
hold.icon = (ImageView) convertView.findViewById(android.R.id.icon);
convertView.setTag(hold);
final FileDetail fileDetail = fileDetails.get(position);
final String fileName = fileDetail.getName();
setIcon(hold, fileDetail);
hold.nameLabel.setText(fileName);
hold.detailLabel.setText(fileDetail.getSize() + "\t\t" + fileDetail.getDateModified());
} else {
final ViewHolder hold = ((ViewHolder) convertView.getTag());
final FileDetail fileDetail = fileDetails.get(position);
final String fileName = fileDetail.getName();
setIcon(hold, fileDetail);
hold.nameLabel.setText(fileName);
hold.detailLabel.setText(fileDetail.getSize() + "\t\t" + fileDetail.getDateModified());
}
return convertView;
}
@Override
public int getCount() {
return fileDetails.size();
}
private void setIcon(final ViewHolder viewHolder, final FileDetail fileDetail) {
final String fileName = fileDetail.getName();
final String ext = FilenameUtils.getExtension(fileName);
if (fileDetail.isFolder()) {
viewHolder.icon.setImageResource(R.color.file_folder);
} else if (Arrays.asList(MimeTypes.MIME_HTML).contains(ext) || ext.endsWith("html")) {
viewHolder.icon.setImageResource(R.color.file_html);
} else if (Arrays.asList(MimeTypes.MIME_CODE).contains(ext)
|| fileName.endsWith("css")
|| fileName.endsWith("js")) {
viewHolder.icon.setImageResource(R.color.file_code);
} else if (Arrays.asList(MimeTypes.MIME_ARCHIVE).contains(ext)) {
viewHolder.icon.setImageResource(R.color.file_archive);
} else if (Arrays.asList(MimeTypes.MIME_MUSIC)
.contains(ext)) {
viewHolder.icon.setImageResource(R.color.file_media_music);
} else if (Arrays.asList(MimeTypes.MIME_PICTURE).contains(ext)) {
viewHolder.icon.setImageResource(R.color.file_media_picture);
} else if (Arrays.asList(MimeTypes.MIME_VIDEO).contains(ext)) {
viewHolder.icon.setImageResource(R.color.file_media_video);
} else {
viewHolder.icon.setImageResource(R.color.file_text);
}
}
@Override
public Filter getFilter() {
if (customFilter == null) {
customFilter = new CustomFilter();
}
return customFilter;
}
public static class ViewHolder {
// Name of the file
public TextView nameLabel;
// Size of the file
public TextView detailLabel;
// Icon of the file
public ImageView icon;
}
public static class FileDetail {
private final String name;
private final String size;
private final String dateModified;
private final boolean isFolder;
public FileDetail(String name, String size,
String dateModified) {
this.name = name;
this.size = size;
this.dateModified = dateModified;
isFolder = TextUtils.isEmpty(dateModified);
}
public String getDateModified() {
return dateModified;
}
public String getSize() {
return size;
}
public String getName() {
return name;
}
public boolean isFolder() {
return isFolder;
}
}
private class CustomFilter extends Filter {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if (constraint == null || constraint.length() == 0) {
results.values = orig;
results.count = orig.size();
} else {
LinkedList<FileDetail> nHolderList = new LinkedList<>();
for (FileDetail h : orig) {
if (h.getName().toLowerCase().contains(constraint.toString().toLowerCase()))
nHolderList.add(h);
}
results.values = nHolderList;
results.count = nHolderList.size();
}
return results;
}
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
fileDetails = (LinkedList<FileDetail>) results.values;
notifyDataSetChanged();
}
}
}

View File

@@ -0,0 +1,124 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Turbo Editor.
*
* Turbo Editor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Turbo Editor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package sharedcode.turboeditor.adapter;
import android.content.Context;
import android.graphics.Typeface;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import sharedcode.turboeditor.R;
import java.io.File;
import java.util.ArrayList;
public class AdapterDrawer extends
ArrayAdapter<File> {
private final Callbacks callbacks;
// Layout Inflater
private final LayoutInflater inflater;
// List of file details
private final ArrayList<File> files;
private String selectedPath = "";
public AdapterDrawer(Context context,
ArrayList<File> files,
Callbacks callbacks) {
super(context, R.layout.item_file_list, files);
this.files = files;
this.inflater = LayoutInflater.from(context);
this.callbacks = callbacks;
}
@Override
public View getView(final int position,
View convertView, final ViewGroup parent) {
if (convertView == null) {
convertView = this.inflater
.inflate(R.layout.item_drawer_list,
parent, false);
final ViewHolder hold = new ViewHolder();
hold.nameLabel = (TextView) convertView.findViewById(android.R.id.text1);
hold.cancelButton = (ImageView) convertView.findViewById(R.id.button_remove_from_list);
convertView.setTag(hold);
final String fileName = files.get(position).getName();
hold.nameLabel.setText(fileName);
hold.cancelButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
boolean closeOpenedFile = TextUtils.equals(selectedPath, files.get(position).getAbsolutePath());
callbacks.CancelItem(position, closeOpenedFile);
if (closeOpenedFile)
selectedPath = "";
}
});
if (TextUtils.equals(selectedPath, files.get(position).getAbsolutePath()))
hold.nameLabel.setTypeface(hold.nameLabel.getTypeface(), Typeface.BOLD);
else
hold.nameLabel.setTypeface(hold.nameLabel.getTypeface(), Typeface.NORMAL);
} else {
final ViewHolder hold = ((ViewHolder) convertView.getTag());
final String fileName = files.get(position).getName();
hold.nameLabel.setText(fileName);
hold.cancelButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
boolean closeOpenedFile = TextUtils.equals(selectedPath, files.get(position).getAbsolutePath());
callbacks.CancelItem(position, closeOpenedFile);
if (closeOpenedFile)
selectedPath = "";
}
});
if (TextUtils.equals(selectedPath, files.get(position).getAbsolutePath()))
hold.nameLabel.setTypeface(hold.nameLabel.getTypeface(), Typeface.BOLD);
else
hold.nameLabel.setTypeface(hold.nameLabel.getTypeface(), Typeface.NORMAL);
}
return convertView;
}
public void selectView(String selectedPath) {
callbacks.ItemSelected(selectedPath);
this.selectedPath = selectedPath;
notifyDataSetChanged();
}
public interface Callbacks {
void CancelItem(int position, boolean andCloseOpenedFile);
void ItemSelected(String path);
}
public static class ViewHolder {
// Name of the file
public TextView nameLabel;
public ImageView cancelButton;
}
}

View File

@@ -0,0 +1,91 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Turbo Editor.
*
* Turbo Editor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Turbo Editor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package sharedcode.turboeditor.fragment;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.LayoutInflater;
import sharedcode.turboeditor.R;
import it.gmariotti.changelibs.library.view.ChangeLogListView;
import sharedcode.turboeditor.util.Constants;
public class ChangelogDialogFragment extends DialogFragment {
public static void showChangeLogDialog(FragmentManager fragmentManager) {
ChangelogDialogFragment changelogDialogFragment = new ChangelogDialogFragment();
FragmentTransaction ft = fragmentManager.beginTransaction();
Fragment prev = fragmentManager.findFragmentByTag("changelogdemo_dialog");
if (prev != null) {
ft.remove(prev);
}
ft.addToBackStack(null);
changelogDialogFragment.show(ft, "changelogdemo_dialog");
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
LayoutInflater layoutInflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ChangeLogListView chgList = (ChangeLogListView) layoutInflater.inflate(R.layout.demo_changelog_fragment_dialogstandard, null);
return new AlertDialog.Builder(getActivity())
.setTitle(R.string.changelog)
.setView(chgList)
.setNegativeButton(android.R.string.cancel,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
dialog.dismiss();
}
}
)
.setPositiveButton(R.string.vota, new DialogInterface.OnClickListener() {
/**
* {@inheritDoc}
*/
@Override
public void onClick(final DialogInterface dialog, final int which) {
try {
if (Constants.FOR_AMAZON) {
String url = "amzn://apps/android?p=com.maskyn.fileeditor";
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url))
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
} else {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=com.maskyn.fileeditor"))
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
}
} catch (Exception e) {
}
}
})
.create();
}
}

View File

@@ -0,0 +1,128 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Turbo Editor.
*
* Turbo Editor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Turbo Editor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package sharedcode.turboeditor.fragment;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
import android.widget.TextView;
import sharedcode.turboeditor.R;
// ...
public class EditDialogFragment extends DialogFragment implements TextView.OnEditorActionListener {
private EditText mEditText;
public static EditDialogFragment newInstance(final Actions action) {
return EditDialogFragment.newInstance(action, "");
}
public static EditDialogFragment newInstance(final Actions action, final String hint) {
final EditDialogFragment f = new EditDialogFragment();
final Bundle args = new Bundle();
args.putSerializable("action", action);
args.putString("hint", hint);
f.setArguments(args);
return f;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final Actions action = (Actions) getArguments().getSerializable("action");
final String hint;
switch (action) {
case NewFile:
hint = getString(R.string.file);
break;
case NewFolder:
hint = getString(R.string.folder);
break;
default:
hint = null;
break;
}
final View view = getActivity().getLayoutInflater().inflate(R.layout.dialog_fragment_edittext, null);
this.mEditText = (EditText) view.findViewById(android.R.id.edit);
this.mEditText.setHint(hint);
// Show soft keyboard automatically
this.mEditText.setText(getArguments().getString("hint"));
this.mEditText.requestFocus();
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
this.mEditText.setOnEditorActionListener(this);
return new AlertDialog.Builder(getActivity())
.setView(view)
.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
returnData();
}
}
)
.setNegativeButton(android.R.string.cancel,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
}
)
.create();
}
void returnData() {
EditDialogListener target = (EditDialogListener) getTargetFragment();
if (target == null) {
target = (EditDialogListener) getActivity();
}
target.onFinishEditDialog(this.mEditText.getText().toString(), getArguments().getString("hint"),
(Actions) getArguments().getSerializable("action"));
this.dismiss();
}
@Override
public boolean onEditorAction(final TextView v, final int actionId, final KeyEvent event) {
if (EditorInfo.IME_ACTION_DONE == actionId) {
returnData();
return true;
}
return false;
}
public enum Actions {
NewFile, NewFolder
}
public interface EditDialogListener {
void onFinishEditDialog(String result, String hint, Actions action);
}
}

View File

@@ -0,0 +1,125 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Turbo Editor.
*
* Turbo Editor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Turbo Editor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package sharedcode.turboeditor.fragment;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.CompoundButton;
import android.widget.ListView;
import android.widget.Switch;
import sharedcode.turboeditor.R;
import sharedcode.turboeditor.preferences.PreferenceHelper;
import sharedcode.turboeditor.preferences.SettingsFragment;
import sharedcode.turboeditor.util.SaveFileTask;
import org.mozilla.universalchardet.Constants;
public class EncodingDialogFragment extends DialogFragment implements AdapterView.OnItemClickListener {
private final String[] encodings = new String[]{
Constants.CHARSET_BIG5,
Constants.CHARSET_EUC_JP,
Constants.CHARSET_EUC_KR,
Constants.CHARSET_EUC_TW,
Constants.CHARSET_GB18030,
"GB2312",
Constants.CHARSET_IBM855,
Constants.CHARSET_IBM866,
Constants.CHARSET_ISO_2022_CN,
Constants.CHARSET_ISO_2022_JP,
Constants.CHARSET_ISO_2022_KR,
Constants.CHARSET_ISO_8859_5,
Constants.CHARSET_ISO_8859_7,
Constants.CHARSET_ISO_8859_8,
Constants.CHARSET_KOI8_R,
Constants.CHARSET_MACCYRILLIC,
Constants.CHARSET_SHIFT_JIS,
Constants.CHARSET_UTF_16BE,
Constants.CHARSET_UTF_16LE,
Constants.CHARSET_UTF_32BE,
Constants.CHARSET_UTF_32LE,
Constants.CHARSET_UTF_8,
Constants.CHARSET_WINDOWS_1251,
Constants.CHARSET_WINDOWS_1252,
Constants.CHARSET_WINDOWS_1253,
Constants.CHARSET_WINDOWS_1255
};
private ListView list;
public static EncodingDialogFragment newInstance() {
final EncodingDialogFragment f = new EncodingDialogFragment();
return f;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final View view = getActivity().getLayoutInflater().inflate(R.layout.dialog_encoding_list, null);
list = (ListView) view.findViewById(android.R.id.list);
Switch autoencoding = (Switch) view.findViewById(android.R.id.checkbox);
autoencoding.setChecked(PreferenceHelper.getAutoEncoding(getActivity()));
autoencoding.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
PreferenceHelper.setAutoencoding(getActivity(), isChecked);
}
});
list.setAdapter(new ArrayAdapter<>(getActivity(), R.layout.item_single_choice, encodings));
list.setOnItemClickListener(this);
String currentEncoding = PreferenceHelper.getEncoding(getActivity());
for (int i = 0; i < encodings.length; i++) {
if (currentEncoding.equals(encodings[i])) {
list.setItemChecked(i, true);
}
}
return new AlertDialog.Builder(getActivity())
.setView(view)
.create();
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
DialogListener target = (DialogListener) getTargetFragment();
if (target == null) {
target = (DialogListener) getActivity();
}
target.onEncodingSelected(encodings[position]);
this.dismiss();
}
public interface DialogListener {
void onEncodingSelected(String result);
}
}

View File

@@ -0,0 +1,213 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Turbo Editor.
*
* Turbo Editor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Turbo Editor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package sharedcode.turboeditor.fragment;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.Toast;
import sharedcode.turboeditor.R;
import sharedcode.turboeditor.util.SearchResult;
import java.util.LinkedList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
// ...
public class FindTextDialogFragment extends DialogFragment {
private EditText textToFind, textToReplace;
private CheckBox regexCheck, replaceCheck, matchCaseCheck;
public static FindTextDialogFragment newInstance(String allText) {
final FindTextDialogFragment f = new FindTextDialogFragment();
final Bundle args = new Bundle();
args.putString("allText", allText);
f.setArguments(args);
return f;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final View view = getActivity().getLayoutInflater().inflate(R.layout.dialog_fragment_find_text, null);
this.textToFind = (EditText) view.findViewById(R.id.text_to_find);
this.textToReplace = (EditText) view.findViewById(R.id.text_to_replace);
this.regexCheck = (CheckBox) view.findViewById(R.id.regex_check);
this.replaceCheck = (CheckBox) view.findViewById(R.id.replace_check);
this.matchCaseCheck = (CheckBox) view.findViewById(R.id.match_case_check);
replaceCheck.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
textToReplace.setVisibility(isChecked ? View.VISIBLE : View.GONE);
}
});
return new AlertDialog.Builder(getActivity())
.setView(view)
.setPositiveButton(R.string.find,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
}
)
.setNegativeButton(android.R.string.cancel,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
}
)
.create();
}
@Override
public void onStart()
{
super.onStart(); //super.onStart() is where dialog.show() is actually called on the underlying dialog, so we have to do it after this point
AlertDialog d = (AlertDialog)getDialog();
if(d != null)
{
Button positiveButton = (Button) d.getButton(Dialog.BUTTON_POSITIVE);
positiveButton.setText(getString(R.string.find));
positiveButton.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
returnData();
}
});
Button negativeButton = (Button) d.getButton(Dialog.BUTTON_NEGATIVE);
negativeButton.setText(getString(android.R.string.cancel));
negativeButton.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
dismiss();
}
});
}
}
void returnData() {
if(textToFind.getText().toString().isEmpty()) {
this.dismiss();
} else {
// we disable the okButton while we search
new SearchTask().execute();
}
}
private class SearchTask extends AsyncTask<Void, Void, Void>{
LinkedList<Integer> foundIndex;
boolean foundSomething;
@Override
protected Void doInBackground(Void... params) {
String allText = getArguments().getString("allText");
String whatToSearch = textToFind.getText().toString();
boolean caseSensitive = matchCaseCheck.isChecked();
boolean isRegex = regexCheck.isChecked();
foundIndex = new LinkedList<>();
Matcher matcher = null;
foundSomething = false;
if(isRegex) {
try {
if(caseSensitive)
matcher = Pattern.compile(whatToSearch, Pattern.MULTILINE).matcher(allText);
else
matcher = Pattern.compile(whatToSearch, Pattern.CASE_INSENSITIVE | Pattern.MULTILINE).matcher(allText);
} catch (Exception e) {
isRegex = false;
}
}
if(isRegex) {
while (matcher.find()) {
foundSomething = true;
foundIndex.add(matcher.start());
}
} else {
if(caseSensitive == false) { // by default is case sensitive
whatToSearch = whatToSearch.toLowerCase();
allText = allText.toLowerCase();
}
int index = allText.indexOf(whatToSearch);
while (index >= 0) {
foundSomething = true;
foundIndex.add(index);
index = allText.indexOf(whatToSearch, index + 1);
}
}
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
if(foundSomething) {
// the class that called this Dialog should implement the SearchDialogIterface
SearchDialogInterface searchDialogInterface;
searchDialogInterface = ((SearchDialogInterface) getTargetFragment());
if(searchDialogInterface == null)
searchDialogInterface = ((SearchDialogInterface) getActivity());
// if who called this has not implemented the interface we return nothing
if(searchDialogInterface == null)
return;
// else we return positions and other things
else {
SearchResult searchResult = new SearchResult(foundIndex, textToFind.length(), replaceCheck.isChecked(), textToReplace.getText().toString());
searchDialogInterface.onSearchDone(searchResult);
}
} else {
}
Toast.makeText(getActivity(), String.format(getString(R.string.occurrences_found), foundIndex.size()), Toast.LENGTH_SHORT).show();
// dismiss the dialog
FindTextDialogFragment.this.dismiss();
}
}
public interface SearchDialogInterface {
void onSearchDone(SearchResult searchResult);
}
}

View File

@@ -0,0 +1,206 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Turbo Editor.
*
* Turbo Editor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Turbo Editor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package sharedcode.turboeditor.fragment;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListView;
import sharedcode.turboeditor.R;
import sharedcode.turboeditor.adapter.AdapterDrawer;
import sharedcode.turboeditor.util.EventBusEvents;
import sharedcode.turboeditor.preferences.PreferenceHelper;
import java.io.File;
import java.util.ArrayList;
import de.greenrobot.event.EventBus;
public class NavigationDrawerListFragment extends Fragment implements AdapterView.OnItemClickListener, AdapterDrawer.Callbacks {
private AdapterDrawer arrayAdapter;
private ArrayList<File> files;
private ListView listView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Our custom layout
View rootView = inflater.inflate(R.layout.fragment_navigation_drawer, container, false);
listView = (ListView) rootView.findViewById(android.R.id.list);
listView.setEmptyView(rootView.findViewById(android.R.id.empty));
files = new ArrayList<>();
arrayAdapter = new AdapterDrawer(getActivity(), files, this);
listView.setAdapter(arrayAdapter);
return rootView;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
listView.setOnItemClickListener(this);
}
@Override
public void onResume() {
super.onResume();
// Register the Event Bus for events
EventBus.getDefault().registerSticky(this);
// Refresh the list view
refreshList();
}
@Override
public void onPause() {
super.onPause();
// Unregister the Event Bus
EventBus.getDefault().unregister(this);
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// File paths saved in preferences
String[] savedPaths = PreferenceHelper.getSavedPaths(getActivity());
// Path of the file selected
String filePath = savedPaths[position];
// Send the event that a file was selected
EventBus.getDefault().post(new EventBusEvents.NewFileToOpen(new File(filePath)));
arrayAdapter.selectView(filePath);
}
/**
* When a new file is opened
* Invoked by the main activity which receive the intent
*
* @param event The event called
*/
public void onEvent(EventBusEvents.NewFileToOpen event) {
// File paths saved in preferences
String[] savedPaths = PreferenceHelper.getSavedPaths(getActivity());
String selectedPath = event.getFile().getAbsolutePath();
for (String savedPath : savedPaths) {
// We don't need to save the file path twice
if (savedPath.equals(selectedPath)) {
arrayAdapter.selectView(selectedPath);
return;
}
}
// Add the path if it wasn't added before
addPath(selectedPath);
arrayAdapter.selectView(selectedPath);
EventBus.getDefault().removeStickyEvent(event);
}
public void onEvent(EventBusEvents.SavedAFile event) {
if (addPath(event.getPath())) {
arrayAdapter.selectView(event.getPath());
}
}
public void onEvent(EventBusEvents.ClosedAFile event) {
arrayAdapter.selectView("");
}
private boolean addPath(String path) {
// File paths saved in preferences
String[] savedPaths = PreferenceHelper.getSavedPaths(getActivity());
// StringBuilder
StringBuilder sb = new StringBuilder();
boolean pathAlreadyExist = false;
for (String savedPath : savedPaths) {
// Append the file path and a comma
sb.append(savedPath).append(",");
if (savedPath.equals(path))
pathAlreadyExist = true;
}
// Append new path
if (!pathAlreadyExist)
sb.append(path);
// Put the string and commit
PreferenceHelper.setSavedPaths(getActivity(), sb);
// Update list
refreshList();
return pathAlreadyExist == false;
}
private void removePath(String path) {
// File paths saved in preferences
String[] savedPaths = PreferenceHelper.getSavedPaths(getActivity());
// StringBuilder
StringBuilder sb = new StringBuilder();
// for cycle
for (String savedPath : savedPaths) {
if (path.equals(savedPath)) continue;
sb.append(savedPath).append(",");
}
// Put the string and commit
PreferenceHelper.setSavedPaths(getActivity(), sb);
// Update list
refreshList();
}
private void refreshList() {
// File paths saved in preferences
String[] savedPaths = PreferenceHelper.getSavedPaths(getActivity());
// File names for the list
files.clear();
// StringBuilder that will contain the file paths
StringBuilder sb = new StringBuilder();
// for cycle to convert paths to names
for (String path : savedPaths) {
File file = new File(path);
// Check that the file exist
if (file.exists()) {
files.add(file);
sb.append(path).append(",");
}
}
// save list without empty or non existed files
PreferenceHelper.setSavedPaths(getActivity(), sb);
// Set adapter
arrayAdapter.notifyDataSetChanged();
}
@Override
public void CancelItem(int position, boolean andCloseOpenedFile) {
String[] savedPaths = PreferenceHelper.getSavedPaths(getActivity());
removePath(savedPaths[position]);
if (andCloseOpenedFile)
EventBus.getDefault().post(new EventBusEvents.CannotOpenAFile());
}
@Override
public void ItemSelected(String path) {
EventBus.getDefault().post(new EventBusEvents.AFileIsSelected(path));
}
}

View File

@@ -0,0 +1,93 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Turbo Editor.
*
* Turbo Editor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Turbo Editor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package sharedcode.turboeditor.fragment;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
import android.widget.TextView;
import java.io.File;
import sharedcode.turboeditor.R;
import sharedcode.turboeditor.activity.PreferenceAbout;
import sharedcode.turboeditor.preferences.PreferenceHelper;
import sharedcode.turboeditor.util.SaveFileTask;
// ...
public class NewFileDetailsDialogFragment extends DialogFragment {
private EditText mName;
private EditText mFolder;
public static NewFileDetailsDialogFragment newInstance(String fileText, String fileEncoding) {
final NewFileDetailsDialogFragment f = new NewFileDetailsDialogFragment();
final Bundle args = new Bundle();
args.putString("fileText", fileText);
args.putString("fileEncoding", fileEncoding);
f.setArguments(args);
return f;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final View view = getActivity().getLayoutInflater().inflate(R.layout.dialog_fragment_new_file_details, null);
this.mName = (EditText) view.findViewById(android.R.id.text1);
this.mFolder = (EditText) view.findViewById(android.R.id.text2);
this.mFolder.setText(PreferenceHelper.getWorkingFolder(getActivity()));
// Show soft keyboard automatically
this.mName.requestFocus();
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
return new AlertDialog.Builder(getActivity())
.setView(view)
.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if(!mName.getText().toString().isEmpty() && !mFolder.getText().toString().isEmpty()) {
File file = new File(mFolder.getText().toString(), mName.getText().toString());
new SaveFileTask(getActivity(), file.getPath(), getArguments().getString("fileText"), getArguments().getString("fileEncoding")).execute();
}
}
}
)
.setNegativeButton(android.R.string.cancel,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
}
)
.create();
}
}

View File

@@ -0,0 +1,37 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Turbo Editor.
*
* Turbo Editor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Turbo Editor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package sharedcode.turboeditor.fragment;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import sharedcode.turboeditor.R;
public class NoFileOpenedFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_no_file_open, container, false);
}
}

View File

@@ -0,0 +1,83 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Turbo Editor.
*
* Turbo Editor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Turbo Editor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package sharedcode.turboeditor.fragment;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.DialogInterface;
import android.os.Bundle;
import sharedcode.turboeditor.R;
import sharedcode.turboeditor.preferences.SettingsFragment;
import sharedcode.turboeditor.util.SaveFileTask;
import org.apache.commons.io.FilenameUtils;
import java.io.File;
public class SaveFileDialogFragment extends DialogFragment {
public static SaveFileDialogFragment newInstance(String filePath, String text) {
SaveFileDialogFragment frag = new SaveFileDialogFragment();
Bundle args = new Bundle();
args.putString("filePath", filePath);
args.putString("text", text);
frag.setArguments(args);
return frag;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final String filePath = getArguments().getString("filePath");
final String text = getArguments().getString("text");
final String fileName = FilenameUtils.getName(filePath);
final File file = new File(filePath);
return new AlertDialog.Builder(getActivity())
.setMessage(String.format(getString(R.string.save_changes), fileName))
.setPositiveButton(android.R.string.yes,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if(!fileName.isEmpty())
new SaveFileTask(getActivity(), filePath, text, SettingsFragment.sCurrentEncoding).execute();
else {
NewFileDetailsDialogFragment dialogFrag = NewFileDetailsDialogFragment.newInstance(text, SettingsFragment.sCurrentEncoding);
dialogFrag.show(getFragmentManager().beginTransaction(), "dialog");
}
}
}
)
.setNegativeButton(android.R.string.no,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
}
)
.create();
}
public static enum Action {
SaveAFile
}
}

View File

@@ -0,0 +1,103 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Turbo Editor.
*
* Turbo Editor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Turbo Editor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package sharedcode.turboeditor.fragment;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.View;
import android.widget.NumberPicker;
import sharedcode.turboeditor.R;
// ...
public class SeekbarDialogFragment extends DialogFragment {
private NumberPicker mSeekBar;
public static SeekbarDialogFragment newInstance(final Actions action) {
return SeekbarDialogFragment.newInstance(action, 0, 50, 100);
}
public static SeekbarDialogFragment newInstance(final Actions action, final int min, final int current, final int max) {
final SeekbarDialogFragment f = new SeekbarDialogFragment();
final Bundle args = new Bundle();
args.putSerializable("action", action);
args.putInt("min", min);
args.putInt("current", current);
args.putInt("max", max);
f.setArguments(args);
return f;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final Actions action = (Actions) getArguments().getSerializable("action");
final View view = getActivity().getLayoutInflater().inflate(R.layout.dialog_fragment_seekbar, null);
this.mSeekBar = (NumberPicker) view.findViewById(android.R.id.input);
this.mSeekBar.setMaxValue(getArguments().getInt("max"));
this.mSeekBar.setMinValue(getArguments().getInt("min"));
this.mSeekBar.setValue(getArguments().getInt("current"));
return new AlertDialog.Builder(getActivity())
//.setTitle(title)
.setView(view)
.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
returnData();
}
}
)
.setNegativeButton(android.R.string.cancel,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
}
)
.create();
}
void returnData() {
onSeekbarDialogDismissed target = (onSeekbarDialogDismissed) getTargetFragment();
if (target == null) {
target = (onSeekbarDialogDismissed) getActivity();
}
target.onSeekbarDialogDismissed(
(Actions) getArguments().getSerializable("action"),
mSeekBar.getValue()
);
this.dismiss();
}
public enum Actions {
FileSize, SelectPage, GoToLine
}
public interface onSeekbarDialogDismissed {
void onSeekbarDialogDismissed(Actions action, int value);
}
}

View File

@@ -0,0 +1,174 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Turbo Editor.
*
* Turbo Editor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Turbo Editor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package sharedcode.turboeditor.preferences;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Environment;
import android.preference.PreferenceManager;
public final class PreferenceHelper {
public static final String SD_CARD_ROOT = Environment.getExternalStorageDirectory().getAbsolutePath();
private PreferenceHelper() {
}
// Getter Methods
private static SharedPreferences getPrefs(Context context) {
return PreferenceManager.getDefaultSharedPreferences(context);
}
private static SharedPreferences.Editor getEditor(Context context) {
return getPrefs(context).edit();
}
public static boolean getUseMonospace(Context context) {
return getPrefs(context).getBoolean("use_monospace", false);
}
public static boolean getLineNumbers(Context context) {
return getPrefs(context).getBoolean("editor_line_numbers", true);
}
public static boolean getSyntaxHiglight(Context context) {
return getPrefs(context).getBoolean("editor_syntax_highlight", false);
}
public static boolean getWrapContent(Context context) {
return getPrefs(context).getBoolean("editor_wrap_content", true);
}
public static boolean getLightTheme(Context context) {
return getPrefs(context).getBoolean("light_theme", false);
}
public static boolean getSuggestionActive(Context context) {
return getPrefs(context).getBoolean("suggestion_active", false);
}
public static boolean getAutoEncoding(Context context) {
return getPrefs(context).getBoolean("autoencoding", true);
}
public static boolean getSendErrorReports(Context context) {
return getPrefs(context).getBoolean("send_error_reports", true);
}
public static int getLastDayAdShowed(Context context) {
return getPrefs(context).getInt("last_day_ad_showed", 0);
}
public static String getEncoding(Context context) {
return getPrefs(context).getString("editor_encoding", "UTF-8");
}
public static int getFontSize(Context context) {
return getPrefs(context).getInt("font_size", 16);
}
public static String getWorkingFolder(Context context) {
return getPrefs(context).getString("working_folder", SD_CARD_ROOT);
}
public static String[] getSavedPaths(Context context) {
return getPrefs(context).getString("savedPaths", "").split(",");
}
public static boolean getPageSystemButtonsPopupShown(Context context) {
return getPrefs(context).getBoolean("page_system_button_popup_shown", false);
}
public static boolean getAutoSave(Context context) {
return getPrefs(context).getBoolean("auto_save", false);
}
public static boolean getReadOnly(Context context) {
return getPrefs(context).getBoolean("read_only", false);
}
// Setter methods
public static void setUseMonospace(Context context, boolean value) {
getEditor(context).putBoolean("use_monospace", value).commit();
}
public static void setLineNumbers(Context context, boolean value) {
getEditor(context).putBoolean("editor_line_numbers", value).commit();
}
public static void setSyntaxHiglight(Context context, boolean value) {
getEditor(context).putBoolean("editor_syntax_highlight", value).commit();
}
public static void setWrapContent(Context context, boolean value) {
getEditor(context).putBoolean("editor_wrap_content", value).commit();
}
public static void setLightTheme(Context context, boolean value) {
getEditor(context).putBoolean("light_theme", value).commit();
}
public static void setSuggestionActive(Context context, boolean value) {
getEditor(context).putBoolean("suggestion_active", value).commit();
}
public static void setAutoencoding(Context context, boolean value) {
getEditor(context).putBoolean("autoencoding", value).commit();
}
public static void setSendErrorReports(Context context, boolean value) {
getEditor(context).putBoolean("send_error_reports", value).commit();
}
public static void setLastDayAdShowed(Context context, int value) {
getEditor(context).putInt("last_day_ad_showed", value).commit();
}
public static void setEncoding(Context context, String value) {
getEditor(context).putString("editor_encoding", value).commit();
}
public static void setFontSize(Context context, int value) {
getEditor(context).putInt("font_size", value).commit();
}
public static void setWorkingFolder(Context context, String value) {
getEditor(context).putString("working_folder", value).commit();
}
public static void setSavedPaths(Context context, StringBuilder stringBuilder) {
getEditor(context).putString("savedPaths", stringBuilder.toString()).commit();
}
public static void setPageSystemButtonsPopupShown(Context context, boolean value) {
getEditor(context).putBoolean("page_system_button_popup_shown", value).commit();
}
public static void setAutoSave(Context context, boolean value) {
getEditor(context).putBoolean("auto_save", value).commit();
}
public static void setReadOnly(Context context, boolean value) {
getEditor(context).putBoolean("read_only", value).commit();
}
}

View File

@@ -0,0 +1,264 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Turbo Editor.
*
* Turbo Editor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Turbo Editor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package sharedcode.turboeditor.preferences;
import android.app.Fragment;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.CheckedTextView;
import android.widget.CompoundButton;
import android.widget.Switch;
import android.widget.TextView;
import sharedcode.turboeditor.R;
import sharedcode.turboeditor.fragment.EncodingDialogFragment;
import sharedcode.turboeditor.fragment.SeekbarDialogFragment;
import de.greenrobot.event.EventBus;
import sharedcode.turboeditor.util.ProCheckUtils;
import static sharedcode.turboeditor.util.EventBusEvents.APreferenceValueWasChanged;
import static sharedcode.turboeditor.util.EventBusEvents.APreferenceValueWasChanged.Type.AUTO_SAVE;
import static sharedcode.turboeditor.util.EventBusEvents.APreferenceValueWasChanged.Type.ENCODING;
import static sharedcode.turboeditor.util.EventBusEvents.APreferenceValueWasChanged.Type.FONT_SIZE;
import static sharedcode.turboeditor.util.EventBusEvents.APreferenceValueWasChanged.Type.LINE_NUMERS;
import static sharedcode.turboeditor.util.EventBusEvents.APreferenceValueWasChanged.Type.MONOSPACE;
import static sharedcode.turboeditor.util.EventBusEvents.APreferenceValueWasChanged.Type.READ_ONLY;
import static sharedcode.turboeditor.util.EventBusEvents.APreferenceValueWasChanged.Type.SYNTAX;
import static sharedcode.turboeditor.util.EventBusEvents.APreferenceValueWasChanged.Type.TEXT_SUGGESTIONS;
import static sharedcode.turboeditor.util.EventBusEvents.APreferenceValueWasChanged.Type.THEME_CHANGE;
import static sharedcode.turboeditor.util.EventBusEvents.APreferenceValueWasChanged.Type.WRAP_CONTENT;
public class SettingsFragment extends Fragment implements EncodingDialogFragment.DialogListener, SeekbarDialogFragment.onSeekbarDialogDismissed {
public static String sCurrentEncoding;
// Editor Variables
public static boolean sLineNumbers;
public static boolean sColorSyntax;
public static boolean sWrapContent;
public static int sFontSize;
public static boolean sUseMonospace;
public static boolean sLightTheme;
public static boolean sSuggestionsActive;
public static boolean sAutoSave;
public static boolean sReadOnly;
public static boolean sSendErrorReports;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SettingsFragment.sCurrentEncoding = PreferenceHelper.getEncoding(getActivity());
SettingsFragment.sUseMonospace = PreferenceHelper.getUseMonospace(getActivity());
SettingsFragment.sColorSyntax = PreferenceHelper.getSyntaxHiglight(getActivity());
SettingsFragment.sWrapContent = PreferenceHelper.getWrapContent(getActivity());
SettingsFragment.sLineNumbers = PreferenceHelper.getLineNumbers(getActivity());
SettingsFragment.sFontSize = PreferenceHelper.getFontSize(getActivity());
SettingsFragment.sSuggestionsActive = PreferenceHelper.getSuggestionActive(getActivity());
SettingsFragment.sLightTheme = PreferenceHelper.getLightTheme(getActivity());
SettingsFragment.sAutoSave = PreferenceHelper.getAutoSave(getActivity());
SettingsFragment.sReadOnly = PreferenceHelper.getReadOnly(getActivity());
SettingsFragment.sSendErrorReports = PreferenceHelper.getReadOnly(getActivity());
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Our custom layout
View rootView = inflater.inflate(R.layout.fragment_settings, container, false);
final CheckBox switchLineNumbers, switchSyntax, switchWrapContent, switchMonospace, switchLightTheme, switchSuggestionsActive, switchAutoSave, switchReadOnly, switchSendErrorReports;
switchLineNumbers = (CheckBox) rootView.findViewById(R.id.switch_line_numbers);
switchSyntax = (CheckBox) rootView.findViewById(R.id.switch_syntax);
switchWrapContent = (CheckBox) rootView.findViewById(R.id.switch_wrap_content);
switchMonospace = (CheckBox) rootView.findViewById(R.id.switch_monospace);
switchLightTheme = (CheckBox) rootView.findViewById(R.id.switch_light_theme);
switchSuggestionsActive = (CheckBox) rootView.findViewById(R.id.switch_suggestions_active);
switchAutoSave = (CheckBox) rootView.findViewById(R.id.switch_auto_save);
switchReadOnly = (CheckBox) rootView.findViewById(R.id.switch_read_only);
switchSendErrorReports = (CheckBox) rootView.findViewById(R.id.switch_send_error_reports);
switchLineNumbers.setChecked(sLineNumbers);
switchSyntax.setChecked(sColorSyntax);
switchWrapContent.setChecked(sWrapContent);
switchMonospace.setChecked(sUseMonospace);
switchLightTheme.setChecked(sLightTheme);
switchSuggestionsActive.setChecked(sSuggestionsActive);
switchAutoSave.setChecked(sAutoSave);
switchReadOnly.setChecked(sReadOnly);
TextView encodingView, fontSizeView, goProView;
encodingView = (TextView) rootView.findViewById(R.id.drawer_button_encoding);
fontSizeView = (TextView) rootView.findViewById(R.id.drawer_button_font_size);
goProView = (TextView) rootView.findViewById(R.id.drawer_button_go_pro);
switchLineNumbers.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
sLineNumbers = isChecked;
PreferenceHelper.setLineNumbers(getActivity(), isChecked);
EventBus.getDefault().post(new APreferenceValueWasChanged(LINE_NUMERS));
}
});
switchSyntax.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
sColorSyntax = isChecked;
PreferenceHelper.setSyntaxHiglight(getActivity(), isChecked);
EventBus.getDefault().post(new APreferenceValueWasChanged(SYNTAX));
}
});
switchWrapContent.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
sWrapContent = isChecked;
PreferenceHelper.setWrapContent(getActivity(), isChecked);
EventBus.getDefault().post(new APreferenceValueWasChanged(WRAP_CONTENT));
}
});
switchMonospace.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
sUseMonospace = isChecked;
PreferenceHelper.setUseMonospace(getActivity(), isChecked);
EventBus.getDefault().post(new APreferenceValueWasChanged(MONOSPACE));
}
});
switchLightTheme.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
sLightTheme = isChecked;
PreferenceHelper.setLightTheme(getActivity(), isChecked);
EventBus.getDefault().post(new APreferenceValueWasChanged(THEME_CHANGE));
}
});
switchSuggestionsActive.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
sSuggestionsActive = isChecked;
PreferenceHelper.setSuggestionActive(getActivity(), isChecked);
EventBus.getDefault().post(new APreferenceValueWasChanged(TEXT_SUGGESTIONS));
}
});
switchAutoSave.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
sAutoSave = isChecked;
PreferenceHelper.setAutoSave(getActivity(), isChecked);
EventBus.getDefault().post(new APreferenceValueWasChanged(AUTO_SAVE));
}
});
switchReadOnly.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
sReadOnly = isChecked;
PreferenceHelper.setReadOnly(getActivity(), isChecked);
EventBus.getDefault().post(new APreferenceValueWasChanged(READ_ONLY));
}
});
switchSendErrorReports.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
sSendErrorReports = isChecked;
PreferenceHelper.setSendErrorReports(getActivity(), isChecked);
}
});
encodingView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
EncodingDialogFragment dialogFrag = EncodingDialogFragment.newInstance();
dialogFrag.setTargetFragment(SettingsFragment.this, 0);
dialogFrag.show(getFragmentManager().beginTransaction(), "dialog");
}
});
fontSizeView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int fontMax = 36;
int fontCurrent = //(int) (mEditor.getTextSize() / scaledDensity);
//fontMax / 2;
PreferenceHelper.getFontSize(getActivity());
SeekbarDialogFragment dialogFrag = SeekbarDialogFragment.newInstance(SeekbarDialogFragment.Actions.FileSize, 1, fontCurrent, fontMax);
dialogFrag.setTargetFragment(SettingsFragment.this, 0);
dialogFrag.show(getFragmentManager().beginTransaction(), "dialog");
}
});
goProView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=com.maskyn.fileeditorpro"))
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
} catch (Exception e) {
}
}
});
goProView.setVisibility(ProCheckUtils.isPro(getActivity()) ? View.GONE : View.VISIBLE);
return rootView;
}
@Override
public void onEncodingSelected(String value) {
PreferenceHelper.setEncoding(getActivity(), value);
EventBus.getDefault().post(new APreferenceValueWasChanged(ENCODING));
}
@Override
public void onSeekbarDialogDismissed(SeekbarDialogFragment.Actions action, int value) {
sFontSize = value;
PreferenceHelper.setFontSize(getActivity(), value);
EventBus.getDefault().post(new APreferenceValueWasChanged(FONT_SIZE));
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p/>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
public void onFragmentInteraction(Uri uri);
}
}

View File

@@ -0,0 +1,138 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Turbo Editor.
*
* Turbo Editor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Turbo Editor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package sharedcode.turboeditor.util;/*
* The Alphanum Algorithm is an improved sorting algorithm for strings
* containing numbers. Instead of sorting numbers in ASCII order like
* a standard sort, this algorithm sorts numbers in numeric order.
*
* The Alphanum Algorithm is discussed at http://www.DaveKoelle.com
*
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
import java.util.Comparator;
/**
* This is an updated version with enhancements made by Daniel Migowski, Andre Bogus, and David
* Koelle
* <p/>
* To convert to use Templates (Java 1.5+): - Change "implements Comparator" to "implements
* Comparator<String>" - Change "compare(Object o1, Object o2)" to "compare(String s1, String s2)" -
* Remove the type checking and casting in compare().
* <p/>
* To use this class: Use the static "sort" method from the java.util.Collections class:
* Collections.sort(your list, new AlphanumComparator());
*/
public class AlphanumComparator implements Comparator {
private boolean isDigit(char ch) {
return ch >= 48 && ch <= 57;
}
/**
* Length of string is passed in for improved efficiency (only need to calculate it once) *
*/
private String getChunk(String s, int slength, int marker) {
StringBuilder chunk = new StringBuilder();
char c = s.charAt(marker);
chunk.append(c);
marker++;
if (isDigit(c)) {
while (marker < slength) {
c = s.charAt(marker);
if (!isDigit(c)) {
break;
}
chunk.append(c);
marker++;
}
} else {
while (marker < slength) {
c = s.charAt(marker);
if (isDigit(c)) {
break;
}
chunk.append(c);
marker++;
}
}
return chunk.toString();
}
public String getTheString(Object obj) {
return (String) obj;
}
public int compare(Object o1, Object o2) {
String s1 = getTheString(o1);
String s2 = getTheString(o2);
int thisMarker = 0;
int thatMarker = 0;
int s1Length = s1.length();
int s2Length = s2.length();
while (thisMarker < s1Length && thatMarker < s2Length) {
String thisChunk = getChunk(s1, s1Length, thisMarker);
thisMarker += thisChunk.length();
String thatChunk = getChunk(s2, s2Length, thatMarker);
thatMarker += thatChunk.length();
// If both chunks contain numeric characters, sort them numerically
int result = 0;
if (isDigit(thisChunk.charAt(0)) && isDigit(thatChunk.charAt(0))) {
// Simple chunk comparison by length.
int thisChunkLength = thisChunk.length();
result = thisChunkLength - thatChunk.length();
// If equal, the first different number counts
if (result == 0) {
for (int i = 0; i < thisChunkLength; i++) {
result = thisChunk.charAt(i) - thatChunk.charAt(i);
if (result != 0) {
return result;
}
}
}
} else {
result = thisChunk.compareTo(thatChunk);
}
if (result != 0) {
return result;
}
}
return s1Length - s2Length;
}
}

View File

@@ -0,0 +1,42 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Turbo Editor.
*
* Turbo Editor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Turbo Editor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package sharedcode.turboeditor.util;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
public class AppInfoHelper {
public static String getApplicationName(final Context context) {
final ApplicationInfo applicationInfo = context.getApplicationInfo();
return context.getString(applicationInfo.labelRes);
}
public static String getCurrentVersion(final Context context) {
try {
final PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(),
0);
return packageInfo.versionName;
} catch (PackageManager.NameNotFoundException e) {
return "";
}
}
}

View File

@@ -0,0 +1,25 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Turbo Editor.
*
* Turbo Editor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Turbo Editor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package sharedcode.turboeditor.util;
public class Constants {
public static final int MAX_FILE_SIZE = 20_000;
public static final boolean FOR_AMAZON = false;
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Turbo Editor.
*
* Turbo Editor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Turbo Editor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package sharedcode.turboeditor.util;
import android.widget.ScrollView;
import sharedcode.turboeditor.views.GoodScrollView;
public interface EditorInterface {
public GoodScrollView getVerticalScrollView();
public String getFilePath();
public PageSystem getPageSystem();
public void updateTextSyntax();
}

View File

@@ -0,0 +1,37 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Turbo Editor.
*
* Turbo Editor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Turbo Editor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package sharedcode.turboeditor.util;
import android.content.Context;
public class EdittextPadding {
public static int getPaddingWithoutLineNumbers(Context context) {
return (int) PixelDipConverter.convertDpToPixel(5, context);
}
public static int getPaddingWithLineNumbers(Context context, float fontSize) {
return (int) PixelDipConverter.convertDpToPixel(fontSize * 1.85f, context);
}
public static int getPaddingTop(Context context) {
return getPaddingWithoutLineNumbers(context);
}
}

View File

@@ -0,0 +1,107 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Turbo Editor.
*
* Turbo Editor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Turbo Editor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package sharedcode.turboeditor.util;
import java.io.File;
public class EventBusEvents {
public static class CannotOpenAFile {
}
public static class NewFileToOpen {
private final File file;
private final String fileText;
public NewFileToOpen(File file) {
this.file = file;
this.fileText = "";
}
public NewFileToOpen(String fileText) {
this.file = new File("");
this.fileText = fileText;
}
public File getFile() {
return file;
}
public String getFileText() {
return fileText;
}
}
public static class AFileIsSelected {
private final String path;
public AFileIsSelected(String path) {
this.path = path;
}
public String getPath() {
return path;
}
}
public static class APreferenceValueWasChanged {
private Type type;
public APreferenceValueWasChanged(Type type) {
this.type = type;
}
public Type getType() {
return type;
}
public void setType(Type type) {
this.type = type;
}
public enum Type {
FONT_SIZE, ENCODING, SYNTAX, WRAP_CONTENT, MONOSPACE, LINE_NUMERS, THEME_CHANGE, TEXT_SUGGESTIONS, AUTO_SAVE, READ_ONLY
}
}
public static class SaveAFile {
}
public static class SavedAFile {
private final String path;
public SavedAFile(String path) {
this.path = path;
}
public String getPath() {
return path;
}
}
public static class ClosedAFile {
}
public static class InvalideTheMenu {
}
}

View File

@@ -0,0 +1,58 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Turbo Editor.
*
* Turbo Editor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Turbo Editor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package sharedcode.turboeditor.util;
import org.mozilla.universalchardet.UniversalDetector;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
public class FileUtils {
public static String getDetectedEncoding(File file) {
InputStream is = null;
String encoding = null;
try {
is = new FileInputStream(file);
UniversalDetector detector = new UniversalDetector(null);
byte[] buf = new byte[4096];
int nread;
while ((nread = is.read(buf)) > 0 && !detector.isDone()) {
detector.handleData(buf, 0, nread);
}
detector.dataEnd();
encoding = detector.getDetectedCharset();
} catch (IOException e) {
// nothing to do
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
if (encoding == null) {
return Charset.defaultCharset().name();
}
}
return encoding;
}
}

View File

@@ -0,0 +1,128 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Turbo Editor.
*
* Turbo Editor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Turbo Editor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package sharedcode.turboeditor.util;
import android.text.Layout;
import android.widget.ScrollView;
public class LineUtils {
private boolean[] toCountLinesArray;
private int[] realLines;
public boolean[] getToCountLinesArray() {
return toCountLinesArray;
}
public int[] getRealLines() {
return realLines;
}
public int getYAtLine(ScrollView scrollView, int lineCount, int line){
return scrollView.getChildAt(0).getHeight() / lineCount * line;
}
public int getFirstVisibleLine(ScrollView scrollView, int lineCount){
return getFirstVisibleLine(scrollView, scrollView.getChildAt(0).getHeight(), lineCount);
}
public int getFirstVisibleLine(ScrollView scrollView, int childHeight, int lineCount) throws ArithmeticException{
int line = (scrollView.getScrollY() * lineCount) / childHeight;
if (line < 0) line = 0;
return line;
}
public int getLastVisibleLine(int firstVisibleLine, int lineCount) {
int line;
line = firstVisibleLine + 150;
if (line > lineCount) line = lineCount;
return line;
}
public void updateHasNewLineArray(int startingLine, int lineCount, Layout layout, String text) {
boolean[] hasNewLineArray = new boolean[lineCount];
toCountLinesArray = new boolean[lineCount];
realLines = new int[lineCount];
int i;
// for every line on the edittext
for (i = 0; i < lineCount; i++) {
// check if this line contains "\n"
hasNewLineArray[i] = text.substring(layout.getLineStart(i), layout.getLineEnd(i)).endsWith("\n");
// if true
if (hasNewLineArray[i]) {
int j = i - 1;
while (j > -1 && !hasNewLineArray[j]) {
j--;
}
toCountLinesArray[j + 1] = true;
}
}
int realLine = startingLine; // the first line is not 0, is 1. We start counting from 1
for (i = 0; i < toCountLinesArray.length; i++) {
if (toCountLinesArray[i]) {
realLine++;
}
realLines[i] = realLine;
}
}
/**
* Gets the line from the index of the letter in the text
* @param index
* @param lineCount
* @param layout
* @return
*/
public int getLineFromIndex(int index, int lineCount, Layout layout) {
int line;
int currentIndex = 0;
for (line = 0; line < lineCount; line++) {
currentIndex += layout.getLineEnd(line) - layout.getLineStart(line);
if (currentIndex > index) {
break;
}
}
return line;
}
public int lastReadLine() {
return realLines[realLines.length-1];
}
public int fakeLineFromRealLine(int realLine) {
int i;
int fakeLine = 0;
for(i = 0; i < realLines.length; i++) {
if (realLine == realLines[i]){
fakeLine = i;
break;
}
}
return fakeLine;
}
}

View File

@@ -0,0 +1,142 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Turbo Editor.
*
* Turbo Editor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Turbo Editor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* 920 Text Editor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* 920 Text Editor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with 920 Text Editor. If not, see <http://www.gnu.org/licenses/>.
*/
package sharedcode.turboeditor.util;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
public class LinuxShell {
public static String getCmdPath(String path) {
return path.replace(" ", "\\ ").replace("'", "\\'");
}
/**
* 返回执行完<E8A18C><E5AE8C>?的结果
*
* @param cmd 命令内容
* @return
*/
public static BufferedReader execute(String cmd) {
BufferedReader reader = null; //errReader = null;
try {
Process process = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(process.getOutputStream());
//os.writeBytes("mount -oremount,rw /dev/block/mtdblock3 /system\n");
//os.writeBytes("busybox cp /data/data/com.koushikdutta.superuser/su /system/bin/su\n");
os.writeBytes(cmd + "\n");
os.writeBytes("exit\n");
reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String err = (new BufferedReader(new InputStreamReader(process.getErrorStream()))).readLine();
os.flush();
if (process.waitFor() != 0 || (!"".equals(err) && null != err)) {
return null;
}
return reader;
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/*public static boolean isRoot()
{
boolean retval = false;
Process suProcess;
try
{
suProcess = Runtime.getRuntime().exec("su");
DataOutputStream os =
new DataOutputStream(suProcess.getOutputStream());
DataInputStream osRes =
new DataInputStream(suProcess.getInputStream());
if (null != os && null != osRes)
{
// Getting the id of the current user to check if this is root
os.writeBytes("id\n");
os.flush();
String currUid = osRes.readLine();
boolean exitSu = false;
if (null == currUid)
{
retval = false;
exitSu = false;
Log.e("ROOT", "Can't get root access or denied by user");
}
else if (true == currUid.contains("uid=0"))
{
retval = true;
exitSu = true;
}
else
{
retval = false;
exitSu = true;
Log.e("ROOT", "Root access rejected: " + currUid);
}
if (exitSu)
{
os.writeBytes("exit\n");
os.flush();
}
}
}
catch (Exception e)
{
// Can't get root !
// Probably broken pipe exception on trying to write to output
// stream after su failed, meaning that the device is not rooted
retval = false;
Log.d("ROOT", "Root access rejected [" +
e.getClass().getName() + "] : " + e.getMessage());
}
return retval;
}*/
}

View File

@@ -0,0 +1,48 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Turbo Editor.
*
* Turbo Editor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Turbo Editor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package sharedcode.turboeditor.util;
public class MimeTypes {
public static final String[] MIME_TEXT = {
"ajx", "am", "asa", "asc", "asp", "aspx", "awk", "bat", "c", "cdf", "cf", "cfg", "cfm", "cgi", "cnf", "conf", "cpp", "css", "csv", "ctl", "dat", "dhtml", "diz", "file", "forward", "grp", "h", "hpp", "hqx", "hta", "htaccess", "htc", "htm", "html", "htpasswd", "htt", "htx", "in", "inc", "info", "ini", "ink", "java", "js", "jsp", "key", "log", "logfile", "m3u", "m4", "m4a", "mak", "map", "model", "msg", "nfo", "nsi", "info", "old", "pas", "patch", "perl", "php", "php2", "php3", "php4", "php5", "php6", "phtml", "pix", "pl", "pm", "po", "pwd", "py", "qmail", "rb", "rbl", "rbw", "readme", "reg", "rss", "rtf", "ruby", "session", "setup", "sh", "shtm", "shtml", "sql", "ssh", "stm", "style", "svg", "tcl", "text", "threads", "tmpl", "tpl", "txt", "ubb", "vbs", "xhtml", "xml", "xrc", "xsl"
};
public static final String[] MIME_CODE = {
"php", "js", "cs", "java", "py", "aspx", "cshtml", "vbhtml", "go", "c", "h", "cpp", "pl", "pm", "t", "pod",
"m", "f", "for", "f90", "f95", "asp", "json", "wiki", "lua"
};
public static final String[] MIME_HTML = {
"htm"
};
public static final String[] MIME_PICTURE = {
"png", "jpeg", "jpg", "ico", "gif", "bmp", "tiff"
};
public static final String[] MIME_MUSIC = {
"mp3", "avi", "flac", "mpga"
};
public static final String[] MIME_VIDEO = {
"mp4", "mkv", "wmw"
};
public static final String[] MIME_ARCHIVE = {
"zip", "tar", "gz", "bz2", "rar", "7z"
};
public static final String[] MIME_SQL = {
"sql", "mdf", "ndf", "ldf"
};
}

View File

@@ -0,0 +1,166 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Turbo Editor.
*
* Turbo Editor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Turbo Editor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package sharedcode.turboeditor.util;
import java.util.LinkedList;
import java.util.List;
public class PageSystem {
public interface PageSystemInterface {
void onPageChanged(int page);
}
private List<String> pages;
private int[] startingLines;
private int currentPage = 0;
private PageSystemInterface pageSystemInterface;
public PageSystem(PageSystemInterface pageSystemInterface, String text) {
this.pageSystemInterface = pageSystemInterface;
pages = new LinkedList<>();
int i = 0;
int charForPage = 15000;
int maxLenghtInOnePage = 30000;
int to;
int indexOfReturn;
int textLenght = text.length();
if(textLenght > maxLenghtInOnePage) {
while (i < textLenght) {
to = i + charForPage;
indexOfReturn = text.indexOf("\n", to);
if (indexOfReturn > to) to = indexOfReturn;
if (to > text.length()) to = text.length();
pages.add(text.substring(i, to));
i = to + 1;
}
if (i == 0)
pages.add("");
} else {
pages.add(text);
}
startingLines = new int[pages.size()];
setStartingLines();
}
public int getStartingLine() {
return startingLines[currentPage];
}
public String getCurrentPageText() {
return pages.get(currentPage);
}
public String getTextOfNextPages(boolean includeCurrent, int nOfPages) {
StringBuilder stringBuilder = new StringBuilder();
int i;
for(i = includeCurrent ? 0 : 1; i < nOfPages; i++){
if(pages.size() > (currentPage + i)) {
stringBuilder.append(pages.get(currentPage + 1));
}
}
return stringBuilder.toString();
}
public void savePage(String currentText) {
pages.set(currentPage, currentText);
}
public void nextPage() {
if(!canReadNextPage()) return;
goToPage(currentPage + 1);
}
public void prevPage() {
if(!canReadPrevPage()) return;
goToPage(currentPage - 1);
}
public void goToPage(int page) {
if(page >= pages.size()) page = pages.size() - 1;
if(page < 0) page = 0;
boolean shouldUpdateLines = page > currentPage && canReadNextPage();
if(shouldUpdateLines) {
String text = getCurrentPageText();
int nOfNewLineNow = (text.length() - text.replace("\n", "").length()) + 1; // normally the last line is not counted so we have to add 1
int nOfNewLineBefore = startingLines[currentPage+1] - startingLines[currentPage];
int difference = nOfNewLineNow - nOfNewLineBefore;
updateStartingLines(currentPage+1, difference);
}
currentPage = page;
pageSystemInterface.onPageChanged(page);
}
public void setStartingLines() {
int i;
int startingLine;
int nOfNewLines;
String text;
startingLines[0] = 0;
for(i = 1; i < pages.size(); i++) {
text = pages.get(i-1);
nOfNewLines = text.length() - text.replace("\n", "").length() + 1;
startingLine = startingLines[i - 1] + nOfNewLines;
startingLines[i] = startingLine;
}
}
public void updateStartingLines(int fromPage, int difference) {
if(difference == 0)
return;
int i;
if(fromPage < 1) fromPage = 1;
for(i = fromPage; i < pages.size(); i++) {
startingLines[i] += difference;
}
}
public int getMaxPage() {
return pages.size() - 1;
}
public int getCurrentPage() { return currentPage; }
public String getAllText(String currentPageText) {
pages.set(currentPage, currentPageText);
int i;
StringBuilder allText = new StringBuilder();
for(i = 0; i < pages.size(); i++) {
allText.append(pages.get(i)).append("\n");
}
return allText.toString();
}
public boolean canReadNextPage() {
return currentPage < pages.size() - 1;
}
public boolean canReadPrevPage() {
return currentPage >= 1;
}
}

View File

@@ -0,0 +1,132 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Turbo Editor.
*
* Turbo Editor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Turbo Editor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package sharedcode.turboeditor.util;
import android.content.Context;
import android.os.Handler;
import android.view.View;
import com.faizmalkani.floatingactionbutton.FloatingActionButton;
import sharedcode.turboeditor.R;
public class PageSystemButtons {
private static final int TIME_TO_SHOW_FABS = 2000;
public interface PageButtonsInterface {
public void nextPageClicked();
public void prevPageClicked();
public void pageSystemButtonLongClicked();
public boolean canReadNextPage();
public boolean canReadPrevPage();
}
FloatingActionButton prev, next;
PageButtonsInterface pageButtonsInterface;
public PageSystemButtons(Context context, final PageButtonsInterface pageButtonsInterface, FloatingActionButton prev, FloatingActionButton next) {
this.prev = prev;
this.next = next;
this.pageButtonsInterface = pageButtonsInterface;
this.next.setColor(context.getResources().getColor(R.color.fab_light));
this.next.setDrawable(context.getResources().getDrawable(R.drawable.ic_keyboard_arrow_right));
this.prev.setColor(context.getResources().getColor(R.color.fab_light));
this.prev.setDrawable(context.getResources().getDrawable(R.drawable.ic_keyboard_arrow_left));
if(pageButtonsInterface.canReadNextPage())
next.setVisibility(View.VISIBLE);
if(pageButtonsInterface.canReadPrevPage())
prev.setVisibility(View.VISIBLE);
this.next.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
pageButtonsInterface.nextPageClicked();
}
});
this.next.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
pageButtonsInterface.pageSystemButtonLongClicked();
return true;
}
});
this.prev.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
pageButtonsInterface.prevPageClicked();
}
});
this.prev.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
pageButtonsInterface.pageSystemButtonLongClicked();
return true;
}
});
}
final Handler handler = new Handler();
final Runnable runnable = new Runnable() {
@Override
public void run() {
PageSystemButtons.this.next.setVisibility(View.GONE);
PageSystemButtons.this.prev.setVisibility(View.GONE);
}
};
public void updateVisibility(boolean autoHide) {
if(pageButtonsInterface.canReadNextPage())
PageSystemButtons.this.next.setVisibility(View.VISIBLE);
else
PageSystemButtons.this.next.setVisibility(View.GONE);
if(pageButtonsInterface.canReadPrevPage())
PageSystemButtons.this.prev.setVisibility(View.VISIBLE);
else
PageSystemButtons.this.prev.setVisibility(View.GONE);
/*if(pageButtonsInterface.hasNext())
next.showFab();
else
next.hideFab();
if(pageButtonsInterface.hasPrev())
prev.showFab();
else
prev.hideFab();*/
if(autoHide) {
handler.removeCallbacks(runnable);
handler.postDelayed(runnable, TIME_TO_SHOW_FABS);
} else {
handler.removeCallbacks(runnable);
}
}
}

View File

@@ -0,0 +1,90 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Turbo Editor.
*
* Turbo Editor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Turbo Editor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package sharedcode.turboeditor.util;
import java.util.regex.Pattern;
public class Patterns {
/*
public static final int COLOR_NUMBER = 0xffff6600;
public static final int COLOR_KEYWORD = 0xff2f6f9f;
public static final int COLOR_ATTR = 0xff4f9fcf;
public static final int COLOR_ATTR_VALUE = 0xffd44950;
public static final int COLOR_STRING = 0xffd44950;
public static final int COLOR_COMMENT = 0xff999999;
*/
// Strings
public static final Pattern GENERAL_STRINGS = Pattern.compile("\"(.*?)\"|'(.*?)'");
public static final Pattern HTML_OPEN_TAGS = Pattern.compile(
"<([A-Za-z][A-Za-z0-9]*)\\b[^>]*>");
public static final Pattern HTML_CLOSE_TAGS = Pattern.compile(
"</([A-Za-z][A-Za-z0-9]*)\\b[^>]*>");
public static final Pattern HTML_ATTRS = Pattern.compile(
"(\\S+)=[\"']?((?:.(?![\"']?\\s+(?:\\S+)=|[>\"']))+.)[\"']?");
//static final Pattern CSS_STYLE_NAME= Pattern.compile(
// "[ \\t\\n\\r\\f](.+?)\\{([^\\)]+)\\}");
public static final Pattern CSS_ATTRS = Pattern.compile(
"(.+?):(.+?);");
public static final Pattern CSS_ATTR_VALUE = Pattern.compile(
":[ \t](.+?);");
public static final Pattern NUMBERS = Pattern.compile(
"\\b(\\d*[.]?\\d+)\\b");
public static final Pattern CSS_NUMBERS = Pattern.compile(
"/^auto$|^[+-]?[0-9]+\\.?([0-9]+)?(px|em|ex|%|in|cm|mm|pt|pc)?$/ig");
public static final Pattern SYMBOLS = Pattern.compile(
"(!|,|\\(|\\)|\\+|\\-|\\*|<|>|=|\\.|\\?|;|\\{|\\}|\\[|\\])");
public static final Pattern GENERAL_KEYWORDS = Pattern.compile(
"\\b(alignas|alignof|and|and_eq|asm|auto|bitand|bitorbool|break|case|catch|char|"
+ "char16_t|char32_t|class|compl|const|constexpr|const_cast|continue|decltype"
+ "|default|delete|do|double|dynamic_cast|echo|else|enum|explicit|export|extern|"
+ "false|float|for|friend|function|goto|if|inline|int|mutable|namespace|new|noexcept|"
+ "not|not_eq|null|nullptr|operator|or|or_eq|private|protected|public|register|"
+ "reinterpret_cast|return|short|signed|sizeof|static|static_assert|static_cast"
+ "|struct|switch|template|this|thread_local|throw|true|try|typedef|typeid|typename|undefined"
+ "|union|unsigned|using|var|virtual|void|volatile|wchar_t|while|xor|xor_eq|)\\b", Pattern.CASE_INSENSITIVE);
public static final Pattern PY_KEYWORDS = Pattern.compile(
"\\b(int|float|long|complex|str|unicode|list|tuple|bytearray|buffer|xrange|set|frozenset|dict|bool)|(True|False|None|self|NotImplemented|Ellipsis|__debug__|__file__)|(and|del|from|not|while|as|elif|global|or|with|assert|else|if|pass|yield|break|except|import|print|class|exec|in|raise|continue|finally|is|return|def|for|lambda|try)|(ArithmeticError|AssertionError|AttributeError|BaseException|DeprecationWarning|EnvironmentError|EOFError|Exception|FloatingPointError|FutureWarning|GeneratorExit|IOError|ImportError|ImportWarning|IndexError|KeyError|KeyboardInterrupt|LookupError|MemoryError|NameError|NotImplementedError|OSError|OverflowError|PendingDeprecationWarning|ReferenceError|RuntimeError|RuntimeWarning|StandardError|StopIteration|SyntaxError|SyntaxWarning|SystemError|SystemExit|TypeError|UnboundLocalError|UserWarning|UnicodeError|UnicodeWarning|UnicodeEncodeError|UnicodeDecodeError|UnicodeTranslateError|ValueError|Warning|WindowsError|ZeroDivisionError)\\b", Pattern.CASE_INSENSITIVE);
public static final Pattern LUA_KEYWORDS = Pattern.compile(
"@[A-Za-z0-9_\\.]*|\\b(local|global|boolean|number|userdata)\\b|\\b(true|false|nil)\\b|\\b(return|then|while|and|break|do|else|elseif|end|for|function|if|in|not|or|repeat|until|thread|table)\\b" +
"|(?i)\\b(editsetText|editText|inkey|touch|system.exit|system.expCall|system.getAppPath|system.getCardMnt|system.getSec|system.impCallActionSend|system.impCallActionView|system.setrun|system.setScreen|system.version|El_Psy_Congroo|canvas.drawCircle|canvas.drawCls|canvas.drawLine|canvas.drawRect|canvas.getBmpSize|canvas.getColor|canvas.getg|canvas.getviewSize|canvas.loadBmp|canvas.putCircle|canvas.putCls|canvas.putflush|canvas.putg|canvas.putLine|canvas.putRect|canvas.putrotg|canvas.putWork|canvas.saveBmp|canvas.setMainBmp|canvas.setWorkBmp|canvas.workCls|canvas.workflush|color|canvas.drawText|canvas.drawTextBox|canvas.drawTextCenter|canvas.drawTextRotate|canvas.putText|canvas.putTextBox|canvas.putTextRotate|http.addHeader|http.addParam|http.clrHeader|http.clrParam|http.get|http.post|http.setContentType|http.setPostFile|http.status|dialog|item.add|item.check|item.clear|item.list|item.radio|toast|sensor.getAccel|sensor.setdevAccel|sensor.setdevMagnet|sensor.setdevOrient|sensor.getGdirection|sensor.getMagnet|sensor.getOrient|sound.beep|sound.isPlay|sound.pause|sound.restart|sound.setSoundFile|sound.start|sound.stop|zip.addFile|zip.exec|zip.status|sock.close|sock.connectOpen|sock.getAddress|sock.listenOpen|sock.recv|sock.send|sprite.clear|sprite.define|sprite.init|sprite.move|sprite.put)\\b" +
"|(?i)\\b(assert|collectgarbage|coroutine.create|coroutine.resume|coroutine.running|coroutine.status|coroutine.wrap|coroutine.yield|debug.debug|debug.getfenv|debug.gethook|debug.getinfo|debug.getlocal|debug.getmetatable|debug.getregistry|debug.getupvalue|debug.setfenv|debug.sethook|debug.setlocal|debug.setmetatable|debug.setupvalue|debug.traceback|dofile|error|file:close|file:flush|file:lines|file:read|file:seek|file:setvbuf|file:write|getfenv|getmetatable|io.close|io.flush|io.input|io.lines|io.open|io.output|io.popen|io.read|io.tmpfile|io.type|io.write|ipairs|load|loadfile|loadstring|math.abs|math.acos|math.asin|math.atan2|math.atan|math.ceil|math.cosh|math.cos|math.deg|math.exp|math.floor|math.fmod|math.frexp|math.ldexp|math.log10|math.log|math.max|math.min|math.modf|math.pow|math.rad|math.random|math.randomseed|math.sinh|math.sin|math.sqrt|math.tanh|math.tan|module|next|os.clock|os.date|os.difftime|os.execute|os.exit|os.getenv|os.remove|os.rename|os.setlocale|os.time|os.tmpname|package.cpath|package.loaded|package.loadlib|package.path|package.preload|package.seeal|pairs|pcall|print|rawequal|rawget|rawset|require|select|setfenv|setmetatable|string.byte|string.char|string.dump|string.find|string.format|string.gmatch|string.gsub|string.len|string.lower|string.match|string.rep|string.reverse|string.sub|string.upper|table.concat|table.insert|table.maxn|table.remove|table.sort|tonumber|tostring|type|unpack|xpcall)\\b"
);
public static final Pattern PHP_VARIABLES = Pattern.compile("\\$\\s*(\\w+)");
// Comments
public static final Pattern XML_COMMENTS = Pattern.compile("(?s)<!--.*?-->");
public static final Pattern GENERAL_COMMENTS = Pattern.compile(
"/\\*(?:.|[\\n\\r])*?\\*/|//.*|#.*");
public static final Pattern GENERAL_COMMENTS_NO_SLASH = Pattern.compile(
"/\\*(?:.|[\\n\\r])*?\\*/|#.*");
public static final Pattern SQL_KEYWORDS = Pattern.compile(
"\\b(ADD|EXCEPT|PERCENT|ALL|EXEC|PLAN|ALTER|EXECUTE|PRECISION|AND|EXISTS|PRIMARY|ANY|EXIT|PRINT|AS|FETCH|PROC|ASC|FILE|PROCEDURE|AUTHORIZATION|FILLFACTOR|PUBLIC|BACKUP|FOR|RAISERROR|BEGIN|FOREIGN|READ|BETWEEN|FREETEXT|READTEXT|BREAK|FREETEXTTABLE|RECONFIGURE|BROWSE|FROM|REFERENCES|BULK|FULL|REPLICATION|BY|FUNCTION|RESTORE|CASCADE|GOTO|RESTRICT|CASE|GRANT|RETURN|CHECK|GROUP|REVOKE|CHECKPOINT|HAVING|RIGHT|CLOSE|HOLDLOCK|ROLLBACK|CLUSTERED|IDENTITY|ROWCOUNT|COALESCE|IDENTITY_INSERT|ROWGUIDCOL|COLLATE|IDENTITYCOL|RULE|COLUMN|IF|SAVE|COMMIT|IN|SCHEMA|COMPUTE|INDEX|SELECT|CONSTRAINT|INNER|SESSION_USER|CONTAINS|INSERT|SET|CONTAINSTABLE|INTERSECT|SETUSER|CONTINUE|INTO|SHUTDOWN|CONVERT|IS|SOME|CREATE|JOIN|STATISTICS|CROSS|KEY|SYSTEM_USER|CURRENT|KILL|TABLE|CURRENT_DATE|LEFT|TEXTSIZE|CURRENT_TIME|LIKE|THEN|CURRENT_TIMESTAMP|LINENO|TO|CURRENT_USER|LOAD|TOP|CURSOR|NATIONAL|TRAN|DATABASE|NOCHECK|TRANSACTION|DBCC|NONCLUSTERED|TRIGGER|DEALLOCATE|NOT|TRUNCATE|DECLARE|NULL|TSEQUAL|DEFAULT|NULLIF|UNION|DELETE|OF|UNIQUE|DENY|OFF|UPDATE|DESC|OFFSETS|UPDATETEXT|DISK|ON|USE|DISTINCT|OPEN|USER|DISTRIBUTED|OPENDATASOURCE|VALUES|DOUBLE|OPENQUERY|VARYING|DROP|OPENROWSET|VIEW|DUMMY|OPENXML|WAITFOR|DUMP|OPTION|WHEN|ELSE|OR|WHERE|END|ORDER|WHILE|ERRLVL|OUTER|WITH|ESCAPE|OVER|WRITETEXT)\\b", Pattern.CASE_INSENSITIVE);
public static final Pattern LINK = android.util.Patterns.WEB_URL;
}

View File

@@ -0,0 +1,56 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Turbo Editor.
*
* Turbo Editor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Turbo Editor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package sharedcode.turboeditor.util;
import android.content.Context;
import android.content.res.Resources;
import android.util.DisplayMetrics;
public final class PixelDipConverter {
private PixelDipConverter() {
}
/**
* This method convets dp unit to equivalent device specific value in pixels.
*
* @param dp A value in dp(Device independent pixels) unit. Which we need to convert into pixels
* @param context Context to get resources and device specific display metrics
* @return A float value to represent Pixels equivalent to dp according to device
*/
public static float convertDpToPixel(final float dp, final Context context) {
final Resources resources = context.getResources();
final DisplayMetrics metrics = resources.getDisplayMetrics();
return dp * metrics.densityDpi / 160f;
}
/**
* This method converts device specific pixels to device independent pixels.
*
* @param px A value in px (pixels) unit. Which we need to convert into db
* @param context Context to get resources and device specific display metrics
* @return A float value to represent db equivalent to px value
*/
public static float convertPixelsToDp(final float px, final Context context) {
final Resources resources = context.getResources();
final DisplayMetrics metrics = resources.getDisplayMetrics();
return px / (metrics.densityDpi / 160f);
}
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Turbo Editor.
*
* Turbo Editor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Turbo Editor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package sharedcode.turboeditor.util;
import android.content.Context;
public class ProCheckUtils {
public static boolean isPro(Context context) {
String packageName = context.getPackageName();
if(Constants.FOR_AMAZON)
return true;
else if(packageName.equals("com.maskyn.fileeditorpro"))
return true;
else
return false;
}
}

View File

@@ -0,0 +1,102 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Turbo Editor.
*
* Turbo Editor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Turbo Editor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* 920 Text Editor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* 920 Text Editor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with 920 Text Editor. If not, see <http://www.gnu.org/licenses/>.
*/
package sharedcode.turboeditor.util;
import android.content.Context;
import org.apache.commons.io.FileUtils;
import org.sufficientlysecure.rootcommands.Shell;
import org.sufficientlysecure.rootcommands.Toolbox;
import java.io.BufferedReader;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
public class RootUtils {
public static void writeFile(Context context, String path, String text, String encoding, boolean isRoot) throws Exception {
File file = new File(path);
if (!file.canWrite() && isRoot) {
File appFolder = context.getFilesDir();
File tempFile = new File(appFolder, "temp.root.file");
if (!tempFile.exists())
tempFile.createNewFile();
FileUtils.write(tempFile, text, encoding);
Shell shell = Shell.startRootShell();
Toolbox tb = new Toolbox(shell);
String mount = tb.getFilePermissions(path);
tb.copyFile(tempFile.getAbsolutePath(), path, true, false);
tb.setFilePermissions(path, mount);
tempFile.delete();
} else {
FileUtils.write(file,
text,
encoding);
}
}
public static ArrayList<File> getFileList(String path, boolean runAtRoot) {
ArrayList<File> filesList = new ArrayList<File>();
if (runAtRoot == false) {
File base = new File(path);
File[] files = base.listFiles();
if (files == null)
return null;
Collections.addAll(filesList, files);
} else {
BufferedReader reader = null; //errReader = null;
try {
reader = LinuxShell.execute("IFS='\n';CURDIR='" + LinuxShell.getCmdPath(path) + "';for i in `ls $CURDIR`; do if [ -d $CURDIR/$i ]; then echo \"d $CURDIR/$i\";else echo \"f $CURDIR/$i\"; fi; done");
if (reader == null)
return null;
File f;
String line;
while ((line = reader.readLine()) != null) {
f = new File(line.substring(2));
filesList.add(f);
}
} catch (Exception e) {
e.printStackTrace();
}
}
return filesList;
}
}

View File

@@ -0,0 +1,106 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Turbo Editor.
*
* Turbo Editor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Turbo Editor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package sharedcode.turboeditor.util;
import android.content.Context;
import android.os.AsyncTask;
import android.widget.Toast;
import sharedcode.turboeditor.R;
import org.sufficientlysecure.rootcommands.Shell;
import org.sufficientlysecure.rootcommands.Toolbox;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import de.greenrobot.event.EventBus;
public class SaveFileTask extends AsyncTask<Void, Void, Void> {
private final Context context;
private final String filePath;
private final String text;
private final String encoding;
private File file;
private String message;
private String positiveMessage;
public SaveFileTask(Context context, String filePath, String text, String encoding) {
this.context = context;
this.filePath = filePath;
this.text = text;
this.encoding = encoding;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
file = new File(filePath);
positiveMessage = String.format(context.getString(R.string.file_saved_with_success), file.getName());
}
/**
* {@inheritDoc}
*/
@Override
protected Void doInBackground(final Void... voids) {
try {
if (!file.exists()) {
file.getParentFile().mkdirs();
file.createNewFile();
}
boolean isRoot = false;
if (!file.canWrite()) {
try {
Shell shell = null;
shell = Shell.startRootShell();
Toolbox tb = new Toolbox(shell);
isRoot = tb.isRootAccessGiven();
} catch (IOException | TimeoutException e) {
e.printStackTrace();
isRoot = false;
}
}
RootUtils.writeFile(context, file.getAbsolutePath(), text, encoding, isRoot);
message = positiveMessage;
} catch (Exception e) {
message = e.getMessage();
}
return null;
}
/**
* {@inheritDoc}
*/
@Override
protected void onPostExecute(final Void aVoid) {
super.onPostExecute(aVoid);
Toast.makeText(context, message, Toast.LENGTH_LONG).show();
if(message.equals(positiveMessage))
EventBus.getDefault().post(new EventBusEvents.SavedAFile(filePath));
}
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Turbo Editor.
*
* Turbo Editor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Turbo Editor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package sharedcode.turboeditor.util;
import java.util.LinkedList;
public class SearchResult {
public LinkedList<Integer> foundIndex;
public int textLength;
public boolean isReplace;
public String textToReplace;
public int index;
public SearchResult(LinkedList<Integer> foundIndex, int textLength, boolean isReplace, String textToReplace) {
this.foundIndex = foundIndex;
this.textLength = textLength;
this.isReplace = isReplace;
this.textToReplace = textToReplace;
}
public void doneReplace() {
foundIndex.remove(index);
int i;
for(i = index; i < foundIndex.size(); i++) {
foundIndex.set(i, foundIndex.get(i) + textToReplace.length() - textLength);
}
index--; // an element was removed so we decrease the index
}
public int numberOfResults() {
return foundIndex.size();
}
}

View File

@@ -0,0 +1,37 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Turbo Editor.
*
* Turbo Editor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Turbo Editor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package sharedcode.turboeditor.util;
import android.app.Activity;
import sharedcode.turboeditor.R;
import sharedcode.turboeditor.preferences.PreferenceHelper;
public class ThemeHelper {
public static void setWindowsBackground(Activity activity) {
boolean whiteTheme = PreferenceHelper.getLightTheme(activity);
if (whiteTheme) {
activity.getWindow().setBackgroundDrawableResource(R.color.window_background_light);
} else {
activity.getWindow().setBackgroundDrawableResource(R.color.window_background);
}
}
}

View File

@@ -0,0 +1,49 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Turbo Editor.
*
* Turbo Editor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Turbo Editor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package sharedcode.turboeditor.views;
import android.content.Context;
import android.support.v4.widget.DrawerLayout;
import android.util.AttributeSet;
import android.view.KeyEvent;
public class CustomDrawerLayout extends DrawerLayout {
public CustomDrawerLayout(Context context) {
super(context);
}
public CustomDrawerLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomDrawerLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
return false;
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
return false;
}
}

View File

@@ -0,0 +1,62 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Turbo Editor.
*
* Turbo Editor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Turbo Editor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package sharedcode.turboeditor.views;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.ScrollView;
public class GoodScrollView extends ScrollView {
public ScrollInterface scrollInterface;
public GoodScrollView(Context context) {
super(context);
}
public GoodScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public GoodScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public interface ScrollInterface {
public void onScrollChanged(int l, int t, int oldl, int oldt);
}
public void setScrollInterface(ScrollInterface scrollInterface) {
this.scrollInterface = scrollInterface;
}
int lastY;
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
if(scrollInterface == null) return;
if(Math.abs(lastY - t) > 50){
lastY = t;
scrollInterface.onScrollChanged(l, t, oldl, oldt);
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 301 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 724 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 621 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 465 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 615 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 531 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 495 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 713 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 644 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 365 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 853 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 898 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 475 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 462 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 291 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 377 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 403 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 535 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 434 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 749 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 692 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 517 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 546 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 353 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 848 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 776 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 597 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 775 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 835 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 677 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 968 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 878 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 433 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 656 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Some files were not shown because too many files have changed in this diff Show More