77 Commits

Author SHA1 Message Date
d9f35737de Rename Turbo-Editor in German language. 2018-06-25 01:31:21 -05:00
f7a95be11b Need to flush/close output stream, else our data won't actually be written. 2018-06-24 20:17:32 -05:00
f08edb736d Swap out rootfw for libsu.
THis compiles but I haven't yet tested it. It won't get merged back in until I test it fully.
2018-06-24 19:43:30 -05:00
05e3600504 Add note that the builds are currently not signed 2018-06-24 18:59:42 -05:00
0b24c89307 Add link to build artifacts 2018-06-24 18:11:25 -05:00
f8491fefdb revert 2018-06-24 16:56:01 -05:00
4885aa9df6 try this out 2018-06-24 16:55:04 -05:00
0dd894a777 add .gitlab-ci.yml 2018-06-24 16:45:13 -05:00
01e7a2674c Remove f-droid text metadata.
This is the format used by f-droid's own metadata repo but they seem to be moving away from it at least for application repos.

see  bca2f86802 (note_50562827)
2018-06-24 05:51:51 -05:00
8838fbd5a9 Correctly format .fdroid.yml. 2018-06-24 05:51:35 -05:00
ddd99e48e5 Add .fdroid.yml 2018-06-24 05:41:57 -05:00
b4da74dea1 Update gradle version in gradle-wrapper 2018-06-24 02:23:40 -05:00
24e7fc5904 Also fix the fdroid metadata file name. 2018-06-24 02:20:37 -05:00
6ef85c45b5 Fix applicationId. 2018-06-24 02:11:42 -05:00
2c55929f9f add google() repository to allprojects 2018-06-24 02:07:25 -05:00
e45665ece1 attempt to update gradle 2018-06-24 01:59:04 -05:00
97f1be558b Add f-droid metadata file.
This is currently for use with the fdroid-docker-build image at https://gitlab.monarch-pass.net/malacoda/fdroid-docker-build. But, once it builds correctly (it does not), it should be able to be pushed to F-droid rather easily.
2018-06-24 01:46:41 -05:00
2ee5a8e904 Hide "View it on the web" option until it can be fixed. 2018-06-23 22:41:54 -05:00
c56b0f8054 Update readme. 2018-06-23 04:14:11 -05:00
7a6d0d3eba Rebrand to Text Editor 8000. 2018-06-23 03:47:51 -05:00
ef533e6e44 Add CSS style to markdown view. 2018-06-23 03:20:15 -05:00
23d09e05c9 Bump minSdkVersion to 15, which is the minimum supported SDK for the markdown library. 2018-06-23 02:07:12 -05:00
a35d95b799 Re-implmenet MarkdownView using the Atlassian commonmark library. 2018-06-23 02:02:00 -05:00
39c7dd956c Swap out markdownview-1.2.jar for commonmark library. 2018-06-23 00:26:36 -05:00
12c539738a Fix line endings of gradlew script. 2018-06-23 00:22:22 -05:00
68e8c4235a Update README.md 2018-02-21 13:05:29 -06:00
b7f84409db Re-introduce some strings that were in the removed turbo-client strings list. 2016-09-25 05:35:04 -05:00
79d6cb6172 Remove ProCheckUtils and dependent code 2016-09-25 05:15:16 -05:00
c1d658ffb1 Reorganize project structure by pulling all of the app code and assets into app project. 2016-09-25 04:54:22 -05:00
a3624e6b2e Remove donation and turbo client strings. 2016-09-25 04:15:57 -05:00
cd20b586f1 oops, this was what I meant to do 2016-09-25 04:04:17 -05:00
02492c8d83 Turbo -> Robut 2016-09-25 04:02:15 -05:00
871b2cfc11 fold app-pro into app as we are not going to have an adware version 2016-09-25 03:55:36 -05:00
401814cb22 fold app-pro into app as we are not going to have an adware version 2016-09-25 03:54:26 -05:00
0269d9c210 Robut Editor officially open for business 2016-09-25 03:51:30 -05:00
46ad99aa46 when shift key is pressed delegate to super implementation so shift key is handled correctly, for certain hardware keyboards this is required so the editor is not stuck in shift mode 2016-09-25 02:09:17 -05:00
9408fba5dd Merge remote-tracking branch 'mitchellgordon95/patch-1' 2016-09-25 01:18:04 -05:00
ebce0bd69b Merge remote-tracking branch 'ldemianiuk/replace-fix' 2016-09-25 01:17:02 -05:00
ce2c2d8b0f Removing generated build stuff 2016-09-25 01:13:45 -05:00
0de5a82cdf Merge remote-tracking branch 'Zerglrisk/master' 2016-09-25 01:12:36 -05:00
69f8f2b0c7 Update gradle wrapper to gradle 2.14 2016-09-25 01:00:52 -05:00
245b9f4230 Pin android gradle plugin to 2.1.2 2016-09-25 00:41:06 -05:00
3db0519ec6 File open Bug Fix & Add Page System's Split By Line Mode 2016-06-21 09:56:29 +09:00
9b7de55f55 Fix Folder open if no file 2016-06-20 22:03:12 +09:00
66a86dc513 Add Folder Open 2016-06-20 18:28:39 +09:00
38123fd510 Support opening .org files
Org (organization) files are common among emacs developers. If you're not familiar with it, it's kind of like markdown. It would be nice to be able to automatically open these.
2016-04-19 11:01:56 -07:00
lde
481fe94eb9 fix replace all 2016-02-01 23:25:59 +01:00
6a965ca560 Update README.md 2015-06-25 15:42:20 +02:00
a1e82b65d4 Version 1.19 2015-03-26 21:26:24 +01:00
e399a217e5 Version 1.18.4 2015-03-25 14:47:22 +01:00
68ad318388 Version 1.18.3 2015-03-23 15:31:39 +01:00
1f3ad1ab12 Version 1.17
Added a markdown viewer and fixed a bug with Copy/Paste/Cut actions
2015-03-15 18:45:18 +01:00
2414192638 Merge remote-tracking branch 'origin/master'
Conflicts:
	build/intermediates/dex-cache/cache.xml
2015-03-15 17:38:46 +01:00
1cd94a5310 Small changes 2015-03-15 17:38:03 +01:00
ce4d1756fb Merge pull request #70 from DF1E/master
remove generated files from repo
2015-03-15 17:36:08 +01:00
3234597537 remove old generated files 2015-03-15 14:07:20 +01:00
5f77e6d7b5 remove generated files from git repo 2015-03-15 14:01:29 +01:00
60395106e5 Version 1.16: Accessory View and Black theme
Accessory View and Black theme
2015-03-15 09:26:28 +01:00
3ee11e0bfb Updated support library 2015-03-14 13:21:11 +01:00
b71d27aeaa Commit 2015-03-14 13:12:23 +01:00
05e4157bed Version 1.15
∙ It is a "beta" release, feel free to send you feedback on github.com!
∙ Added Save As! (and rename option)
∙ Added Replace All!
∙ The default encoding now is UTF-16
∙ Removed donations items, if you want to donate please buy the pro
version!
∙ Minor bug fixes
2015-03-14 13:11:56 +01:00
89673216e8 Small changes 2014-12-11 18:58:22 +01:00
7a86540c60 First mac commit 2014-12-11 18:28:54 +01:00
b359950e34 Fixes 2014-10-31 16:42:35 +01:00
614274c7d6 Happy Halloween! 2014-10-30 20:17:33 +01:00
78407c292a New material things 2014-10-25 14:35:31 +02:00
4d26fa7f3d Updated translations from crowdin 2014-10-18 15:47:54 +02:00
4b16119b53 Version 1.13 2014-10-18 15:20:23 +02:00
bf4dcd51b8 Merge pull request #41 from RyDroid/gitignore
Adding some rules to .gitignore
2014-10-18 15:02:54 +02:00
e52a3cb9f5 Merge pull request #42 from RyDroid/mime-types
Adding and reorganizing a little mime types
2014-10-18 15:02:27 +02:00
5702a6c24f Adding and reorganizing a little mime types 2014-10-18 01:29:07 +02:00
ffcd50616e Adding some rules to .gitignore 2014-10-18 01:25:09 +02:00
46842a5343 Version 1.12 2014-10-12 18:11:19 +02:00
df5a302129 Some fixes 2014-10-07 18:55:18 +02:00
04faa104ed Merge pull request #30 from DF1E/master
update LinuxShell from SimpleExplorer
2014-10-02 19:03:37 +02:00
a20f93f0f6 remove old info from LinuxShell 2014-10-02 18:33:44 +02:00
564e55385f update LinuxShell from SimpleExplorer
https://github.com/DF1E/SimpleExplorer/blob/master/src/com/dnielfe/manager/commands/RootCommands.java
2014-10-02 18:25:12 +02:00
451 changed files with 18642 additions and 22339 deletions

25
.fdroid.yml Normal file
View File

@ -0,0 +1,25 @@
Categories:
- Writing
License: GPL-3.0-or-later
WebSite: https://github.com/adrianmalacoda/text-editor-8000
SourceCode: https://github.com/adrianmalacoda/text-editor-8000
IssueTracker: https://github.com/adrianmalacoda/text-editor-8000/issues
AutoName: Text Editor 8000
Summary: Simple text editor
Description: Simple, yet powerful editor for text files.
RepoType: git
Repo: .
builds:
- versionName: "1.20"
versionCode: 48
commit: HEAD
subdir: app
gradle: yes
AutoUpdateMode: None
UpdateCheckMode: RepoManifest
CurrentVersion: 1.20
CurrentVersion Code: 48

122
.gitignore vendored
View File

@ -1,59 +1,63 @@
# Built application files
*.apk
*.ap_
# Files for the Dalvik VM
*.dex
# Java class files
*.class
# Generated files
bin/
gen/
# Proguard folder generated by Eclipse
proguard/
# Log Files
*.log
# Built application files
/*/build/
# Crashlytics configuations
com_crashlytics_export_strings.xml
crashlytics-build.properties
crashlytics.properties
# Local configuration file (sdk path, etc)
local.properties
# Gradle generated files
.gradle/
# Signing files
.signing/
# User-specific configurations
.idea/libraries/
.idea/workspace.xml
.idea/tasks.xml
.idea/.name
.idea/compiler.xml
.idea/copyright/profiles_settings.xml
.idea/encodings.xml
.idea/misc.xml
.idea/modules.xml
.idea/scopes/scope_settings.xml
.idea/vcs.xml
*.iml
# OS-specific files
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
# Built application files
*.apk
*.ap_
# Files for the Dalvik VM
*.dex
# Java class files
*.class
# Generated files
bin/
gen/
doc/
/build
# Proguard folder generated by Eclipse
proguard/
# Log Files
*.log
# Built application files
/*/build/
# Crashlytics configuations
com_crashlytics_export_strings.xml
crashlytics-build.properties
crashlytics.properties
# Local configuration file (sdk path, etc)
local.properties
# Gradle generated files
.gradle/
# Signing files
.signing/
# User-specific configurations
.idea/libraries/
.idea/workspace.xml
.idea/tasks.xml
.idea/.name
.idea/compiler.xml
.idea/copyright/profiles_settings.xml
.idea/encodings.xml
.idea/misc.xml
.idea/modules.xml
.idea/scopes/scope_settings.xml
.idea/vcs.xml
*.iml
# OS-specific files
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
*~
#*#

9
.gitlab-ci.yml Normal file
View File

@ -0,0 +1,9 @@
image: fdroidbuild:latest
build-apk:
script:
- fdroid build
artifacts:
paths:
- unsigned/*.apk
- unsigned/*.tar.gz

View File

@ -1,9 +0,0 @@
<component name="CopyrightManager">
<copyright>
<option name="notice" value="Copyright (C) 2014 Vlad Mihalachi&#10;&#10;This file is part of Turbo Editor.&#10;&#10;Turbo Editor is free software: you can redistribute it and/or modify&#10;it under the terms of the GNU General Public License as published by&#10;the Free Software Foundation, either version 3 of the License, or&#10;(at your option) any later version.&#10;&#10;Turbo Editor is distributed in the hope that it will be useful,&#10;but WITHOUT ANY WARRANTY; without even the implied warranty of&#10;MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the&#10;GNU General Public License for more details.&#10;&#10;You should have received a copy of the GNU General Public License&#10;along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;." />
<option name="keyword" value="Copyright" />
<option name="allowReplaceKeyword" value="Copyright" />
<option name="myName" value="Copyright Vlad Mihalachi" />
<option name="myLocal" value="true" />
</copyright>
</component>

8
.idea/gradle.xml generated
View File

@ -3,8 +3,9 @@
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="distributionType" value="LOCAL" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleHome" value="C:\Android\android-studio\gradle\gradle-2.10" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
@ -12,12 +13,11 @@
<option value="$PROJECT_DIR$/app-pro" />
<option value="$PROJECT_DIR$/libraries" />
<option value="$PROJECT_DIR$/libraries/FloatingActionButton" />
<option value="$PROJECT_DIR$/libraries/RootCommands" />
<option value="$PROJECT_DIR$/libraries/sharedCode" />
</set>
</option>
<option name="resolveModulePerSourceSet" value="false" />
</GradleProjectSettings>
</option>
</component>
</project>
</project>

View File

@ -1,9 +0,0 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0" is_locked="false">
<option name="myName" value="Project Default" />
<option name="myLocal" value="false" />
<inspection_tool class="AndroidLintMissingQuantity" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="AndroidLintMissingTranslation" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="AndroidLintUnusedQuantity" enabled="false" level="WARNING" enabled_by_default="false" />
</profile>
</component>

View File

@ -1,7 +0,0 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="PROJECT_PROFILE" value="Project Default" />
<option name="USE_PROJECT_PROFILE" value="true" />
<version value="1.0" />
</settings>
</component>

1354
LICENSE

File diff suppressed because it is too large Load Diff

View File

@ -1,60 +1,14 @@
# Turbo Editor
[![Crowdin](https://d322cqt584bo4o.cloudfront.net/turbo-client/localized.png)](https://crowdin.com/project/turbo-client)
Simple, powerful and Open Source text editor for Android licensed under the GPLv3 license.
### Download
[![Play Store](http://developer.android.com/images/brand/en_generic_rgb_wo_60.png)](http://play.google.com/store/apps/details?id=com.maskyn.fileeditorpro)
[![F-Droid](https://lh5.googleusercontent.com/-zezQqsBye0c/VCUpPVjcKEI/AAAAAAAAAIQ/HbcG5f1qMIw/w129-h45-no/getitonfdroid.png)](https://f-droid.org/repository/browse/?fdid=com.maskyn.fileeditorpro)
### Contribute
You can contribute to this project in many ways:
* Browse our issues, comment on proposals, report bugs.
* Help to translate the application on [Crowdin][crowdin]
* Be a part of the Google Plus [Community][community googleplus]
* Discuss with us on [XDA thread][xda thread]
* Help to maintain this project active and [Donate][donate]
------
###Donate
[![Paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_SM.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=26VWS2TSAMUJA)
[![Flattr this git repo](http://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/submit/auto?user_id=vmihalachi&url=https://github.com/vmihalachi/turbo-editor&title=Turbo Editor&language=java&tags=github&category=software)
------
###Images
![](https://lh3.googleusercontent.com/-0GHukwGQPW4/VCUpEhKnZCI/AAAAAAAAAH4/cclI70K79_Q/w347-h520-no/PhoneCustom_7.png)![](https://lh3.googleusercontent.com/-OvazluFl_QQ/VCUo9DAje9I/AAAAAAAAAHQ/i7n1uCpU1hE/w347-h520-no/PhoneCustom_1.png)![](https://lh4.googleusercontent.com/-zh4CYdQPecg/VCUpD3QXpAI/AAAAAAAAAHw/ulL5-V0iJUw/w347-h520-no/PhoneCustom_6.png)![](https://lh4.googleusercontent.com/-LT3k4z9JHo8/VCUo_0jnZRI/AAAAAAAAAHg/Npk9UlkXIV8/w347-h520-no/PhoneCustom_4.png)![](https://lh5.googleusercontent.com/-hXvsf-WYvBs/VCUo9sYfR-I/AAAAAAAAAHY/TTfAgiV_7ko/w347-h520-no/PhoneCustom_3.png)![](https://lh6.googleusercontent.com/-Qib82pK6mZU/VCUpAgYmUdI/AAAAAAAAAHo/zoPVmwcatbQ/w347-h520-no/PhoneCustom_5.png)![](https://lh5.googleusercontent.com/-SERL7X-JHuc/VCax0QSlCGI/AAAAAAAAAJA/hu8dvbvJGBM/w375-h563-no/PhoneCustom_2.png)
------
### Developer
[Vlad Mihalachi][developer site]
------
### A special thanks to..
* [Dumitru Grubii][contributor dumitru grubii] for the icon
* All the translators
* You?
------
### License
Turbo Client is made available under the terms of the [GPLv3][gplv3].
See the [LICENSE][license] file that accompanies this distribution for the full text of the license.
[gplv3]: http://www.gnu.org/licenses/gpl.html
[license]: https://github.com/vmihalachi/turbo-editor/LICENSE
[donate]: https://github.com/vmihalachi/turbo-editor#donate
[donate paypal]: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=PUQXSX6MTXHZ2
[xda thread]: http://forum.xda-developers.com/android/apps-games/app-turbo-editor-text-editor-t2832016
[community googleplus]: https://plus.google.com/u/0/communities/111974095419108178946
[crowdin]: https://crowdin.net/project/turbo-client
[developer site]: http://vmihalachi.com/
[crowdin]: https://crowdin.net/project/turbo-client
[contributor dumitru grubii]: https://twitter.com/DumitruGrubii
[project issues]: https://github.com/vmihalachi/turbo-editor/issues
[project wiki]: https://github.com/vmihalachi/turbo-editor/wiki
# Text Editor 8000
Text editor for Android. Forked from [Turbo Editor](https://github.com/vmihalachi/turbo-editor) by Vlad Mihalachi.
Currently this fork includes a fix for hardware keyboards, as well as an updated [CommonMark](http://commonmark.org/) Markdown renderer.
## Notice
This project undergoes sporadic bursts of activity. There's no timeframe for a release, and stuff gets worked on when it gets worked on.
The general policy is that master is always buildable and should run fine, but there's no guarantees.
Also, [build artifacts](https://gitlab.monarch-pass.net/malacoda/text-editor-8000/-/jobs/artifacts/master/download?job=build-apk) from master are available on the Monarch Pass GitLab. Note that as of now these builds are not signed so you'll need to sign them yourself before installing them. Use at your own risk!
## License
GNU General Public License version 3, see [LICENSE](./license).

View File

@ -1,49 +0,0 @@
/*
* 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/>.
*/
apply plugin: 'com.android.application'
android {
compileSdkVersion 19
buildToolsVersion "19.1.0"
defaultConfig {
applicationId "com.maskyn.fileeditorpro"
minSdkVersion 14
targetSdkVersion 19
versionCode 27
versionName "1.11"
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
buildTypes {
release {
runProguard false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile project(':libraries:sharedCode')
}

View File

@ -1,17 +0,0 @@
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in C:/Users/Vlad/AppData/Local/Android/android-sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

View File

@ -1,139 +0,0 @@
<!--
~ 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="com.maskyn.fileeditorpro"
android:installLocation="auto">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_SUPERUSER" />
<supports-screens
android:anyDensity="true"
android:largeScreens="true"
android:normalScreens="true"
android:resizeable="true"
android:smallScreens="true"
android:xlargeScreens="true" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/nome_app_turbo_editor"
android:hardwareAccelerated="false"
android:largeHeap="true"
android:supportsRtl="true"
>
<!-- android:alwaysRetainTaskState="true" -->
<activity
android:name=".HomeActivity"
android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen"
android:launchMode="singleTop"
android:windowSoftInputMode="stateUnspecified|adjustResize"
android:theme="@style/AppTheme.Light.Editor">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.MULTIWINDOW_LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.EDIT" />
<action android:name="android.intent.action.PICK" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="file" />
<data android:mimeType="text/*" />
<data android:pathPattern="*.txt" />
<data android:pathPattern="*.html" />
<data android:pathPattern="*.css" />
<data android:pathPattern="*.js" />
<data android:pathPattern="*.md"/>
<data android:pathPattern="*.php" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity>
<activity
android:name="sharedcode.turboeditor.activity.PreferenceAbout"
android:configChanges="keyboardHidden|orientation|screenSize"
android:label="@string/info"
android:parentActivityName=".HomeActivity"
android:theme="@style/AppTheme.Dark">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".HomeActivity" />
</activity>
<activity
android:name="sharedcode.turboeditor.activity.LicensesActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:label="@string/open_source_license"
android:parentActivityName="sharedcode.turboeditor.activity.PreferenceAbout"
android:theme="@style/AppTheme.Light">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".PreferenceAbout" />
</activity>
<activity
android:name="sharedcode.turboeditor.activity.SelectFileActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:label="@string/open_a_file"
android:parentActivityName=".HomeActivity"
android:theme="@style/AppTheme.Light">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".HomeActivity" />
</activity>
<activity
android:name="sharedcode.turboeditor.preferences.ExtraSettingsActivity"
android:label="@string/extra_options"
android:parentActivityName=".HomeActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".HomeActivity" />
</activity>
<meta-data
android:name="com.sec.android.support.multiwindow"
android:value="true" />
<meta-data
android:name="com.sec.android.multiwindow.DEFAULT_SIZE_W"
android:value="632.0dip" />
<meta-data
android:name="com.sec.android.multiwindow.DEFAULT_SIZE_H"
android:value="598.0dip" />
<meta-data
android:name="com.sec.android.multiwindow.MINIMUM_SIZE_W"
android:value="632.0dip" />
<meta-data
android:name="com.sec.android.multiwindow.MINIMUM_SIZE_H"
android:value="598.0dip" />
</application>
</manifest>

3
app/.gitignore vendored
View File

@ -1 +1,2 @@
/build
/build
manifest-merger-release-report.txt

View File

@ -1,68 +1,88 @@
/*
* 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/>.
*/
buildscript {
repositories {
maven { url 'http://download.crashlytics.com/maven' }
}
dependencies {
classpath 'com.crashlytics.tools.gradle:crashlytics-gradle:1.+'
}
}
apply plugin: 'com.android.application'
apply plugin: 'crashlytics'
repositories {
maven { url 'http://download.crashlytics.com/maven' }
}
android {
compileSdkVersion 19
buildToolsVersion "19.1.0"
defaultConfig {
applicationId "com.maskyn.fileeditor"
minSdkVersion 14
targetSdkVersion 19
versionCode 27
versionName "1.11"
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
buildTypes {
release {
runProguard false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: '*.jar')
compile project(':libraries:sharedCode')
compile 'com.google.android.gms:play-services:5.0.89'
compile 'com.crashlytics.android:crashlytics:1.+'
}
/*
* Copyright (C) 2016 Adrian Malacoda
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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/>.
*/
import java.util.regex.Pattern
apply plugin: 'com.android.application'
android {
lintOptions {
disable 'MissingTranslation', 'ExtraTranslation'
}
compileSdkVersion 22
buildToolsVersion '22.0.1'
defaultConfig {
applicationId "net.monarchpass.android.texteditor8000"
minSdkVersion 15
targetSdkVersion 22
versionCode 48
versionName "1.20"
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
lintOptions {
abortOnError false
}
packagingOptions {
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/NOTICE.txt'
}
}
dependencies {
compile 'com.github.topjohnwu:libsu:1.2.0'
compile project(':libraries:FloatingActionButton')
compile 'org.apache.commons:commons-lang3:+'
compile 'com.googlecode.juniversalchardet:juniversalchardet:1.0.3'
compile('com.android.support:appcompat-v7:22.+') {
exclude group: 'com.android.support', module: 'support-v4'
}
compile 'com.android.support:support-v4:22.+'
compile 'com.github.gabrielemariotti.changeloglib:library:+'
compile 'commons-io:commons-io:2.4'
compile 'com.android.support:support-annotations:+'
compile 'com.atlassian.commonmark:commonmark:0.11.0'
}
task incrementVersionCode << {
println(":incrementVersionCode - Incrementing Version Code...")
def buildGradleFile = file("build.gradle")
def patternVersionCode = Pattern.compile("versionCode (\\d+)")
def buildGradleFileText = buildGradleFile.getText()
def matcherVersionCode = patternVersionCode.matcher(buildGradleFileText)
matcherVersionCode.find()
def mVersionCode = Integer.parseInt(matcherVersionCode.group(1))
def mNextVersionCode = mVersionCode + 1
def manifestContent = matcherVersionCode.replaceAll("versionCode " + mNextVersionCode)
println(":incrementVersionCode - current versionCode=" + mVersionCode);
println(":incrementVersionCode - next versionCode=" + mNextVersionCode);
buildGradleFile.write(manifestContent)
}

View File

View File

@ -1,17 +1,17 @@
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in C:\Users\Vlad\AppData\Local\Android\android-sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in C:/Users/Vlad/AppData/Local/Android/android-sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

View File

@ -1,32 +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 com.maskyn.fileeditorpro;
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);
}
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro;
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

@ -1,32 +0,0 @@
/*
* 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 com.maskyn.fileeditor;
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

@ -1,147 +1,162 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ 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="com.maskyn.fileeditor"
android:installLocation="auto">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_SUPERUSER" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<supports-screens
android:anyDensity="true"
android:largeScreens="true"
android:normalScreens="true"
android:resizeable="true"
android:smallScreens="true"
android:xlargeScreens="true" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/nome_app_turbo_editor"
android:hardwareAccelerated="false"
android:largeHeap="true"
android:supportsRtl="true"
>
<!-- android:alwaysRetainTaskState="true" -->
<meta-data android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version"/>
<activity
android:name=".HomeActivity"
android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen"
android:launchMode="singleTop"
android:windowSoftInputMode="stateUnspecified|adjustResize"
android:theme="@style/AppTheme.Light.Editor">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.MULTIWINDOW_LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.EDIT" />
<action android:name="android.intent.action.PICK" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="file" />
<data android:mimeType="text/*" />
<data android:pathPattern="*.txt" />
<data android:pathPattern="*.html" />
<data android:pathPattern="*.css" />
<data android:pathPattern="*.js" />
<data android:pathPattern="*.md"/>
<data android:pathPattern="*.php" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity>
<activity
android:name="sharedcode.turboeditor.activity.PreferenceAbout"
android:configChanges="keyboardHidden|orientation|screenSize"
android:label="@string/info"
android:parentActivityName=".HomeActivity"
android:theme="@style/AppTheme.Dark">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".HomeActivity" />
</activity>
<activity
android:name="sharedcode.turboeditor.activity.LicensesActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:label="@string/open_source_license"
android:parentActivityName="sharedcode.turboeditor.activity.PreferenceAbout"
android:theme="@style/AppTheme.Light">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".PreferenceAbout" />
</activity>
<activity
android:name="sharedcode.turboeditor.activity.SelectFileActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:label="@string/open_a_file"
android:parentActivityName=".HomeActivity"
android:theme="@style/AppTheme.Light">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".HomeActivity" />
</activity>
<activity
android:name="sharedcode.turboeditor.preferences.ExtraSettingsActivity"
android:label="@string/extra_options"
android:parentActivityName=".HomeActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".HomeActivity" />
</activity>
<meta-data
android:name="com.sec.android.support.multiwindow"
android:value="true" />
<meta-data
android:name="com.sec.android.multiwindow.DEFAULT_SIZE_W"
android:value="632.0dip" />
<meta-data
android:name="com.sec.android.multiwindow.DEFAULT_SIZE_H"
android:value="598.0dip" />
<meta-data
android:name="com.sec.android.multiwindow.MINIMUM_SIZE_W"
android:value="632.0dip" />
<meta-data
android:name="com.sec.android.multiwindow.MINIMUM_SIZE_H"
android:value="598.0dip" />
<activity android:name="com.google.android.gms.ads.AdActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"/>
<meta-data android:name="com.crashlytics.ApiKey" android:value="672ab7531ce1e2e83c2ec6d84e8e94f2fa692c2a"/>
</application>
</manifest>
<!--
~ Copyright (C) 2014 Vlad Mihalachi
~
~ This file is part of Text Editor 8000.
~
~ Text Editor 8000 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.
~
~ Text Editor 8000 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="com.maskyn.fileeditorpro"
xmlns:tools="http://schemas.android.com/tools"
android:installLocation="auto">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<supports-screens
android:anyDensity="true"
android:largeScreens="true"
android:normalScreens="true"
android:resizeable="true"
android:smallScreens="true"
android:xlargeScreens="true" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/nome_app_turbo_editor"
android:hardwareAccelerated="true"
android:largeHeap="true"
android:supportsRtl="true"
android:name="com.maskyn.fileeditorpro.application.MyApp"
tools:replace="android:label"
>
<!-- android:alwaysRetainTaskState="true" -->
<activity
android:name=".HomeActivity"
android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen"
android:launchMode="singleTop"
android:windowSoftInputMode="stateUnspecified|adjustResize"
android:theme="@style/AppThemeEditorDark">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.MULTIWINDOW_LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="file" />
<data android:mimeType="*/*" />
<data android:host="*" />
<data android:pathPattern=".*\\.txt" />
<data android:pathPattern=".*\\.html" />
<data android:pathPattern=".*\\.xml" />
<data android:pathPattern=".*\\.css" />
<data android:pathPattern=".*\\.js" />
<data android:pathPattern=".*\\.md"/>
<data android:pathPattern=".*\\.markdown"/>
<data android:pathPattern=".*\\.php" />
<data android:pathPattern=".*\\.py" />
<data android:pathPattern=".*\\.script" />
<data android:pathPattern=".*\\.cs" />
<data android:pathPattern=".*\\.java" />
<data android:pathPattern=".*\\.rb" />
<data android:pathPattern=".*\\.aspx" />
<data android:pathPattern=".*\\.cshtml" />
<data android:pathPattern=".*\\.vbhtml" />
<data android:pathPattern=".*\\.go" />
<data android:pathPattern=".*\\.c" />
<data android:pathPattern=".*\\.h" />
<data android:pathPattern=".*\\.cc" />
<data android:pathPattern=".*\\.cpp" />
<data android:pathPattern=".*\\.hh" />
<data android:pathPattern=".*\\.hpp" />
<data android:pathPattern=".*\\.pl" />
<data android:pathPattern=".*\\.pm" />
<data android:pathPattern=".*\\.t" />
<data android:pathPattern=".*\\.pod" />
<data android:pathPattern=".*\\.m" />
<data android:pathPattern=".*\\.f" />
<data android:pathPattern=".*\\.for" />
<data android:pathPattern=".*\\.f90" />
<data android:pathPattern=".*\\.f95" />
<data android:pathPattern=".*\\.asp" />
<data android:pathPattern=".*\\.json" />
<data android:pathPattern=".*\\.wiki" />
<data android:pathPattern=".*\\.lua" />
<data android:pathPattern=".*\\.r" />
<data android:pathPattern=".*\\.key" />
<data android:pathPattern=".*\\.log" />
</intent-filter>
<intent-filter >
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="file" />
<data android:mimeType="text/*" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity>
<activity
android:name="com.maskyn.fileeditorpro.activity.SelectFileActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:label="@string/open_a_file"
android:exported="true"
android:parentActivityName=".HomeActivity"
android:theme="@style/AppThemeBaseLight">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".HomeActivity" />
<intent-filter>
<action android:name="android.intent.action.GET_CONTENT" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.OPENABLE" />
<data android:mimeType="*/*" />
</intent-filter>
</activity>
<meta-data
android:name="com.sec.android.support.multiwindow"
android:value="true" />
<meta-data
android:name="com.sec.android.multiwindow.DEFAULT_SIZE_W"
android:value="632.0dip" />
<meta-data
android:name="com.sec.android.multiwindow.DEFAULT_SIZE_H"
android:value="598.0dip" />
<meta-data
android:name="com.sec.android.multiwindow.MINIMUM_SIZE_W"
android:value="632.0dip" />
<meta-data
android:name="com.sec.android.multiwindow.MINIMUM_SIZE_H"
android:value="598.0dip" />
<activity android:name="com.maskyn.fileeditorpro.activity.MarkdownActivity" />
</application>
</manifest>

View File

@ -0,0 +1,144 @@
/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.vending.billing;
import android.os.Bundle;
/**
* InAppBillingService is the service that provides in-app billing version 3 and beyond.
* This service provides the following features:
* 1. Provides a new API to get details of in-app items published for the app including
* price, type, title and description.
* 2. The purchase flow is synchronous and purchase information is available immediately
* after it completes.
* 3. Purchase information of in-app purchases is maintained within the Google Play system
* till the purchase is consumed.
* 4. An API to consume a purchase of an inapp item. All purchases of one-time
* in-app items are consumable and thereafter can be purchased again.
* 5. An API to get current purchases of the user immediately. This will not contain any
* consumed purchases.
*
* All calls will give a response code with the following possible values
* RESULT_OK = 0 - success
* RESULT_USER_CANCELED = 1 - user pressed back or canceled a dialog
* RESULT_BILLING_UNAVAILABLE = 3 - this billing API version is not supported for the type requested
* RESULT_ITEM_UNAVAILABLE = 4 - requested SKU is not available for purchase
* RESULT_DEVELOPER_ERROR = 5 - invalid arguments provided to the API
* RESULT_ERROR = 6 - Fatal error during the API action
* RESULT_ITEM_ALREADY_OWNED = 7 - Failure to purchase since item is already owned
* RESULT_ITEM_NOT_OWNED = 8 - Failure to consume since item is not owned
*/
interface IInAppBillingService {
/**
* Checks support for the requested billing API version, package and in-app type.
* Minimum API version supported by this interface is 3.
* @param apiVersion the billing version which the app is using
* @param packageName the package name of the calling app
* @param type type of the in-app item being purchased "inapp" for one-time purchases
* and "subs" for subscription.
* @return RESULT_OK(0) on success, corresponding result code on failures
*/
int isBillingSupported(int apiVersion, String packageName, String type);
/**
* Provides details of a list of SKUs
* Given a list of SKUs of a valid type in the skusBundle, this returns a bundle
* with a list JSON strings containing the productId, price, title and description.
* This API can be called with a maximum of 20 SKUs.
* @param apiVersion billing API version that the Third-party is using
* @param packageName the package name of the calling app
* @param skusBundle bundle containing a StringArrayList of SKUs with key "ITEM_ID_LIST"
* @return Bundle containing the following key-value pairs
* "RESPONSE_CODE" with int value, RESULT_OK(0) if success, other response codes on
* failure as listed above.
* "DETAILS_LIST" with a StringArrayList containing purchase information
* in JSON format similar to:
* '{ "productId" : "exampleSku", "type" : "inapp", "price" : "$5.00",
* "title : "Example Title", "description" : "This is an example description" }'
*/
Bundle getSkuDetails(int apiVersion, String packageName, String type, in Bundle skusBundle);
/**
* Returns a pending intent to launch the purchase flow for an in-app item by providing a SKU,
* the type, a unique purchase token and an optional developer payload.
* @param apiVersion billing API version that the app is using
* @param packageName package name of the calling app
* @param sku the SKU of the in-app item as published in the developer console
* @param type the type of the in-app item ("inapp" for one-time purchases
* and "subs" for subscription).
* @param developerPayload optional argument to be sent back with the purchase information
* @return Bundle containing the following key-value pairs
* "RESPONSE_CODE" with int value, RESULT_OK(0) if success, other response codes on
* failure as listed above.
* "BUY_INTENT" - PendingIntent to start the purchase flow
*
* The Pending intent should be launched with startIntentSenderForResult. When purchase flow
* has completed, the onActivityResult() will give a resultCode of OK or CANCELED.
* If the purchase is successful, the result data will contain the following key-value pairs
* "RESPONSE_CODE" with int value, RESULT_OK(0) if success, other response codes on
* failure as listed above.
* "INAPP_PURCHASE_DATA" - String in JSON format similar to
* '{"orderId":"12999763169054705758.1371079406387615",
* "packageName":"com.example.app",
* "productId":"exampleSku",
* "purchaseTime":1345678900000,
* "purchaseToken" : "122333444455555",
* "developerPayload":"example developer payload" }'
* "INAPP_DATA_SIGNATURE" - String containing the signature of the purchase data that
* was signed with the private key of the developer
* TODO: change this to app-specific keys.
*/
Bundle getBuyIntent(int apiVersion, String packageName, String sku, String type,
String developerPayload);
/**
* Returns the current SKUs owned by the user of the type and package name specified along with
* purchase information and a signature of the data to be validated.
* This will return all SKUs that have been purchased in V3 and managed items purchased using
* V1 and V2 that have not been consumed.
* @param apiVersion billing API version that the app is using
* @param packageName package name of the calling app
* @param type the type of the in-app items being requested
* ("inapp" for one-time purchases and "subs" for subscription).
* @param continuationToken to be set as null for the first call, if the number of owned
* skus are too many, a continuationToken is returned in the response bundle.
* This method can be called again with the continuation token to get the next set of
* owned skus.
* @return Bundle containing the following key-value pairs
* "RESPONSE_CODE" with int value, RESULT_OK(0) if success, other response codes on
* failure as listed above.
* "INAPP_PURCHASE_ITEM_LIST" - StringArrayList containing the list of SKUs
* "INAPP_PURCHASE_DATA_LIST" - StringArrayList containing the purchase information
* "INAPP_DATA_SIGNATURE_LIST"- StringArrayList containing the signatures
* of the purchase information
* "INAPP_CONTINUATION_TOKEN" - String containing a continuation token for the
* next set of in-app purchases. Only set if the
* user has more owned skus than the current list.
*/
Bundle getPurchases(int apiVersion, String packageName, String type, String continuationToken);
/**
* Consume the last purchase of the given SKU. This will result in this item being removed
* from all subsequent responses to getPurchases() and allow re-purchase of this item.
* @param apiVersion billing API version that the app is using
* @param packageName package name of the calling app
* @param purchaseToken token in the purchase information JSON that identifies the purchase
* to be consumed
* @return 0 if consumption succeeded. Appropriate error values for failures.
*/
int consumePurchase(int apiVersion, String packageName, String purchaseToken);
}

View File

@ -0,0 +1,112 @@
@charset "utf-8";
/**
* markdown.css
*
* This program 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 3 of the License, or (at your option) any
* later version.
*
* This program 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 program. If not, see http://gnu.org/licenses/lgpl.txt.
*
* @project Weblog and Open Source Projects of Florian Wolters
* @version GIT: $Id$
* @package xhtml-css
* @author Florian Wolters <florian.wolters.85@googlemail.com>
* @copyright 2012 Florian Wolters
* @cssdoc version 1.0-pre
* @license http://gnu.org/licenses/lgpl.txt GNU Lesser General Public License
* @link http://github.com/FlorianWolters/jekyll-bootstrap-theme
* @media all
* @valid true
*/
body {
font-family: Helvetica, Arial, Freesans, clean, sans-serif;
padding:1em;
margin:auto;
max-width:42em;
background:#fefefe;
}
h1, h2, h3, h4, h5, h6 {
font-weight: bold;
}
h1 {
color: #000000;
font-size: 28px;
}
h2 {
border-bottom: 1px solid #CCCCCC;
color: #000000;
font-size: 24px;
}
h3 {
font-size: 18px;
}
h4 {
font-size: 16px;
}
h5 {
font-size: 14px;
}
h6 {
color: #777777;
background-color: inherit;
font-size: 14px;
}
hr {
height: 0.2em;
border: 0;
color: #CCCCCC;
background-color: #CCCCCC;
}
p, blockquote, ul, ol, dl, li, table, pre {
margin: 15px 0;
}
code, pre {
border-radius: 3px;
background-color: #F8F8F8;
color: inherit;
}
code {
border: 1px solid #EAEAEA;
margin: 0 2px;
padding: 0 5px;
}
pre {
border: 1px solid #CCCCCC;
line-height: 1.25em;
overflow: auto;
padding: 6px 10px;
}
pre > code {
border: 0;
margin: 0;
padding: 0;
}
a, a:visited {
color: #4183C4;
background-color: inherit;
text-decoration: none;
}

View File

@ -1,61 +0,0 @@
/*
* 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 com.maskyn.fileeditor;
import android.app.Activity;
import android.preference.PreferenceManager;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.InterstitialAd;
import java.util.Calendar;
import sharedcode.turboeditor.preferences.PreferenceHelper;
public class AdsHelper {
private Activity activity;
private InterstitialAd interstitial;
public AdsHelper(Activity activity) {
this.activity = activity;
interstitial = new InterstitialAd(activity);
interstitial.setAdUnitId("ca-app-pub-5679083452234719/7178038180");
// Create ad request.
AdRequest adRequest = new AdRequest.Builder().build();
// Begin loading your interstitial.
interstitial.loadAd(adRequest);
}
public void displayInterstitial() {
int numberOfAdsRequested = PreferenceHelper.getNumberOfAdsRequested(activity);
numberOfAdsRequested++;
PreferenceHelper.setNumberOfAdsRequested(activity, numberOfAdsRequested);
if (numberOfAdsRequested % 3 == 0 && interstitial != null && interstitial.isLoaded()) {
interstitial.show();
int today = Calendar.getInstance().get(Calendar.DAY_OF_MONTH);
PreferenceHelper.setLastDayAdShowed(activity, today);
}
}
}

View File

@ -1,46 +0,0 @@
/*
* 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 com.maskyn.fileeditor;
import android.os.Bundle;
import com.crashlytics.android.Crashlytics;
import sharedcode.turboeditor.activity.BaseHomeActivity;
import sharedcode.turboeditor.preferences.PreferenceHelper;
public class HomeActivity extends BaseHomeActivity {
private AdsHelper adsHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(PreferenceHelper.getSendErrorReports(this))
Crashlytics.start(this);
// setup the ads
adsHelper = new AdsHelper(this);
}
@Override
public void displayInterstitial() {
adsHelper.displayInterstitial();
}
}

View File

@ -1,32 +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 com.maskyn.fileeditorpro;
import android.os.Bundle;
import sharedcode.turboeditor.activity.BaseHomeActivity;
public class HomeActivity extends BaseHomeActivity {
@Override
public void displayInterstitial() {
// nothing to do here
}
}
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro;
import com.maskyn.fileeditorpro.activity.MainActivity;
public class HomeActivity extends MainActivity {
@Override
public boolean showInterstitial() {
// nothing to do here
return false;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,60 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
* Copyright (C) 2018 Adrian Malacoda
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro.activity;
import android.content.Context;
import android.app.Activity;
import android.os.Bundle;
import android.view.Window;
import android.webkit.WebView;
import org.commonmark.node.Node;
import org.commonmark.parser.Parser;
import org.commonmark.renderer.html.HtmlRenderer;
public class MarkdownActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
MarkdownView webView = new MarkdownView(this);
setContentView(webView);
webView.loadMarkdown(getIntent().getStringExtra("text"), "file:///android_asset/classic_theme_markdown.css");
}
private static class MarkdownView extends WebView {
private static final String CSS_LINK = "<link rel='stylesheet' type='text/css' href='%s'>";
private final Parser parser;
private final HtmlRenderer renderer;
MarkdownView (Context context) {
super(context);
parser = Parser.builder().build();
renderer = HtmlRenderer.builder().build();
}
public void loadMarkdown(String content, String cssUri) {
String html = String.format(CSS_LINK, cssUri);
html = html += renderer.render(parser.parse(content));
loadDataWithBaseURL(null, html, "text/html", null, null);
}
}
}

View File

@ -0,0 +1,468 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro.activity;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.SearchView;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Filter;
import android.widget.ListView;
import android.widget.PopupMenu;
import android.widget.TextView;
import android.widget.Toast;
import com.faizmalkani.floatingactionbutton.FloatingActionButton;
import com.topjohnwu.superuser.io.SuFile;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Comparator;
import java.util.LinkedList;
import com.maskyn.fileeditorpro.R;
import com.maskyn.fileeditorpro.adapter.AdapterDetailedList;
import com.maskyn.fileeditorpro.dialogfragment.EditTextDialog;
import com.maskyn.fileeditorpro.preferences.PreferenceHelper;
import com.maskyn.fileeditorpro.util.AlphanumComparator;
import com.maskyn.fileeditorpro.util.Build;
import com.maskyn.fileeditorpro.util.ThemeUtils;
public class SelectFileActivity extends ActionBarActivity implements SearchView.OnQueryTextListener, AdapterView.OnItemClickListener, EditTextDialog.EditDialogListener {
private String currentFolder;
private ListView listView;
private boolean wantAFile = true;
private MenuItem mSearchViewMenuItem;
private SearchView mSearchView;
private Filter filter;
private int prevposition = 0;
private FloatingActionButton mFab;
private boolean mfabOkMode = false;
private File selectedFile;
private boolean folderOpenMode = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
currentFolder = PreferenceHelper.defaultFolder(this);
ThemeUtils.setTheme(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_select_file);
Toolbar toolbar = (Toolbar) findViewById(R.id.my_awesome_toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
//final Actions action = (Actions) getIntent().getExtras().getSerializable("action");
wantAFile = true; //action == Actions.SelectFile;
mfabOkMode = false;
folderOpenMode = getIntent().getBooleanExtra("foldermode", false);
if(folderOpenMode)
setTitle("Open Folder");
listView = (ListView) findViewById(android.R.id.list);
listView.setOnItemClickListener(this);
listView.setTextFilterEnabled(true);
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) {
if (!mfabOkMode) {
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) {
int i = item.getItemId();
if (i == R.id.im_new_file) {
EditTextDialog.newInstance(EditTextDialog.Actions.NewFile).show(getFragmentManager().beginTransaction(), "dialog");
return true;
} else if (i == R.id.im_new_folder) {
EditTextDialog.newInstance(EditTextDialog.Actions.NewFolder).show(getFragmentManager().beginTransaction(), "dialog");
return true;
} else {
return false;
}
}
});
popup.show();
}
if (mfabOkMode) {
finishWithResult(selectedFile);
}
}
});
mFab.listenTo(listView);
String lastNavigatedPath = PreferenceHelper.getWorkingFolder(this);
File file = new File(lastNavigatedPath);
if (!file.exists()) {
PreferenceHelper.setWorkingFolder(this, PreferenceHelper.defaultFolder(this));
file = new File(PreferenceHelper.defaultFolder(this));
}
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 (filter == null)
return true;
if (TextUtils.isEmpty(newText)) {
filter.filter(null);
} else {
filter.filter(newText);
}
return true;
}
public boolean onQueryTextSubmit(String query) {
return false;
}
/**
* Finish this Activity with a result code and URI of the selected file.
*
* @param file The file selected.
*/
private void finishWithResult(File file) {
if (file != null) {
Uri uri = Uri.fromFile(file);
//Toast.makeText(this, uri.toString(), Toast.LENGTH_SHORT).show();
setResult(RESULT_OK, new Intent().setData(uri));
finish();
} else {
setResult(RESULT_CANCELED);
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());
}
if (mfabOkMode) {
prevposition = 0;
mfabOkMode = false;
mFab.setDrawable(getResources().getDrawable(R.drawable.ic_fab_add));
}
return;
} else if (name.equals(getString(R.string.home))) {
new UpdateList().execute(PreferenceHelper.getWorkingFolder(this));
Toast.makeText(this, "test", Toast.LENGTH_SHORT).show();
if (mfabOkMode) {
prevposition = 0;
mfabOkMode = false;
mFab.setDrawable(getResources().getDrawable(R.drawable.ic_fab_add));
}
return;
}
//final File selectedFile = new File(currentFolder, name);
selectedFile = new File(currentFolder, name);
if (!folderOpenMode) {
if (selectedFile.isFile() && wantAFile) {
if (prevposition == position)
finishWithResult(selectedFile);
else {
prevposition = position;
mfabOkMode = true;
mFab.setDrawable(getResources().getDrawable(R.drawable.ic_fab_ok));
view.setSelected(true);
}
} else if (selectedFile.isDirectory()) {
//Toast.makeText(this, "its folder", Toast.LENGTH_SHORT).show();
if (mfabOkMode) {
prevposition = 0;
mfabOkMode = false;
mFab.setDrawable(getResources().getDrawable(R.drawable.ic_fab_add));
}
new UpdateList().execute(selectedFile.getAbsolutePath());
}
} else if (folderOpenMode) {
if (selectedFile.isDirectory()) {
if (prevposition == position) {
new UpdateList().execute(selectedFile.getAbsolutePath());
if (mfabOkMode) {
prevposition = 0;
mfabOkMode = false;
mFab.setDrawable(getResources().getDrawable(R.drawable.ic_fab_add));
}
} else {
prevposition = position;
mfabOkMode = true;
mFab.setDrawable(getResources().getDrawable(R.drawable.ic_fab_ok));
view.setSelected(true);
}
} else if (selectedFile.isFile()) {
}
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_select_file, menu);
mSearchViewMenuItem = menu.findItem(R.id.im_search);
mSearchView = (SearchView) MenuItemCompat.getActionView(mSearchViewMenuItem);
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_is_working_folder) {
Toast.makeText(getBaseContext(), R.string.is_the_working_folder, Toast.LENGTH_SHORT).show();
return true;
} else if (i == R.id.im_select_folder) {
finishWithResult(new File(currentFolder));
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onEdittextDialogEnded(final String inputText, final String hint, final EditTextDialog.Actions actions) {
if (actions == EditTextDialog.Actions.NewFile && !TextUtils.isEmpty(inputText)) {
File file = new File(currentFolder, inputText);
try {
file.createNewFile();
finishWithResult(file);
} catch (IOException e) {
Toast.makeText(SelectFileActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
}
} else if (actions == EditTextDialog.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);
MenuItemCompat.collapseActionView(mSearchViewMenuItem);
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 tempFolder = new File(path);
if (tempFolder.isFile()) {
tempFolder = tempFolder.getParentFile();
}
String[] unopenableExtensions = {"apk", "mp3", "mp4", "png", "jpg", "jpeg"};
final LinkedList<AdapterDetailedList.FileDetail> fileDetails = new LinkedList<>();
final LinkedList<AdapterDetailedList.FileDetail> folderDetails = new LinkedList<>();
currentFolder = tempFolder.getAbsolutePath();
if (!tempFolder.canRead()) {
SuFile folder = new SuFile(currentFolder);
SuFile[] files = folder.listFiles();
if (files != null) {
for (SuFile file : files) {
if (file.isDirectory()) {
folderDetails.add(new AdapterDetailedList.FileDetail(file.getName(),
getString(R.string.folder),
""));
} else if (!FilenameUtils.isExtension(file.getName().toLowerCase(), unopenableExtensions)
&& file.length() <= Build.MAX_FILE_SIZE * FileUtils.ONE_KB) {
final long fileSize = file.length();
//SimpleDateFormat format = new SimpleDateFormat("MMM dd, yyyy hh:mm a");
//String date = format.format("");
fileDetails.add(new AdapterDetailedList.FileDetail(file.getName(),
FileUtils.byteCountToDisplaySize(fileSize), ""));
}
}
}
} else {
File[] files = tempFolder.listFiles();
Arrays.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) <= Build.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);
filter = mAdapter.getFilter();
}
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

@ -1,204 +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 org.apache.commons.io.FilenameUtils;
import java.util.Arrays;
import java.util.LinkedList;
import sharedcode.turboeditor.R;
import sharedcode.turboeditor.util.MimeTypes;
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();
}
}
}
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro.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 org.apache.commons.io.FilenameUtils;
import java.util.Arrays;
import java.util.LinkedList;
import com.maskyn.fileeditorpro.R;
import com.maskyn.fileeditorpro.util.MimeTypes;
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

@ -1,125 +1,134 @@
/*
* 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 java.io.File;
import java.util.ArrayList;
import sharedcode.turboeditor.R;
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;
}
}
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro.adapter;
import android.content.Context;
import android.graphics.Typeface;
import android.net.Uri;
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 java.util.LinkedList;
import com.maskyn.fileeditorpro.R;
import com.maskyn.fileeditorpro.util.GreatUri;
public class AdapterDrawer extends
ArrayAdapter<GreatUri> {
private final Callbacks callbacks;
// Layout Inflater
private final LayoutInflater inflater;
// List of file details
private final LinkedList<GreatUri> greatUris;
private GreatUri selectedGreatUri = new GreatUri(Uri.EMPTY, "", "");
public AdapterDrawer(Context context,
LinkedList<GreatUri> greatUris,
Callbacks callbacks) {
super(context, R.layout.item_file_list, greatUris);
this.greatUris = greatUris;
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 GreatUri greatUri = greatUris.get(position);
final String fileName = greatUri.getFileName();
hold.nameLabel.setText(fileName);
hold.cancelButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
boolean closeOpenedFile = selectedGreatUri.getUri().equals(greatUri.getUri());
callbacks.CancelItem(position, closeOpenedFile);
if (closeOpenedFile)
selectPosition(new GreatUri(Uri.EMPTY, "", ""));
}
});
if (selectedGreatUri.getUri().equals(greatUri.getUri())) {
hold.nameLabel.setTypeface(null, Typeface.BOLD);
} else {
hold.nameLabel.setTypeface(null, Typeface.NORMAL);
}
} else {
final ViewHolder hold = ((ViewHolder) convertView.getTag());
final GreatUri greatUri = greatUris.get(position);
final String fileName = greatUri.getFileName();
hold.nameLabel.setText(fileName);
hold.cancelButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
boolean closeOpenedFile = selectedGreatUri.getUri().equals(greatUri.getUri());
callbacks.CancelItem(position, closeOpenedFile);
if (closeOpenedFile)
selectPosition(new GreatUri(Uri.EMPTY, "", ""));
}
});
if (selectedGreatUri.getUri().equals(greatUri.getUri())) {
hold.nameLabel.setTypeface(null, Typeface.BOLD);
} else {
hold.nameLabel.setTypeface(null, Typeface.NORMAL);
}
}
return convertView;
}
public void selectPosition(GreatUri greatUri) {
//callbacks.ItemSelected(selectedPath);
this.selectedGreatUri = greatUri;
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,75 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import com.maskyn.fileeditorpro.R;
public class AdapterTwoItem extends
ArrayAdapter<String> {
private final LayoutInflater inflater;
private final String[] lines1;
private final String[] lines2;
public AdapterTwoItem(Context context,
String[] lines1,
String[] lines2) {
super(context, R.layout.item_two_lines, lines1);
this.lines1 = lines1;
this.lines2 = lines2;
this.inflater = LayoutInflater.from(context);
}
@Override
public View getView(final int position,
View convertView, final ViewGroup parent) {
if (convertView == null) {
convertView = this.inflater
.inflate(R.layout.item_two_lines,
parent, false);
final ViewHolder hold = new ViewHolder();
hold.line1 = (TextView) convertView.findViewById(android.R.id.text1);
hold.line2 = (TextView) convertView.findViewById(android.R.id.text2);
convertView.setTag(hold);
hold.line1.setText(lines1[position]);
hold.line2.setText(lines2[position]);
} else {
final ViewHolder hold = ((ViewHolder) convertView.getTag());
hold.line1.setText(lines1[position]);
hold.line2.setText(lines2[position]);
}
return convertView;
}
public static class ViewHolder {
public TextView line1;
public TextView line2;
}
}

View File

@ -0,0 +1,51 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro.application;
import android.app.Application;
import android.view.ViewConfiguration;
import java.lang.reflect.Field;
import com.topjohnwu.superuser.Shell;
public class MyApp extends Shell.ContainerApp {
@Override
public void onCreate() {
super.onCreate();
// Shell initialization
Shell.setFlags(Shell.FLAG_REDIRECT_STDERR);
Shell.verboseLogging(true);
// force to sow the overflow menu icon
try {
ViewConfiguration config = ViewConfiguration.get(this);
Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey");
if (menuKeyField != null) {
menuKeyField.setAccessible(true);
menuKeyField.setBoolean(config, false);
}
} catch (Exception ex) {
// Ignore
}
}
}

View File

@ -0,0 +1,90 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro.dialogfragment;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.os.Bundle;
import android.text.Html;
import android.view.View;
import com.maskyn.fileeditorpro.R;
import com.maskyn.fileeditorpro.views.DialogHelper;
/**
* Dialog fragment that shows some info about this application.
*
* @author Artem Chepurnoy
*/
public class AboutDialog extends DialogFragment {
private static final String VERSION_UNAVAILABLE = "N/A";
/**
* Merges app name and version name into one.
*/
public static CharSequence getVersionName(Context context) {
PackageManager pm = context.getPackageManager();
String packageName = context.getPackageName();
String versionName;
try {
PackageInfo info = pm.getPackageInfo(packageName, 0);
versionName = info.versionName;
// Make the info part of version name a bit smaller.
if (versionName.indexOf('-') >= 0) {
versionName = versionName.replaceFirst("\\-", "<small>-") + "</small>";
}
} catch (PackageManager.NameNotFoundException e) {
versionName = VERSION_UNAVAILABLE;
}
Resources res = context.getResources();
return Html.fromHtml(
res.getString(R.string.about_title,
res.getString(R.string.nome_app_turbo_editor), versionName)
);
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Context context = getActivity();
assert context != null;
CharSequence message = Html.fromHtml(getString(
R.string.about_message));
View view = new DialogHelper.Builder(context)
.setIcon(getResources().getDrawable(R.drawable.ic_launcher))
.setTitle(getVersionName(context))
.setMessage(message)
.createCommonView();
return new AlertDialog.Builder(context)
.setView(view)
.setNeutralButton(R.string.close, null)
.create();
}
}

View File

@ -1,90 +1,69 @@
/*
* 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 it.gmariotti.changelibs.library.view.ChangeLogListView;
import sharedcode.turboeditor.R;
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();
}
}
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro.dialogfragment;
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.os.Bundle;
import android.view.LayoutInflater;
import it.gmariotti.changelibs.library.view.ChangeLogListView;
import com.maskyn.fileeditorpro.R;
public class ChangelogDialog extends DialogFragment {
public static void showChangeLogDialog(FragmentManager fragmentManager) {
ChangelogDialog changelogDialog = new ChangelogDialog();
FragmentTransaction ft = fragmentManager.beginTransaction();
Fragment prev = fragmentManager.findFragmentByTag("changelogdemo_dialog");
if (prev != null) {
ft.remove(prev);
}
ft.addToBackStack(null);
changelogDialog.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();
}
}
)
.create();
}
}

View File

@ -1,128 +1,135 @@
/*
* 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);
}
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro.dialogfragment;
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 com.maskyn.fileeditorpro.R;
import com.maskyn.fileeditorpro.views.DialogHelper;
// ...
public class EditTextDialog extends DialogFragment implements TextView.OnEditorActionListener {
private EditText mEditText;
public static EditTextDialog newInstance(final Actions action) {
return EditTextDialog.newInstance(action, "");
}
public static EditTextDialog newInstance(final Actions action, final String hint) {
final EditTextDialog f = new EditTextDialog();
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 title;
switch (action) {
case NewFile:
title = getString(R.string.file);
break;
case NewFolder:
title = getString(R.string.folder);
break;
case Rename:
title = getString(R.string.rinomina);
break;
default:
title = null;
break;
}
View view = new DialogHelper.Builder(getActivity())
.setTitle(title)
.setView(R.layout.dialog_fragment_edittext)
.createSkeletonView();
this.mEditText = (EditText) view.findViewById(android.R.id.edit);
this.mEditText.setHint(R.string.name);
// 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.onEdittextDialogEnded(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, Rename
}
public interface EditDialogListener {
void onEdittextDialogEnded(String result, String hint, Actions action);
}
}

View File

@ -1,120 +1,122 @@
/*
* 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.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.CompoundButton;
import android.widget.ListView;
import android.widget.Switch;
import org.mozilla.universalchardet.Constants;
import sharedcode.turboeditor.R;
import sharedcode.turboeditor.preferences.PreferenceHelper;
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);
}
}
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro.dialogfragment;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.os.Bundle;
import android.support.v7.widget.SwitchCompat;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.CompoundButton;
import android.widget.ListView;
import org.mozilla.universalchardet.Constants;
import com.maskyn.fileeditorpro.R;
import com.maskyn.fileeditorpro.preferences.PreferenceHelper;
public class EncodingDialog 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,
"ISO-8859-2",
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,
"UTF-16",
Constants.CHARSET_WINDOWS_1251,
Constants.CHARSET_WINDOWS_1252,
Constants.CHARSET_WINDOWS_1253,
Constants.CHARSET_WINDOWS_1255
};
private ListView list;
public static EncodingDialog newInstance() {
final EncodingDialog f = new EncodingDialog();
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);
SwitchCompat autoencoding = (SwitchCompat) 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,105 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro.dialogfragment;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.DialogInterface;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.provider.DocumentFile;
import android.view.View;
import android.widget.ListView;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.util.Date;
import com.maskyn.fileeditorpro.R;
import com.maskyn.fileeditorpro.adapter.AdapterTwoItem;
import com.maskyn.fileeditorpro.util.AccessStorageApi;
import com.maskyn.fileeditorpro.util.Device;
import com.maskyn.fileeditorpro.views.DialogHelper;
// ...
public class FileInfoDialog extends DialogFragment {
public static FileInfoDialog newInstance(Uri uri) {
final FileInfoDialog f = new FileInfoDialog();
final Bundle args = new Bundle();
args.putParcelable("uri", uri);
f.setArguments(args);
return f;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
View view = new DialogHelper.Builder(getActivity())
.setTitle(R.string.info)
.setView(R.layout.dialog_fragment_file_info)
.createSkeletonView();
//final View view = getActivity().getLayoutInflater().inflate(R.layout.dialog_fragment_file_info, null);
ListView list = (ListView) view.findViewById(android.R.id.list);
DocumentFile file = DocumentFile.fromFile(new File(AccessStorageApi.getPath(getActivity(), (Uri) getArguments().getParcelable("uri"))));
if (file == null && Device.hasKitKatApi()) {
file = DocumentFile.fromSingleUri(getActivity(), (Uri) getArguments().getParcelable("uri"));
}
// Get the last modification information.
Long lastModified = file.lastModified();
// Create a new date object and pass last modified information
// to the date object.
Date date = new Date(lastModified);
String[] lines1 = {
getString(R.string.name),
//getString(R.string.folder),
getString(R.string.size),
getString(R.string.modification_date)
};
String[] lines2 = {
file.getName(),
//file.getParent(),
FileUtils.byteCountToDisplaySize(file.length()),
date.toString()
};
list.setAdapter(new AdapterTwoItem(getActivity(), lines1, lines2));
return new AlertDialog.Builder(getActivity())
.setView(view)
.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
}
)
.create();
}
}

View File

@ -1,206 +1,207 @@
/*
* 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 java.util.LinkedList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import sharedcode.turboeditor.R;
import sharedcode.turboeditor.util.SearchResult;
// ...
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();
}
}
public interface SearchDialogInterface {
void onSearchDone(SearchResult searchResult);
}
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();
}
}
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro.dialogfragment;
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 java.util.LinkedList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.maskyn.fileeditorpro.R;
import com.maskyn.fileeditorpro.texteditor.SearchResult;
import com.maskyn.fileeditorpro.views.DialogHelper;
// ...
public class FindTextDialog extends DialogFragment {
private EditText textToFind, textToReplace;
private CheckBox regexCheck, replaceCheck, matchCaseCheck;
public static FindTextDialog newInstance(String allText) {
final FindTextDialog f = new FindTextDialog();
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);
View view = new DialogHelper.Builder(getActivity())
.setTitle(R.string.find)
.setView(R.layout.dialog_fragment_find_text)
.createSkeletonView();
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, null)
.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();
}
}
public interface SearchDialogInterface {
void onSearchDone(SearchResult searchResult);
}
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(), textToFind.getText().toString(), textToReplace.getText().toString(), regexCheck.isChecked());
searchDialogInterface.onSearchDone(searchResult);
}
} else {
}
Toast.makeText(getActivity(), String.format(getString(R.string.occurrences_found), foundIndex.size()), Toast.LENGTH_SHORT).show();
// dismiss the dialog
FindTextDialog.this.dismiss();
}
}
}

View File

@ -0,0 +1,133 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro.dialogfragment;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.DialogInterface;
import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.view.WindowManager;
import android.widget.EditText;
import java.io.File;
import java.io.IOException;
import com.maskyn.fileeditorpro.R;
import com.maskyn.fileeditorpro.activity.MainActivity;
import com.maskyn.fileeditorpro.preferences.PreferenceHelper;
import com.maskyn.fileeditorpro.task.SaveFileTask;
import com.maskyn.fileeditorpro.util.GreatUri;
import com.maskyn.fileeditorpro.views.DialogHelper;
// ...
@SuppressLint("ValidFragment")
public class NewFileDetailsDialog extends DialogFragment {
private EditText mName;
private EditText mFolder;
GreatUri currentUri;
String fileText;
String fileEncoding;
public NewFileDetailsDialog(GreatUri currentUri, String fileText, String fileEncoding) {
this.currentUri = currentUri;
this.fileText = fileText;
this.fileEncoding = fileEncoding;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
View view = new DialogHelper.Builder(getActivity())
.setTitle(R.string.save_as)
.setView(R.layout.dialog_fragment_new_file_details)
.createSkeletonView();
this.mName = (EditText) view.findViewById(android.R.id.text1);
this.mFolder = (EditText) view.findViewById(android.R.id.text2);
boolean noName = TextUtils.isEmpty(currentUri.getFileName());
boolean noPath = TextUtils.isEmpty(currentUri.getFilePath());
if (noName) {
this.mName.setText(".txt");
} else {
this.mName.setText(currentUri.getFileName());
}
if (noPath) {
this.mFolder.setText(PreferenceHelper.getWorkingFolder(getActivity()));
} else {
this.mFolder.setText(currentUri.getParentFolder());
}
// Show soft keyboard automatically
this.mName.requestFocus();
this.mName.setSelection(0);
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());
try {
file.getParentFile().mkdirs();
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
final GreatUri newUri = new GreatUri(Uri.fromFile(file), file.getAbsolutePath(), file.getName());
new SaveFileTask((MainActivity) getActivity(), newUri, fileText, fileEncoding, new SaveFileTask.SaveFileInterface() {
@Override
public void fileSaved(Boolean success) {
if (getActivity() != null) {
((MainActivity) getActivity()).savedAFile(newUri, true);
}
}
}).execute();
}
}
}
)
.setNegativeButton(android.R.string.cancel,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
}
)
.create();
}
}

View File

@ -1,103 +1,123 @@
/*
* 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);
}
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro.dialogfragment;
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 com.maskyn.fileeditorpro.R;
import com.maskyn.fileeditorpro.views.DialogHelper;
// ...
public class NumberPickerDialog extends DialogFragment {
private NumberPicker mSeekBar;
public static NumberPickerDialog newInstance(final Actions action) {
return NumberPickerDialog.newInstance(action, 0, 50, 100);
}
public static NumberPickerDialog newInstance(final Actions action, final int min, final int current, final int max) {
final NumberPickerDialog f = new NumberPickerDialog();
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) {
Actions action = (Actions) getArguments().getSerializable("action");
int title;
switch (action){
case FontSize:
title = R.string.font_size;
break;
case SelectPage:
title = R.string.goto_page;
break;
case GoToLine:
title = R.string.goto_line;
break;
default:
title = R.string.nome_app_turbo_editor;
break;
}
View view = new DialogHelper.Builder(getActivity())
.setTitle(title)
.setView(R.layout.dialog_fragment_seekbar)
.createSkeletonView();
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() {
INumberPickerDialog target = (INumberPickerDialog) getTargetFragment();
if (target == null) {
target = (INumberPickerDialog) getActivity();
}
target.onNumberPickerDialogDismissed(
(Actions) getArguments().getSerializable("action"),
mSeekBar.getValue()
);
this.dismiss();
}
public enum Actions {
FontSize, SelectPage, GoToLine
}
public interface INumberPickerDialog {
void onNumberPickerDialogDismissed(Actions action, int value);
}
}

View File

@ -0,0 +1,120 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro.dialogfragment;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.DialogInterface;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import com.maskyn.fileeditorpro.R;
import com.maskyn.fileeditorpro.activity.MainActivity;
import com.maskyn.fileeditorpro.task.SaveFileTask;
import com.maskyn.fileeditorpro.util.GreatUri;
import com.maskyn.fileeditorpro.views.DialogHelper;
@SuppressLint("ValidFragment")
public class SaveFileDialog extends DialogFragment {
GreatUri uri;
String text;
String encoding;
boolean openNewFileAfter;
GreatUri newUri;
@SuppressLint("ValidFragment")
public SaveFileDialog(GreatUri uri, String text, String encoding) {
this.uri = uri;
this.text = text;
this.encoding = encoding;
this.openNewFileAfter = false;
this.newUri = new GreatUri(Uri.EMPTY, "", "");
}
@SuppressLint("ValidFragment")
public SaveFileDialog(GreatUri uri, String text, String encoding, boolean openNewFileAfter, GreatUri newUri) {
this.uri = uri;
this.text = text;
this.encoding = encoding;
this.openNewFileAfter = openNewFileAfter;
this.newUri = newUri;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
View view = new DialogHelper.Builder(getActivity())
.setIcon(getResources().getDrawable(R.drawable.ic_action_save))
.setTitle(R.string.salva)
.setMessage(String.format(getString(R.string.save_changes), uri.getFileName()))
.createCommonView();
return new AlertDialog.Builder(getActivity())
.setView(view)
.setPositiveButton(R.string.salva,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (uri.getFileName().isEmpty()) {
NewFileDetailsDialog dialogFrag =
new NewFileDetailsDialog(uri,text,
encoding);
dialogFrag.show(getFragmentManager().beginTransaction(),
"dialog");
} else {
new SaveFileTask((MainActivity) getActivity(), uri, text,
encoding, new SaveFileTask.SaveFileInterface() {
@Override
public void fileSaved(Boolean success) {
if (getActivity() != null) {
((MainActivity) getActivity()).savedAFile(uri, true);
}
}
}).execute();
}
}
}
)
.setNeutralButton(android.R.string.cancel, null)
.setNegativeButton(R.string.no,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
ISaveDialog target = (ISaveDialog) getTargetFragment();
if (target == null) {
target = (ISaveDialog) getActivity();
}
target.userDoesntWantToSave(
openNewFileAfter, newUri
);
}
}
)
.create();
}
public interface ISaveDialog {
void userDoesntWantToSave(boolean openNewFile, GreatUri newUri);
}
}

View File

@ -0,0 +1,81 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro.dialogfragment;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import com.maskyn.fileeditorpro.R;
import com.maskyn.fileeditorpro.preferences.PreferenceHelper;
public class ThemeDialog extends DialogFragment implements AdapterView.OnItemClickListener {
private ListView list;
public static ThemeDialog newInstance() {
final ThemeDialog f = new ThemeDialog();
return f;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final View view = getActivity().getLayoutInflater().inflate(R.layout.dialog_theme_list, null);
list = (ListView) view.findViewById(android.R.id.list);
String[] themes = {
getString(R.string.theme_dark), getString(R.string.light_theme), getString(R.string.theme_black)
};
list.setAdapter(new ArrayAdapter<>(getActivity(), R.layout.item_single_choice, themes));
list.setOnItemClickListener(this);
int currentTheme = PreferenceHelper.getTheme(getActivity());
for (int i = 0; i < themes.length; i++) {
if (i == currentTheme)
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.onThemeSelected(position);
this.dismiss();
}
public interface DialogListener {
void onThemeSelected(int result);
}
}

View File

@ -1,14 +1,14 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Turbo Editor.
* This file is part of Text Editor 8000.
*
* Turbo Editor is free software: you can redistribute it and/or modify
* Text Editor 8000 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,
* Text Editor 8000 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.
@ -17,16 +17,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package sharedcode.turboeditor.util;
package com.maskyn.fileeditorpro.preferences;
import sharedcode.turboeditor.views.GoodScrollView;
public interface EditorInterface {
public GoodScrollView getVerticalScrollView();
public String getFilePath();
public PageSystem getPageSystem();
public void updateTextSyntax();
}
public enum PreferenceChangeType {
FONT_SIZE, ENCODING, SYNTAX, WRAP_CONTENT, MONOSPACE, LINE_NUMERS, THEME_CHANGE, TEXT_SUGGESTIONS, READ_ONLY, ACCESSORY_VIEW
}

View File

@ -1,170 +1,242 @@
/*
* 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);
}
public static boolean getIgnoreBackButton(Context context) {
return getPrefs(context).getBoolean("ignore_back_button", false);
}
public static boolean getPageSystemEnabled(Context context) {
return getPrefs(context).getBoolean("page_system_active", true);
}
public static int getNumberOfAdsRequested(Context context) {
return getPrefs(context).getInt("number_of_ads_requested", 0);
}
// 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 setAutoencoding(Context context, boolean value) {
getEditor(context).putBoolean("autoencoding", value).commit();
}
public static void setLastDayAdShowed(Context context, int value) {
getEditor(context).putInt("last_day_ad_showed", 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 setReadOnly(Context context, boolean value) {
getEditor(context).putBoolean("read_only", value).commit();
}
public static void setNumberOfAdsRequested(Context context, int value) {
getEditor(context).putInt("number_of_ads_requested", value).commit();
}
}
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro.preferences;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Environment;
import android.preference.PreferenceManager;
import java.io.File;
import com.maskyn.fileeditorpro.util.Device;
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 getUseAccessoryView(Context context) {
return getPrefs(context).getBoolean("accessory_view", true);
}
public static boolean getUseStorageAccessFramework(Context context) {
return getPrefs(context).getBoolean("storage_access_framework", false);
}
public static boolean getLineNumbers(Context context) {
return getPrefs(context).getBoolean("editor_line_numbers", true);
}
public static boolean getSyntaxHighlight(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 int getTheme(Context context) {
return getPrefs(context).getInt("theme", 0);
}
public static boolean getDarkTheme(Context context) {
return getPrefs(context).getInt("theme", 0) == 0;
}
public static boolean getLightTheme(Context context) {
return getPrefs(context).getInt("theme", 0) == 1;
}
public static boolean getBlackTheme(Context context) {
return getPrefs(context).getInt("theme", 0) == 2;
}
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 String getEncoding(Context context) {
return getPrefs(context).getString("editor_encoding", "UTF-16");
}
public static int getFontSize(Context context) {
return getPrefs(context).getInt("font_size", 16);
}
public static String defaultFolder(Context context) {
String folder;
File externalFolder = context.getExternalFilesDir(null);
if (externalFolder != null && Device.isKitKatApi()) {
folder = externalFolder.getAbsolutePath();
} else {
folder = Environment.getExternalStorageDirectory().getAbsolutePath();
}
//folder = context.getExternalFilesDir(null).getAbsolutePath();
//folder = Environment.getExternalStorageDirectory().getAbsolutePath();
return folder;
}
public static String getWorkingFolder(Context context) {
return getPrefs(context).getString("working_folder2", defaultFolder(context));
}
public static String[] getSavedPaths(Context context) {
return getPrefs(context).getString("savedPaths2", "").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);
}
public static boolean getIgnoreBackButton(Context context) {
return getPrefs(context).getBoolean("ignore_back_button", false);
}
public static boolean getSplitText(Context context) {
return getPrefs(context).getBoolean("page_system_active", true);
}
public static boolean getSplitByLine(Context context){
return getPrefs(context).getBoolean("split_by_line", true);
}
public static boolean hasDonated(Context context) {
return getPrefs(context).getBoolean("has_donated", false);
}
// Setter methods
public static void setUseMonospace(Context context, boolean value) {
getEditor(context).putBoolean("use_monospace", value).commit();
}
public static void setUseAccessoryView(Context context, boolean value) {
getEditor(context).putBoolean("accessory_view", value).commit();
}
public static void setUseStorageAccessFramework(Context context, boolean value) {
getEditor(context).putBoolean("storage_access_framework", value).commit();
}
public static void setLineNumbers(Context context, boolean value) {
getEditor(context).putBoolean("editor_line_numbers", value).commit();
}
public static void setSyntaxHighlight(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 setAutoencoding(Context context, boolean value) {
getEditor(context).putBoolean("autoencoding", 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_folder2", value).commit();
}
public static void setSavedPaths(Context context, StringBuilder stringBuilder) {
getEditor(context).putString("savedPaths2", stringBuilder.toString()).commit();
}
public static void setPageSystemButtonsPopupShown(Context context, boolean value) {
getEditor(context).putBoolean("page_system_button_popup_shown", value).commit();
}
public static void setReadOnly(Context context, boolean value) {
getEditor(context).putBoolean("read_only", value).commit();
}
public static void setHasDonated(Context context, boolean value) {
getEditor(context).putBoolean("has_donated", value).commit();
}
public static void setTheme(Context context, int value) {
getEditor(context).putInt("theme", value).commit();
}
public static void setSuggestionsActive(Context context, boolean value) {
getEditor(context).putBoolean("suggestion_active", value).commit();
}
public static void setAutoSave(Context context, boolean value) {
getEditor(context).putBoolean("auto_save", value).commit();
}
public static void setIgnoreBackButton(Context context, boolean value) {
getEditor(context).putBoolean("ignore_back_button", value).commit();
}
public static void setSplitText(Context context, boolean value) {
getEditor(context).putBoolean("page_system_active", value).commit();
}
public static void setSplitByLine(Context context, boolean value){
getEditor(context).putBoolean("split_by_line",value).commit();
}
public static void setSendErrorReport(Context context, boolean value) {
getEditor(context).putBoolean("send_error_reports", value).commit();
}
public static void setEncoding(Context context, String value) {
getEditor(context).putString("editor_encoding", value).commit();
}
}

View File

@ -0,0 +1,291 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro.preferences;
import android.app.Fragment;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.widget.SwitchCompat;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.TextView;
import com.maskyn.fileeditorpro.R;
import com.maskyn.fileeditorpro.activity.MainActivity;
import com.maskyn.fileeditorpro.dialogfragment.EncodingDialog;
import com.maskyn.fileeditorpro.dialogfragment.NumberPickerDialog;
import com.maskyn.fileeditorpro.dialogfragment.ThemeDialog;
import com.maskyn.fileeditorpro.util.Device;
import com.maskyn.fileeditorpro.util.ViewUtils;
public class SettingsFragment extends Fragment implements NumberPickerDialog.INumberPickerDialog, EncodingDialog.DialogListener, ThemeDialog.DialogListener {
// Editor Variables
private boolean sLineNumbers;
private boolean sColorSyntax;
private boolean sWrapContent;
private boolean sUseMonospace;
private boolean sReadOnly;
private boolean sAccessoryView;
private boolean sStorageAccessFramework;
private boolean sSuggestions;
private boolean sAutoSave;
private boolean sIgnoreBackButton;
private boolean sSplitText;
private boolean sSplitByLine;
private boolean sErrorReports;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Context context = getActivity();
sUseMonospace = PreferenceHelper.getUseMonospace(context);
sColorSyntax = PreferenceHelper.getSyntaxHighlight(context);
sWrapContent = PreferenceHelper.getWrapContent(context);
sLineNumbers = PreferenceHelper.getLineNumbers(context);
sReadOnly = PreferenceHelper.getReadOnly(context);
sAccessoryView = PreferenceHelper.getUseAccessoryView(context);
sStorageAccessFramework = PreferenceHelper.getUseStorageAccessFramework(context);
sSuggestions = PreferenceHelper.getSuggestionActive(context);
sAutoSave = PreferenceHelper.getAutoSave(context);
sIgnoreBackButton = PreferenceHelper.getIgnoreBackButton(context);
sSplitText = PreferenceHelper.getSplitText(context);
sSplitByLine = PreferenceHelper.getSplitByLine(context);
sErrorReports = PreferenceHelper.getSendErrorReports(context);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Our custom layout
final View rootView = inflater.inflate(R.layout.fragment_settings, container, false);
final SwitchCompat swLineNumbers, swSyntax, swWrapContent, swMonospace, swReadOnly;
final SwitchCompat swSuggestions, swAccessoryView, swStorageAccessFramework, swAutoSave, swIgnoreBackButton, swSplitText, swSplitByLine, swErrorReports;
swLineNumbers = (SwitchCompat) rootView.findViewById(R.id.switch_line_numbers);
swSyntax = (SwitchCompat) rootView.findViewById(R.id.switch_syntax);
swWrapContent = (SwitchCompat) rootView.findViewById(R.id.switch_wrap_content);
swMonospace = (SwitchCompat) rootView.findViewById(R.id.switch_monospace);
swReadOnly = (SwitchCompat) rootView.findViewById(R.id.switch_read_only);
swSuggestions = (SwitchCompat) rootView.findViewById(R.id.switch_suggestions_active);
swAccessoryView = (SwitchCompat) rootView.findViewById(R.id.switch_accessory_view);
swStorageAccessFramework = (SwitchCompat) rootView.findViewById(R.id.switch_storage_access_framework);
swAutoSave = (SwitchCompat) rootView.findViewById(R.id.switch_auto_save);
swIgnoreBackButton = (SwitchCompat) rootView.findViewById(R.id.switch_ignore_backbutton);
swSplitText = (SwitchCompat) rootView.findViewById(R.id.switch_page_system);
swSplitByLine = (SwitchCompat) rootView.findViewById(R.id.split_by_line);
swErrorReports = (SwitchCompat) rootView.findViewById(R.id.switch_send_error_reports);
swLineNumbers.setChecked(sLineNumbers);
swSyntax.setChecked(sColorSyntax);
swWrapContent.setChecked(sWrapContent);
swMonospace.setChecked(sUseMonospace);
swReadOnly.setChecked(sReadOnly);
swSuggestions.setChecked(sSuggestions);
swAccessoryView.setChecked(sAccessoryView);
swStorageAccessFramework.setChecked(sStorageAccessFramework);
swAutoSave.setChecked(sAutoSave);
swIgnoreBackButton.setChecked(sIgnoreBackButton);
swSplitText.setChecked(sSplitText);
swSplitByLine.setChecked(sSplitByLine);
swErrorReports.setChecked(sErrorReports);
TextView fontSizeView, encodingView, extraOptionsView, themeView;
fontSizeView = (TextView) rootView.findViewById(R.id.drawer_button_font_size);
encodingView = (TextView) rootView.findViewById(R.id.drawer_button_encoding);
extraOptionsView = (TextView) rootView.findViewById(R.id.drawer_button_extra_options);
themeView = (TextView) rootView.findViewById(R.id.drawer_button_theme);
ViewUtils.setVisible(swStorageAccessFramework, Device.hasKitKatApi());
swLineNumbers.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
PreferenceHelper.setLineNumbers(getActivity(), isChecked);
((MainActivity) getActivity()).aPreferenceValueWasChanged(PreferenceChangeType.LINE_NUMERS);
}
});
swSyntax.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
sColorSyntax = isChecked;
PreferenceHelper.setSyntaxHighlight(getActivity(), isChecked);
((MainActivity) getActivity()).aPreferenceValueWasChanged(PreferenceChangeType.SYNTAX);
}
});
swWrapContent.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
PreferenceHelper.setWrapContent(getActivity(), isChecked);
((MainActivity) getActivity()).aPreferenceValueWasChanged(PreferenceChangeType.WRAP_CONTENT);
}
});
swMonospace.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
sUseMonospace = isChecked;
PreferenceHelper.setUseMonospace(getActivity(), isChecked);
((MainActivity) getActivity()).aPreferenceValueWasChanged(PreferenceChangeType.MONOSPACE);
}
});
swReadOnly.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
PreferenceHelper.setReadOnly(getActivity(), isChecked);
((MainActivity) getActivity()).aPreferenceValueWasChanged(PreferenceChangeType.READ_ONLY);
}
});
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());
NumberPickerDialog dialogFrag = NumberPickerDialog.newInstance(NumberPickerDialog
.Actions
.FontSize, 1, fontCurrent, fontMax);
dialogFrag.setTargetFragment(SettingsFragment.this, 0);
dialogFrag.show(getFragmentManager().beginTransaction(), "dialog");
}
});
encodingView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
EncodingDialog dialogFrag = EncodingDialog.newInstance();
dialogFrag.setTargetFragment(SettingsFragment.this, 0);
dialogFrag.show(getFragmentManager().beginTransaction(), "dialog");
}
});
extraOptionsView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
View otherOptions = rootView.findViewById(R.id.other_options);
boolean isVisible = otherOptions.getVisibility() == View.VISIBLE;
ViewUtils.setVisible(otherOptions, !isVisible);
}
});
themeView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ThemeDialog dialogFrag = ThemeDialog.newInstance();
dialogFrag.setTargetFragment(SettingsFragment.this, 0);
dialogFrag.show(getFragmentManager().beginTransaction(), "dialog");
}
});
swSuggestions.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
PreferenceHelper.setSuggestionsActive(getActivity(), isChecked);
((MainActivity) getActivity()).aPreferenceValueWasChanged(PreferenceChangeType.TEXT_SUGGESTIONS);
}
});
swAccessoryView.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
PreferenceHelper.setUseAccessoryView(getActivity(), isChecked);
((MainActivity) getActivity()).aPreferenceValueWasChanged(PreferenceChangeType.ACCESSORY_VIEW);
}
});
swStorageAccessFramework.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
PreferenceHelper.setUseStorageAccessFramework(getActivity(), isChecked);
}
});
swAutoSave.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
PreferenceHelper.setAutoSave(getActivity(), isChecked);
}
});
swIgnoreBackButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
PreferenceHelper.setIgnoreBackButton(getActivity(), isChecked);
}
});
swSplitText.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
PreferenceHelper.setSplitText(getActivity(), isChecked);
swSplitByLine.setEnabled(isChecked);
}
});
swSplitByLine.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
PreferenceHelper.setSplitByLine(getActivity(), isChecked);
}
});
swErrorReports.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
PreferenceHelper.setSendErrorReport(getActivity(), isChecked);
}
});
return rootView;
}
@Override
public void onNumberPickerDialogDismissed(NumberPickerDialog.Actions action, int value) {
PreferenceHelper.setFontSize(getActivity(), value);
((MainActivity) getActivity()).aPreferenceValueWasChanged(PreferenceChangeType.FONT_SIZE);
}
@Override
public void onEncodingSelected(String result) {
PreferenceHelper.setEncoding(getActivity(), result);
((MainActivity) getActivity()).aPreferenceValueWasChanged(PreferenceChangeType.ENCODING);
}
@Override
public void onThemeSelected(int result) {
PreferenceHelper.setTheme(getActivity(), result);
((MainActivity) getActivity()).aPreferenceValueWasChanged(PreferenceChangeType.THEME_CHANGE);
}
}

View File

@ -0,0 +1,135 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro.task;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.ParcelFileDescriptor;
import android.text.TextUtils;
import android.widget.Toast;
import com.topjohnwu.superuser.io.SuFileOutputStream;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import com.maskyn.fileeditorpro.R;
import com.maskyn.fileeditorpro.activity.MainActivity;
import com.maskyn.fileeditorpro.util.Device;
import com.maskyn.fileeditorpro.util.GreatUri;
import android.util.Log;
public class SaveFileTask extends AsyncTask<Void, Void, Void> {
private final MainActivity activity;
private final GreatUri uri;
private final String newContent;
private final String encoding;
private String message;
private String positiveMessage, negativeMessage;
private SaveFileInterface mCompletionHandler;
public SaveFileTask(MainActivity activity, GreatUri uri, String newContent, String encoding, SaveFileInterface mCompletionHandler) {
this.activity = activity;
this.uri = uri;
this.newContent = newContent;
this.encoding = encoding;
this.mCompletionHandler = mCompletionHandler;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
positiveMessage = String.format(activity.getString(R.string.file_saved_with_success), uri.getFileName());
negativeMessage = activity.getString(R.string.err_occured);
}
/**
* {@inheritDoc}
*/
@Override
protected Void doInBackground(final Void... voids) {
boolean isRootNeeded = false;
try {
String filePath = uri.getFilePath();
// if the uri has no path
if (TextUtils.isEmpty(filePath)) {
writeUri(uri.getUri(), newContent, encoding);
} else {
isRootNeeded = !uri.isWritable();
if (isRootNeeded == false) {
if (Device.hasKitKatApi())
writeUri(uri.getUri(), newContent, encoding);
else {
FileUtils.write(new java.io.File(filePath),
newContent,
encoding);
}
}
// if we can read the file associated with the uri
else {
SuFileOutputStream out = new SuFileOutputStream(uri.getFilePath());
IOUtils.write(newContent, out, encoding);
out.close();
}
}
message = positiveMessage;
} catch (Exception e) {
e.printStackTrace();
message = e.getMessage();
}
return null;
}
private void writeUri(Uri uri, String newContent, String encoding) throws IOException {
ParcelFileDescriptor pfd = activity.getContentResolver().openFileDescriptor(uri, "w");
FileOutputStream fileOutputStream = new FileOutputStream(pfd.getFileDescriptor());
fileOutputStream.write(newContent.getBytes(Charset.forName(encoding)));
fileOutputStream.close();
pfd.close();
}
/**
* {@inheritDoc}
*/
@Override
protected void onPostExecute(final Void aVoid) {
super.onPostExecute(aVoid);
Toast.makeText(activity, message, Toast.LENGTH_LONG).show();
/*android.content.ClipboardManager clipboard = (android.content.ClipboardManager) activity.getSystemService(Context.CLIPBOARD_SERVICE);
android.content.ClipData clip = android.content.ClipData.newPlainText("Clip",message);
clipboard.setPrimaryClip(clip);*/
if (mCompletionHandler != null)
mCompletionHandler.fileSaved(message.equals(positiveMessage));
}
public interface SaveFileInterface {
void fileSaved(Boolean success);
}
}

View File

@ -1,37 +1,45 @@
/*
* 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);
}
}
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro.texteditor;
import android.content.Context;
import com.maskyn.fileeditorpro.preferences.PreferenceHelper;
import com.maskyn.fileeditorpro.util.PixelDipConverter;
public class EditTextPadding {
public static int getPaddingWithoutLineNumbers(Context context) {
return (int) PixelDipConverter.convertDpToPixel(5, context);
}
public static int getPaddingBottom(Context context) {
boolean useAccessoryView = PreferenceHelper.getUseAccessoryView(context);
return (int) PixelDipConverter.convertDpToPixel(useAccessoryView ? 50 : 0, context);
}
public static int getPaddingWithLineNumbers(Context context, float fontSize) {
return (int) PixelDipConverter.convertDpToPixel(fontSize * 2f, context);
}
public static int getPaddingTop(Context context) {
return getPaddingWithoutLineNumbers(context);
}
}

View File

@ -1,58 +1,61 @@
/*
* 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;
}
}
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro.texteditor;
import org.mozilla.universalchardet.UniversalDetector;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
public class FileUtils {
public static String getDetectedEncoding(InputStream is) {
String encoding = null;
try {
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;
}
public static String getDetectedEncoding(File file) throws FileNotFoundException {
return getDetectedEncoding(new FileInputStream(file));
}
}

View File

@ -1,127 +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;
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(ScrollView scrollView, int childHeight, int lineCount, int deviceHeight) {
int line = ((scrollView.getScrollY() + deviceHeight) * lineCount) / childHeight;
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;
}
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro.texteditor;
import android.text.Layout;
import android.text.TextUtils;
import android.widget.ScrollView;
public class LineUtils {
private boolean[] toCountLinesArray;
private int[] realLines;
public boolean[] getGoodLines() {
return toCountLinesArray;
}
public int[] getRealLines() {
return realLines;
}
public static int getYAtLine(ScrollView scrollView, int lineCount, int line) {
return scrollView.getChildAt(0).getHeight() / lineCount * line;
}
public static int getFirstVisibleLine(ScrollView scrollView, int childHeight, int lineCount) throws ArithmeticException {
int line = (scrollView.getScrollY() * lineCount) / childHeight;
if (line < 0) line = 0;
return line;
}
public static int getLastVisibleLine(ScrollView scrollView, int childHeight, int lineCount, int deviceHeight) {
int line = ((scrollView.getScrollY() + deviceHeight) * lineCount) / childHeight;
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];
if(TextUtils.isEmpty(text)) {
toCountLinesArray[0] = false;
realLines[0] = 1;
return;
}
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");
hasNewLineArray[i] = text.charAt(layout.getLineEnd(i) - 1) == '\n';
// if true
if (hasNewLineArray[i]) {
int j = i - 1;
while (j > -1 && !hasNewLineArray[j]) {
j--;
}
toCountLinesArray[j + 1] = true;
}
}
toCountLinesArray[lineCount-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 static 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 firstReadLine() {
return realLines[0];
}
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

@ -1,170 +1,203 @@
/*
* 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 java.util.LinkedList;
import java.util.List;
import sharedcode.turboeditor.preferences.PreferenceHelper;
public class PageSystem {
private List<String> pages;
private int[] startingLines;
private int currentPage = 0;
private PageSystemInterface pageSystemInterface;
public PageSystem(Context context, 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();
boolean pageSystemEnabled = PreferenceHelper.getPageSystemEnabled(context);
if (pageSystemEnabled && textLenght > maxLenghtInOnePage) {
while (i < textLenght && pageSystemEnabled) {
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;
}
public interface PageSystemInterface {
void onPageChanged(int page);
}
}
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro.texteditor;
import android.content.Context;
import java.util.LinkedList;
import java.util.List;
import com.maskyn.fileeditorpro.preferences.PreferenceHelper;
public class PageSystem {
private List<String> pages;
private int[] startingLines;
private int currentPage = 0;
private PageSystemInterface pageSystemInterface;
public PageSystem(Context context, PageSystemInterface pageSystemInterface, String text) {
final int charForPage = 20000;
final int firstPageChars = 50000;
final int lineForPage = 250;
this.pageSystemInterface = pageSystemInterface;
pages = new LinkedList<>();
int i = 0;
int to;
int nextIndexOfReturn;
final int textLength = text.length();
boolean pageSystemEnabled = PreferenceHelper.getSplitText(context);
boolean splitByLineEnablec = PreferenceHelper.getSplitByLine(context);
if (pageSystemEnabled && !splitByLineEnablec) {
while (i < textLength) {
// first page is longer
to = i + (i == 0 ? firstPageChars : charForPage);
nextIndexOfReturn = text.indexOf("\n", to);
if (nextIndexOfReturn > to) to = nextIndexOfReturn;
if (to > text.length()) to = text.length();
pages.add(text.substring(i, to));
i = to + 1;
}
if (i == 0)
pages.add("");
} else if(pageSystemEnabled && splitByLineEnablec){
int linecount = 0;
to = 0;
while (i < textLength) {
// first page is longer
nextIndexOfReturn = text.indexOf("\n", to);
if (nextIndexOfReturn > to) {
to = nextIndexOfReturn;
linecount++;
}
if (to > text.length()) {
to = text.length();
pages.add(text.substring(i, to));
i = to;
}
if (linecount >= lineForPage) {
pages.add(text.substring(i, to));
i = to;
linecount = 0;
}
to++;
}
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));
if(i < pages.size() - 1)
allText.append("\n");
}
return allText.toString();
}
public boolean canReadNextPage() {
return currentPage < pages.size() - 1;
}
public boolean canReadPrevPage() {
return currentPage >= 1;
}
public interface PageSystemInterface {
void onPageChanged(int page);
}
}

View File

@ -1,134 +1,134 @@
/*
* 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;
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);
}
};
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;
}
});
}
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);
}
}
public interface PageButtonsInterface {
public void nextPageClicked();
public void prevPageClicked();
public void pageSystemButtonLongClicked();
public boolean canReadNextPage();
public boolean canReadPrevPage();
}
}
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro.texteditor;
import android.content.Context;
import android.os.Handler;
import android.view.View;
import com.faizmalkani.floatingactionbutton.FloatingActionButton;
import com.maskyn.fileeditorpro.R;
public class PageSystemButtons {
private static final int TIME_TO_SHOW_FABS = 2000;
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);
}
};
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;
}
});
}
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);
}
}
public interface PageButtonsInterface {
public void nextPageClicked();
public void prevPageClicked();
public void pageSystemButtonLongClicked();
public boolean canReadNextPage();
public boolean canReadPrevPage();
}
}

View File

@ -1,90 +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.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;
}
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro.texteditor;
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_TAGS = Pattern.compile(
"<([A-Za-z][A-Za-z0-9]*)\\b[^>]*>|</([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 NUMBERS_OR_SYMBOLS = Pattern.compile(NUMBERS.pattern()+"|"+SYMBOLS.pattern());
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])*?\\*/|(?<!:)//.*|#.*");
// same as GENERAL_COMMENTS but without -> //
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

@ -1,50 +1,68 @@
/*
* 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();
}
}
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro.texteditor;
import java.util.LinkedList;
public class SearchResult {
// list of index
public LinkedList<Integer> foundIndex;
public int textLength;
public boolean isReplace;
public String textToReplace;
public int index;
public String whatToSearch;
public boolean isRegex;
public SearchResult(LinkedList<Integer> foundIndex, int textLength, boolean isReplace, String whatToSearch, String textToReplace, boolean isRegex) {
this.foundIndex = foundIndex;
this.textLength = textLength;
this.isReplace = isReplace;
this.whatToSearch = whatToSearch;
this.textToReplace = textToReplace;
this.isRegex = isRegex;
}
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();
}
public boolean hasNext() {
return index < foundIndex.size() - 1;
}
public boolean hasPrevious() {
return index > 0;
}
public boolean canReplaceSomething() {
return isReplace && foundIndex.size() > 0;
}
}

View File

@ -0,0 +1,266 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro.util;
import android.annotation.SuppressLint;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import org.apache.commons.io.FilenameUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class AccessStorageApi {
public static Bitmap loadPrescaledBitmap(String filename) throws IOException {
// Facebook image size
final int IMAGE_MAX_SIZE = 630;
File file = null;
FileInputStream fis;
BitmapFactory.Options opts;
int resizeScale;
Bitmap bmp;
file = new File(filename);
// This bit determines only the width/height of the bitmap without loading the contents
opts = new BitmapFactory.Options();
opts.inJustDecodeBounds = true;
fis = new FileInputStream(file);
BitmapFactory.decodeStream(fis, null, opts);
fis.close();
// Find the correct scale value. It should be a power of 2
resizeScale = 1;
if (opts.outHeight > IMAGE_MAX_SIZE || opts.outWidth > IMAGE_MAX_SIZE) {
resizeScale = (int) Math.pow(2, (int) Math.round(Math.log(IMAGE_MAX_SIZE / (double) Math.max(opts.outHeight, opts.outWidth)) / Math.log(0.5)));
}
// Load pre-scaled bitmap
opts = new BitmapFactory.Options();
opts.inSampleSize = resizeScale;
fis = new FileInputStream(file);
bmp = BitmapFactory.decodeStream(fis, null, opts);
fis.close();
return bmp;
}
/**
* Get a file path from a Uri. This will get the the path for Storage Access
* Framework Documents, as well as the _data field for the MediaStore and
* other file-based ContentProviders.
*
* @param context The context.
* @param uri The Uri to query.
* @author paulburke
*/
@SuppressLint("NewApi")
public static String getPath(final Context context, final Uri uri) {
String path = "";
if (uri == null || uri.equals(Uri.EMPTY))
return "";
try {
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
// DocumentProvider
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
if (isTurboDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
path = "/" + split[1];
}
// ExternalStorageProvider
else if (isExternalStorageDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
if ("primary".equalsIgnoreCase(type)) {
path = Environment.getExternalStorageDirectory() + "/" + split[1];
}
// TODO handle non-primary volumes
}
// DownloadsProvider
else if (isDownloadsDocument(uri)) {
final String id = DocumentsContract.getDocumentId(uri);
final Uri contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
path = getDataColumn(context, contentUri, null, null);
}
// MediaProvider
else if (isMediaDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
Uri contentUri = null;
if ("image".equals(type)) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if ("audio".equals(type)) {
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
final String selection = "_id=?";
final String[] selectionArgs = new String[]{
split[1]
};
path = getDataColumn(context, contentUri, selection, selectionArgs);
}
}
// MediaStore (and general)
else if ("content".equalsIgnoreCase(uri.getScheme())) {
path = getDataColumn(context, uri, null, null);
}
// File
else if ("file".equalsIgnoreCase(uri.getScheme())) {
path = uri.getPath();
}
} catch (Exception ex) {
return "";
}
return path;
}
public static String getName(Context context, Uri uri)
{
if (uri == null || uri.equals(Uri.EMPTY))
return "";
String fileName = "";
try {
String scheme = uri.getScheme();
if (scheme.equals("file")) {
fileName = uri.getLastPathSegment();
}
else if (scheme.equals("content")) {
String[] proj = { MediaStore.Images.Media.DISPLAY_NAME };
Cursor cursor = context.getContentResolver().query(uri, proj, null, null, null);
if (cursor != null && cursor.getCount() != 0) {
int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME);
cursor.moveToFirst();
fileName = cursor.getString(columnIndex);
}
if (cursor != null) {
cursor.close();
}
}
} catch (Exception ex) {
return "";
}
return fileName;
}
public static String getExtension(Context context, Uri uri) {
return FilenameUtils.getExtension(getName(context, uri));
}
/**
* Get the value of the data column for this Uri. This is useful for
* MediaStore Uris, and other file-based ContentProviders.
*
* @param context The context.
* @param uri The Uri to query.
* @param selection (Optional) Filter used in the query.
* @param selectionArgs (Optional) Selection arguments used in the query.
* @return The value of the _data column, which is typically a file path.
*/
public static String getDataColumn(Context context, Uri uri, String selection,
String[] selectionArgs) {
Cursor cursor = null;
final String column = "_data";
final String[] projection = {
column
};
try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
null);
if (cursor != null && cursor.moveToFirst()) {
final int column_index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(column_index);
}
} finally {
if (cursor != null)
cursor.close();
}
return null;
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is ExternalStorageProvider.
*/
public static boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is DownloadsProvider.
*/
public static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is MediaProvider.
*/
public static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is Turbo Storage.
*/
public static boolean isTurboDocument(Uri uri) {
return "com.maskyn.fileeditorpro.util.documents".equals(uri.getAuthority());
}
}

View File

@ -0,0 +1,123 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro.util;
import android.content.Context;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import com.maskyn.fileeditorpro.R;
import com.maskyn.fileeditorpro.preferences.PreferenceHelper;
/**
* Created by mac on 15/02/15.
*/
public class AccessoryView extends LinearLayout {
public IAccessoryView iAccessoryView;
private TypedValue outValue;
public AccessoryView(Context context) {
super(context);
init();
}
public AccessoryView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public AccessoryView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
setOrientation(HORIZONTAL);
createView();
}
public void setInterface(IAccessoryView iBreadcrumb) {
this.iAccessoryView = iBreadcrumb;
}
public void createView() {
removeAllViews();
// If we're running on Honeycomb or newer, then we can use the Theme's
// selectableItemBackground to ensure that the View has a pressed state
outValue = new TypedValue();
getContext().getTheme().resolveAttribute(R.attr.selectableItemBackgroundBorderless, outValue, true);
String[] characters = {
"<", ">", "!", "/", ".", ";", "=", "\"", "{", "}", "[", "]", "(", ")", "&", "|", "#", "*", "+", "-", ":", "%", ",", "_", "@", "?", "^", "'",
};
for (int i = 0; i < characters.length; i++)
addAButton(characters[i]);
updateTextColors();
}
private void addAButton(final String text) {
int dimension = (int) PixelDipConverter.convertDpToPixel(50, getContext());
//int padding = (int) PixelDipConverter.convertDpToPixel(10, getContext());
final Button name = new Button(getContext());
name.setLayoutParams(new LinearLayout.LayoutParams(dimension, dimension));
name.setGravity(Gravity.CENTER);
name.setText(text);
name.setTextSize(15);
name.setAllCaps(true);
//name.setPadding(padding, padding, padding, padding);
name.setClickable(true);
name.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
iAccessoryView.onButtonAccessoryViewClicked(text);
}
});
name.setBackgroundResource(outValue.resourceId);
addView(name);
}
public void updateTextColors() {
boolean isLightTheme = PreferenceHelper.getLightTheme(getContext());
for (int i = 0; i < getChildCount(); i++) {
((Button) getChildAt(i)).setTextColor(isLightTheme ? getResources().getColor(android.R.color.background_dark) : getResources().getColor(android.R.color.white));
}
}
public interface IAccessoryView {
public void onButtonAccessoryViewClicked(String text);
}
}

View File

@ -1,138 +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;
}
}
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro.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,52 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro.util;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityOptionsCompat;
import android.view.View;
public class AnimationUtils {
public static Bundle getScaleBundle(View view) {
return ActivityOptionsCompat.makeScaleUpAnimation(
view, 0, 0, view.getWidth(), view.getHeight()).toBundle();
}
public static void startActivityWithScale(@NonNull Activity startActivity, @NonNull Intent subActivity, @NonNull boolean forResult, @Nullable int code, @NonNull View view) {
if(forResult){
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN)
startActivity.startActivityForResult(subActivity, code, AnimationUtils.getScaleBundle
(view));
else
startActivity.startActivityForResult(subActivity, code);
}
else {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN)
startActivity.startActivity(subActivity, AnimationUtils.getScaleBundle
(view));
else
startActivity.startActivity(subActivity);
}
}
}

View File

@ -1,42 +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 "";
}
}
}
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro.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,57 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro.util;
import com.maskyn.fileeditorpro.BuildConfig;
/**
* Created by Artem on 30.12.13.
*/
public final class Build {
public static final boolean DEBUG = BuildConfig.DEBUG;
public static final String SUPPORT_EMAIL = "maskyngames@gmail.com";
public static final String GOOGLE_PLAY_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvpZca3gZSeRTHPMgxM+A1nTXuRL+9NTOWA1VJFs6ytppcO96i9EWQhmtXVUOKRQIgbXvkepxF7ut+JEjrbniQubZvmyBs9DxK7xUN4Zc3ZboQDQdfg2HJmZXzn8+joOfjXdS9WzsW7aaWKIQ8QXgOB1RUm9hdMdAlgKw+cEyp27WOoMK5m2H/i7C0MIO9tEQs3Hn9UTjayzzfy3MY+KDaX3T6oKievegbpyqyt8y4cpVusJC+uQFLa4bHKPtA3MaPUG6kU9tRV/DHrvFV6dOaPuTYCnYJELlGNfeqRUF0Nvb3Sv0U+BUoXgevjrlLdLz1bqgPDibLzaQmmofNXOnVQIDAQAB";
public static final int MAX_FILE_SIZE = 20_000;
public static final boolean FOR_AMAZON = false;
public static class Links {
public static final String GITHUB = "http://github.com/vmihalachi/TurboEditor";
public static final String XDA = "http://forum.xda-developers.com/android/apps-games/app-turbo-editor-text-editor-t2832016";
public static final String TRANSLATE = "http://crowdin.net/project/turbo-client";
public static final String DONATE = "https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=26VWS2TSAMUJA";
public static final String GOOGLE_PLUS_COMMUNITY = "http://plus.google.com/u/0/communities/111974095419108178946";
public static final String AMAZON_STORE = "amzn://apps/android?p=com.maskyn.fileeditor";
public static final String PLAY_STORE = "market://search?q=pub:Maskyn";
}
}

View File

@ -0,0 +1,80 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro.util;
import android.os.Build;
/**
* Contains params of current device. This is nice because we can override
* some here to test compatibility with old API.
*
* @author Artem Chepurnoy
*/
public class Device {
/**
* @return {@code true} if device is device supports given API version,
* {@code false} otherwise.
*/
public static boolean hasTargetApi(int api) {
return Build.VERSION.SDK_INT >= api;
}
/**
* @return {@code true} if device is running
* {@link android.os.Build.VERSION_CODES#L Lemon Cake} or higher, {@code false} otherwise.
*/
public static boolean hasLemonCakeApi() {
return Build.VERSION.SDK_INT >= 20; // Build.VERSION_CODES.L;
}
/**
* @return {@code true} if device is running
* {@link android.os.Build.VERSION_CODES#KITKAT KitKat} or higher, {@code false} otherwise.
*/
public static boolean hasKitKatApi() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
}
/**
* @return {@code true} if device is running
* {@link android.os.Build.VERSION_CODES#KITKAT KitKat} {@code false} otherwise.
*/
public static boolean isKitKatApi() {
return Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT;
}
/**
* @return {@code true} if device is running
* {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2 Jelly Bean 4.3} or higher, {@code false} otherwise.
*/
public static boolean hasJellyBeanMR2Api() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2;
}
/**
* @return {@code true} if device is running
* {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1 Jelly Bean 4.2} or higher, {@code false} otherwise.
*/
public static boolean hasJellyBeanMR1Api() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1;
}
}

View File

@ -0,0 +1,100 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro.util;
import android.net.Uri;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import java.io.File;
/**
* Created by mac on 19/03/15.
*/
public class GreatUri {
private Uri uri;
private String filePath;
private String fileName;
public GreatUri(Uri uri, String filePath, String fileName) {
this.uri = uri;
this.filePath = filePath;
this.fileName = fileName;
}
@Override
public int hashCode() {
return new HashCodeBuilder(17, 31). // two randomly chosen prime numbers
// if deriving: appendSuper(super.hashCode()).
append(uri).
toHashCode();
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof GreatUri))
return false;
if (obj == this)
return true;
GreatUri rhs = (GreatUri) obj;
return new EqualsBuilder().
// if deriving: appendSuper(super.equals(obj)).
append(uri, rhs.uri).
isEquals();
}
public Uri getUri() {
return uri;
}
public void setUri(Uri uri) {
this.uri = uri;
}
public String getFilePath() {
return filePath;
}
public void setFilePath(String filePath) {
this.filePath = filePath;
}
public String getParentFolder() {
return new File(filePath).getParent();
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public boolean isReadable() {
return new File(getFilePath()).canRead();
}
public boolean isWritable() {
return new File(getFilePath()).canWrite();
}
}

View File

@ -1,25 +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/>.
*/
package sharedcode.turboeditor.util;
public class Constants {
public static final int MAX_FILE_SIZE = 20_000;
public static final boolean FOR_AMAZON = false;
}
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro.util;
public interface IHomeActivity {
public abstract boolean showInterstitial();
}

View File

@ -0,0 +1,57 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro.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",
"cc", "cpp", "css", "csv", "ctl", "dat", "dhtml", "diz", "file", "forward", "grp", "h", "hh", "hpp", "hqx", "hta", "htaccess",
"htc", "htm", "html", "htpasswd", "htt", "htx", "in", "inc", "info", "ini", "ink", "java", "js", "jsp", "key", "latex", "log",
"logfile", "m3u", "m4", "m4a", "mak", "map", "md", "markdown", "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",
"tex", "text", "threads", "tmpl", "tpl", "txt", "ubb", "vbs", "xhtml", "xml", "xrc", "xsl"
};
public static final String[] MIME_CODE = {
"cs", "php", "js", "java", "py", "rb", "aspx", "cshtml", "vbhtml", "go", "c", "h", "cc", "cpp", "hh", "hpp", "pl", "pm", "t", "pod",
"m", "f", "for", "f90", "f95", "asp", "json", "wiki", "lua", "r"
};
public static final String[] MIME_HTML = {
"htm", "html", "xhtml"
};
public static final String[] MIME_PICTURE = {
"bmp", "eps", "png", "jpeg", "jpg", "ico", "gif", "tiff", "webp"
};
public static final String[] MIME_MUSIC = {
"aac", "flac", "mp3", "mpga", "oga", "ogg", "opus", "webma", "wav"
};
public static final String[] MIME_VIDEO = {
"avi", "mp4", "mkv", "wmw", "ogv", "webm"
};
public static final String[] MIME_ARCHIVE = {
"7z", "arj", "bz2", "gz", "rar", "tar", "tgz", "zip", "xz"
};
public static final String[] MIME_SQL = {
"sql", "mdf", "ndf", "ldf"
};
public static final String[] MIME_MARKDOWN = {
"md", "mdown", "markdown",
};
}

View File

@ -1,56 +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);
}
}
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro.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

@ -1,37 +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 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);
}
}
}
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro.util;
import android.app.Activity;
import com.maskyn.fileeditorpro.R;
import com.maskyn.fileeditorpro.preferences.PreferenceHelper;
public class ThemeUtils {
public static void setTheme(Activity activity){
boolean light = PreferenceHelper.getLightTheme(activity);
if (light) {
activity.setTheme(R.style.AppThemeBaseLight);
} else {
activity.setTheme(R.style.AppThemeBaseDark);
}
}
public static void setWindowsBackground(Activity activity) {
boolean whiteTheme = PreferenceHelper.getLightTheme(activity);
boolean darkTheme = PreferenceHelper.getDarkTheme(activity);
boolean blackTheme = PreferenceHelper.getBlackTheme(activity);
if (whiteTheme) {
activity.getWindow().setBackgroundDrawableResource(R.color.window_background_light);
} else if (darkTheme) {
activity.getWindow().setBackgroundDrawableResource(R.color.window_background);
} else {
activity.getWindow().setBackgroundDrawableResource(android.R.color.black);
}
}
}

View File

@ -0,0 +1,72 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro.util;
import android.content.Context;
import android.support.annotation.NonNull;
import android.widget.Toast;
/**
* Helper class with utils related to toasts (no bacon.)
*
* @author Artem Chepurnoy
*/
public class ToastUtils {
/**
* Shows toast message with given message shortly.
*
* @param text message to show
* @see #showLong(android.content.Context, CharSequence)
*/
@NonNull
public static Toast showShort(@NonNull Context context, @NonNull CharSequence text) {
return show(context, text, Toast.LENGTH_SHORT);
}
@NonNull
public static Toast showShort(@NonNull Context context, int stringRes) {
return showShort(context, context.getString(stringRes));
}
/**
* Shows toast message with given message for a long time.
*
* @param text message to show
* @see #showShort(android.content.Context, CharSequence)
*/
@NonNull
public static Toast showLong(@NonNull Context context, @NonNull CharSequence text) {
return show(context, text, Toast.LENGTH_LONG);
}
@NonNull
public static Toast showLong(@NonNull Context context, int stringRes) {
return showLong(context, context.getString(stringRes));
}
@NonNull
private static Toast show(@NonNull Context context, CharSequence text, int duration) {
Toast toast = Toast.makeText(context, text, duration);
toast.show();
return toast;
}
}

View File

@ -0,0 +1,306 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro.util;
import android.graphics.Matrix;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.widget.TextView;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* Created by Artem on 21.01.14.
*/
public class ViewUtils {
private static final String TAG = "ViewUtils";
@NonNull
private static final MotionEventHandler MOTION_EVENT_HANDLER = Device.hasKitKatApi()
? new MotionEventHandlerReflection()
: new MotionEventHandlerCompat();
public static boolean isTouchPointInView(@NonNull View view, float x, float y) {
final int[] coordinates = new int[3];
view.getLocationInWindow(coordinates);
int left = coordinates[0];
int top = coordinates[1];
return x >= left && x <= left + view.getWidth() &&
y >= top && y <= top + view.getHeight();
}
public static int getLeft(@NonNull View view) {
final int[] coordinates = new int[3];
view.getLocationInWindow(coordinates);
return coordinates[0];
}
public static int getTop(@NonNull View view) {
final int[] coordinates = new int[3];
view.getLocationInWindow(coordinates);
return coordinates[1];
}
public static int getBottom(@NonNull View view) {
return getTop(view) + view.getHeight();
}
public static int indexOf(@NonNull ViewGroup container, @NonNull View view) {
int length = container.getChildCount();
for (int i = 0; i < length; i++) {
View child = container.getChildAt(i);
assert child != null;
if (child.equals(view)) {
return i;
}
}
return -1;
}
// //////////////////////////////////////////
// //////////// -- VISIBILITY -- ////////////
// //////////////////////////////////////////
public static void setVisible(@NonNull View view, boolean visible) {
setVisible(view, visible, View.GONE);
}
public static void setVisible(@NonNull View view, boolean visible, int invisibleFlag) {
int visibility = view.getVisibility();
int visibilityNew = visible ? View.VISIBLE : invisibleFlag;
if (visibility != visibilityNew) {
view.setVisibility(visibilityNew);
}
}
public static void safelySetText(@NonNull TextView textView, @Nullable CharSequence text) {
final boolean visible = text != null;
if (visible) textView.setText(text);
ViewUtils.setVisible(textView, visible);
}
// //////////////////////////////////////////
// /////////// -- TOUCH EVENTS -- ///////////
// //////////////////////////////////////////
public static boolean pointInView(@NonNull View view, float localX, float localY, float slop) {
return localX >= view.getLeft() - slop
&& localX < view.getRight() + slop
&& localY >= view.getTop() - slop
&& localY < view.getBottom() + slop;
}
/**
* Transforms a motion event from view-local coordinates to on-screen
* coordinates.
*
* @param ev the view-local motion event
* @return false if the transformation could not be applied
*/
public static boolean toGlobalMotionEvent(@NonNull View view, @NonNull MotionEvent ev) {
return MOTION_EVENT_HANDLER.toGlobalMotionEvent(view, ev);
}
/**
* Transforms a motion event from on-screen coordinates to view-local
* coordinates.
*
* @param ev the on-screen motion event
* @return false if the transformation could not be applied
*/
public static boolean toLocalMotionEvent(@NonNull View view, @NonNull MotionEvent ev) {
return MOTION_EVENT_HANDLER.toLocalMotionEvent(view, ev);
}
private static abstract class MotionEventHandler {
/**
* Transforms a motion event from view-local coordinates to on-screen
* coordinates.
*
* @param ev the view-local motion event
* @return false if the transformation could not be applied
*/
abstract boolean toGlobalMotionEvent(@NonNull View view, @NonNull MotionEvent ev);
/**
* Transforms a motion event from on-screen coordinates to view-local
* coordinates.
*
* @param ev the on-screen motion event
* @return false if the transformation could not be applied
*/
abstract boolean toLocalMotionEvent(@NonNull View view, @NonNull MotionEvent ev);
}
private static final class MotionEventHandlerReflection extends MotionEventHandler {
@Override
boolean toGlobalMotionEvent(@NonNull View view, @NonNull MotionEvent ev) {
return toMotionEvent(view, ev, "toGlobalMotionEvent");
}
@Override
boolean toLocalMotionEvent(@NonNull View view, @NonNull MotionEvent ev) {
return toMotionEvent(view, ev, "toLocalMotionEvent");
}
private boolean toMotionEvent(View view, MotionEvent ev, String methodName) {
try {
Method method = View.class.getDeclaredMethod(methodName, MotionEvent.class);
method.setAccessible(true);
return (boolean) method.invoke(view, ev);
} catch (InvocationTargetException
| IllegalAccessException
| NoSuchMethodException
| NoClassDefFoundError e) {
Log.wtf(TAG, "Failed to access motion event transforming!!!");
e.printStackTrace();
}
return false;
}
}
private static final class MotionEventHandlerCompat extends MotionEventHandler {
@Nullable
private static int[] getWindowPosition(@NonNull View view) {
Object info;
try {
Field field = View.class.getDeclaredField("mAttachInfo");
field.setAccessible(true);
info = field.get(view);
} catch (Exception e) {
info = null;
Log.e(TAG, "Failed to get AttachInfo.");
}
if (info == null) {
return null;
}
int[] position = new int[2];
try {
Class clazz = Class.forName("android.view.View$AttachInfo");
Field field = clazz.getDeclaredField("mWindowLeft");
field.setAccessible(true);
position[0] = field.getInt(info);
field = clazz.getDeclaredField("mWindowTop");
field.setAccessible(true);
position[1] = field.getInt(info);
} catch (Exception e) {
Log.e(TAG, "Failed to get window\'s position from AttachInfo.");
return null;
}
return position;
}
/**
* Recursive helper method that applies transformations in post-order.
*
* @param ev the on-screen motion event
*/
private static void transformMotionEventToLocal(@NonNull View view, @NonNull MotionEvent ev) {
final ViewParent parent = view.getParent();
if (parent instanceof View) {
final View vp = (View) parent;
transformMotionEventToLocal(vp, ev);
ev.offsetLocation(vp.getScrollX(), vp.getScrollY());
} // TODO: Use reflections to access ViewRootImpl
// else if (parent instanceof ViewRootImpl) {
// final ViewRootImpl vr = (ViewRootImpl) parent;
// ev.offsetLocation(0, vr.mCurScrollY);
// }
ev.offsetLocation(-view.getLeft(), -view.getTop());
Matrix matrix = view.getMatrix();
if (matrix != null) {
ev.transform(matrix);
}
}
/**
* Recursive helper method that applies transformations in pre-order.
*
* @param ev the on-screen motion event
*/
private static void transformMotionEventToGlobal(@NonNull View view, @NonNull MotionEvent ev) {
Matrix matrix = view.getMatrix();
if (matrix != null) {
ev.transform(matrix);
}
ev.offsetLocation(view.getLeft(), view.getTop());
final ViewParent parent = view.getParent();
if (parent instanceof View) {
final View vp = (View) parent;
ev.offsetLocation(-vp.getScrollX(), -vp.getScrollY());
transformMotionEventToGlobal(vp, ev);
} // TODO: Use reflections to access ViewRootImpl
// else if (parent instanceof ViewRootImpl) {
// final ViewRootImpl vr = (ViewRootImpl) parent;
// ev.offsetLocation(0, -vr.mCurScrollY);
// }
}
@Override
boolean toGlobalMotionEvent(@NonNull View view, @NonNull MotionEvent ev) {
final int[] windowPosition = getWindowPosition(view);
if (windowPosition == null) {
return false;
}
transformMotionEventToGlobal(view, ev);
ev.offsetLocation(windowPosition[0], windowPosition[1]);
return true;
}
@Override
boolean toLocalMotionEvent(@NonNull View view, @NonNull MotionEvent ev) {
final int[] windowPosition = getWindowPosition(view);
if (windowPosition == null) {
return false;
}
ev.offsetLocation(-windowPosition[0], -windowPosition[1]);
transformMotionEventToLocal(view, ev);
return true;
}
}
}

View File

@ -0,0 +1,290 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro.util.systemui;
import android.app.Activity;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.view.WindowManager;
/**
* Helper for controlling the visibility of the System UI across the various API levels. To use
* this API, instantiate an instance of this class with the required level. The level specifies the
* extent to which the System UI's visibility is changed when you call {@link #hide()}
* or {@link #toggle()}.
*/
public final class SystemUiHelper {
/**
* In this level, the helper will toggle low profile mode.
*/
public static final int LEVEL_LOW_PROFILE = 0;
/**
* In this level, the helper will toggle the visibility of the status bar.
* If there is a navigation bar, it will toggle low profile mode.
*/
public static final int LEVEL_HIDE_STATUS_BAR = 1;
/**
* In this level, the helper will toggle the visibility of the navigation bar
* (if present and if possible) and status bar. In cases where the navigation
* bar is present but cannot be hidden, it will toggle low profile mode.
*/
public static final int LEVEL_LEAN_BACK = 2;
/**
* In this level, the helper will toggle the visibility of the navigation bar
* (if present and if possible) and status bar, in an immersive mode. This means that the app
* will continue to receive all touch events. The user can reveal the system bars with an
* inward swipe along the region where the system bars normally appear.
*
* <p>The {@link #FLAG_IMMERSIVE_STICKY} flag can be used to control how the system bars are
* displayed.
*/
public static final int LEVEL_IMMERSIVE = 3;
/**
* When this flag is set, the
* {@link android.view.WindowManager.LayoutParams#FLAG_LAYOUT_IN_SCREEN}
* flag will be set on older devices, making the status bar "float" on top
* of the activity layout. This is most useful when there are no controls at
* the top of the activity layout.
* <p>
* This flag isn't used on newer devices because the <a
* href="http://developer.android.com/design/patterns/actionbar.html">action
* bar</a>, the most important structural element of an Android app, should
* be visible and not obscured by the system UI.
*/
public static final int FLAG_LAYOUT_IN_SCREEN_OLDER_DEVICES = 0x1;
/**
* Used with {@link #LEVEL_IMMERSIVE}. When this flag is set, an inward swipe in the system
* bars areas will cause the system bars to temporarily appear in a semi-transparent state,
* but no flags are cleared, and your system UI visibility change listeners are not triggered.
* The bars automatically hide again after a short delay, or if the user interacts with the
* middle of the screen.
*/
public static final int FLAG_IMMERSIVE_STICKY = 0x2;
private static final String LOG_TAG = SystemUiHelper.class.getSimpleName();
private final SystemUiHelperImpl mImpl;
private final Handler mHandler;
private final Runnable mHideRunnable;
/**
* Construct a new SystemUiHelper.
*
* @param activity The Activity who's system UI should be changed
* @param level The level of hiding. Should be either {@link #LEVEL_LOW_PROFILE},
* {@link #LEVEL_HIDE_STATUS_BAR}, {@link #LEVEL_LEAN_BACK} or
* {@link #LEVEL_IMMERSIVE}
* @param flags Additional options. See {@link #FLAG_LAYOUT_IN_SCREEN_OLDER_DEVICES} and
* {@link #FLAG_IMMERSIVE_STICKY}
*/
public SystemUiHelper(Activity activity, int level, int flags) {
this(activity, level, flags, null);
}
/**
* Construct a new SystemUiHelper.
*
* @param activity The Activity who's system UI should be changed
* @param level The level of hiding. Should be either {@link #LEVEL_LOW_PROFILE},
* {@link #LEVEL_HIDE_STATUS_BAR}, {@link #LEVEL_LEAN_BACK} or
* {@link #LEVEL_IMMERSIVE}
* @param flags Additional options. See {@link #FLAG_LAYOUT_IN_SCREEN_OLDER_DEVICES} and
* {@link #FLAG_IMMERSIVE_STICKY}
* @param listener A listener which is called when the system visibility is changed
*/
public SystemUiHelper(Activity activity, int level, int flags,
OnVisibilityChangeListener listener) {
mHandler = new Handler(Looper.getMainLooper());
mHideRunnable = new HideRunnable();
// Create impl
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
mImpl = new SystemUiHelperImplKK(activity, level, flags, listener);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
mImpl = new SystemUiHelperImplJB(activity, level, flags, listener);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
mImpl = new SystemUiHelperImplICS(activity, level, flags, listener);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
mImpl = new SystemUiHelperImplHC(activity, level, flags, listener);
} else {
mImpl = new SystemUiHelperImplBase(activity, level, flags, listener);
}
}
/**
* @return true if the system UI is currently showing. What this means depends on the mode this
* {@link android.example.android.systemuivis.SystemUiHelper} was instantiated with.
*/
public boolean isShowing() {
return mImpl.isShowing();
}
/**
* Show the system UI. What this means depends on the mode this {@link android.example.android.systemuivis.SystemUiHelper} was
* instantiated with.
*
* <p>Any currently queued delayed hide requests will be removed.
*/
public void show() {
// Ensure that any currently queued hide calls are removed
removeQueuedRunnables();
mImpl.show();
}
/**
* Hide the system UI. What this means depends on the mode this {@link android.example.android.systemuivis.SystemUiHelper} was
* instantiated with.
*
* <p>Any currently queued delayed hide requests will be removed.
*/
public void hide() {
// Ensure that any currently queued hide calls are removed
removeQueuedRunnables();
mImpl.hide();
}
/**
* Request that the system UI is hidden after a delay.
*
* <p>Any currently queued delayed hide requests will be removed.
*
* @param delayMillis The delay (in milliseconds) until the Runnable
* will be executed.
*/
public void delayHide(long delayMillis) {
// Ensure that any currently queued hide calls are removed
removeQueuedRunnables();
mHandler.postDelayed(mHideRunnable, delayMillis);
}
/**
* Toggle whether the system UI is displayed.
*/
public void toggle() {
if (mImpl.isShowing()) {
mImpl.hide();
} else {
mImpl.show();
}
}
private void removeQueuedRunnables() {
// Ensure that any currently queued hide calls are removed
mHandler.removeCallbacks(mHideRunnable);
}
/**
* A callback interface used to listen for system UI visibility changes.
*/
public interface OnVisibilityChangeListener {
/**
* Called when the system UI visibility has changed.
*
* @param visible True if the system UI is visible.
*/
public void onVisibilityChange(boolean visible);
}
static abstract class SystemUiHelperImpl {
final Activity mActivity;
final int mLevel;
final int mFlags;
final OnVisibilityChangeListener mOnVisibilityChangeListener;
boolean mIsShowing = true;
SystemUiHelperImpl(Activity activity, int level, int flags,
OnVisibilityChangeListener onVisibilityChangeListener) {
mActivity = activity;
mLevel = level;
mFlags = flags;
mOnVisibilityChangeListener = onVisibilityChangeListener;
}
abstract void show();
abstract void hide();
boolean isShowing() {
return mIsShowing;
}
void setIsShowing(boolean isShowing) {
mIsShowing = isShowing;
if (mOnVisibilityChangeListener != null) {
mOnVisibilityChangeListener.onVisibilityChange(mIsShowing);
}
}
}
/**
* Base implementation. Used on API level 10 and below.
*/
static class SystemUiHelperImplBase extends SystemUiHelperImpl {
SystemUiHelperImplBase(Activity activity, int level, int flags,
OnVisibilityChangeListener onVisibilityChangeListener) {
super(activity, level, flags, onVisibilityChangeListener);
if ((mFlags & SystemUiHelper.FLAG_LAYOUT_IN_SCREEN_OLDER_DEVICES) != 0) {
mActivity.getWindow().addFlags(
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
| WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
}
}
@Override
void show() {
if (mLevel > SystemUiHelper.LEVEL_LOW_PROFILE) {
mActivity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
setIsShowing(true);
}
}
@Override
void hide() {
if (mLevel > SystemUiHelper.LEVEL_LOW_PROFILE) {
mActivity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
setIsShowing(false);
}
}
}
private class HideRunnable implements Runnable {
@Override
public void run() {
hide();
}
}
}

View File

@ -0,0 +1,94 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro.util.systemui;
import android.app.Activity;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.view.WindowManager;
class SystemUiHelperImplHC extends SystemUiHelper.SystemUiHelperImpl
implements View.OnSystemUiVisibilityChangeListener {
final View mDecorView;
SystemUiHelperImplHC(Activity activity, int level, int flags,
SystemUiHelper.OnVisibilityChangeListener onVisibilityChangeListener) {
super(activity, level, flags, onVisibilityChangeListener);
mDecorView = activity.getWindow().getDecorView();
mDecorView.setOnSystemUiVisibilityChangeListener(this);
}
@Override
void show() {
mDecorView.setSystemUiVisibility(createShowFlags());
}
@Override
void hide() {
mDecorView.setSystemUiVisibility(createHideFlags());
}
@Override
public final void onSystemUiVisibilityChange(int visibility) {
if ((visibility & createTestFlags()) != 0) {
onSystemUiHidden();
} else {
onSystemUiShown();
}
}
protected void onSystemUiShown() {
ActionBar ab = ((ActionBarActivity) mActivity).getSupportActionBar();
if (ab != null) {
ab.show();
}
mActivity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
setIsShowing(true);
}
protected void onSystemUiHidden() {
ActionBar ab = ((ActionBarActivity) mActivity).getSupportActionBar();
if (ab != null) {
ab.hide();
}
mActivity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
setIsShowing(false);
}
protected int createShowFlags() {
return View.STATUS_BAR_VISIBLE;
}
protected int createHideFlags() {
return View.STATUS_BAR_HIDDEN;
}
protected int createTestFlags() {
return View.STATUS_BAR_HIDDEN;
}
}

View File

@ -0,0 +1,60 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro.util.systemui;
import android.annotation.TargetApi;
import android.app.Activity;
import android.os.Build;
import android.view.View;
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
class SystemUiHelperImplICS extends SystemUiHelperImplHC {
SystemUiHelperImplICS(Activity activity, int level, int flags,
SystemUiHelper.OnVisibilityChangeListener onVisibilityChangeListener) {
super(activity, level, flags, onVisibilityChangeListener);
}
@Override
protected int createShowFlags() {
return View.SYSTEM_UI_FLAG_VISIBLE;
}
@Override
protected int createTestFlags() {
if (mLevel >= SystemUiHelper.LEVEL_LEAN_BACK) {
// Intentionally override test flags.
return View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
}
return View.SYSTEM_UI_FLAG_LOW_PROFILE;
}
@Override
protected int createHideFlags() {
int flag = View.SYSTEM_UI_FLAG_LOW_PROFILE;
if (mLevel >= SystemUiHelper.LEVEL_LEAN_BACK) {
flag |= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
}
return flag;
}
}

View File

@ -0,0 +1,93 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro.util.systemui;
import android.annotation.TargetApi;
import android.app.ActionBar;
import android.app.Activity;
import android.os.Build;
import android.view.View;
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
class SystemUiHelperImplJB extends SystemUiHelperImplICS {
SystemUiHelperImplJB(Activity activity, int level, int flags,
SystemUiHelper.OnVisibilityChangeListener onVisibilityChangeListener) {
super(activity, level, flags, onVisibilityChangeListener);
}
@Override
protected int createShowFlags() {
int flag = super.createShowFlags();
if (mLevel >= SystemUiHelper.LEVEL_HIDE_STATUS_BAR) {
flag |= View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
if (mLevel >= SystemUiHelper.LEVEL_LEAN_BACK) {
flag |= View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
}
}
return flag;
}
@Override
protected int createHideFlags() {
int flag = super.createHideFlags();
if (mLevel >= SystemUiHelper.LEVEL_HIDE_STATUS_BAR) {
flag |= View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_FULLSCREEN;
if (mLevel >= SystemUiHelper.LEVEL_LEAN_BACK) {
flag |= View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
}
}
return flag;
}
@Override
protected void onSystemUiShown() {
if (mLevel == SystemUiHelper.LEVEL_LOW_PROFILE) {
// Manually show the action bar when in low profile mode.
ActionBar ab = mActivity.getActionBar();
if (ab != null) {
ab.show();
}
}
setIsShowing(false);
}
@Override
protected void onSystemUiHidden() {
if (mLevel == SystemUiHelper.LEVEL_LOW_PROFILE) {
// Manually hide the action bar when in low profile mode.
ActionBar ab = mActivity.getActionBar();
if (ab != null) {
ab.hide();
}
}
setIsShowing(true);
}
}

View File

@ -0,0 +1,53 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro.util.systemui;
import android.annotation.TargetApi;
import android.app.Activity;
import android.os.Build;
import android.view.View;
@TargetApi(Build.VERSION_CODES.KITKAT)
class SystemUiHelperImplKK extends SystemUiHelperImplJB {
SystemUiHelperImplKK(Activity activity, int level, int flags,
SystemUiHelper.OnVisibilityChangeListener onVisibilityChangeListener) {
super(activity, level, flags, onVisibilityChangeListener);
}
@Override
protected int createHideFlags() {
int flag = super.createHideFlags();
if (mLevel == SystemUiHelper.LEVEL_IMMERSIVE) {
// If the client requested immersive mode, and we're on Android 4.4
// or later, add relevant flags. Applying HIDE_NAVIGATION without
// IMMERSIVE prevents the activity from accepting all touch events,
// so we only do this on Android 4.4 and later (where IMMERSIVE is
// present).
flag |= ((mFlags & SystemUiHelper.FLAG_IMMERSIVE_STICKY) != 0)
? View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
: View.SYSTEM_UI_FLAG_IMMERSIVE;
}
return flag;
}
}

View File

@ -1,49 +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;
}
}
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro.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,299 @@
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro.views;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.DialogFragment;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.text.method.LinkMovementMethod;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import com.maskyn.fileeditorpro.R;
import com.maskyn.fileeditorpro.dialogfragment.AboutDialog;
/**
* Helper class for showing fragment dialogs.
*/
public class DialogHelper {
public static final String TAG_FRAGMENT_ABOUT = "dialog_about";
public static final String TAG_FRAGMENT_HELP = "dialog_help";
public static final String TAG_FRAGMENT_FEEDBACK = "dialog_feedback";
public static void showAboutDialog(Activity activity) {
showDialog(activity, AboutDialog.class, TAG_FRAGMENT_ABOUT);
}
private static void showDialog(Activity activity, Class clazz, String tag) {
FragmentManager fm = activity.getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
Fragment prev = fm.findFragmentByTag(tag);
if (prev != null) {
ft.remove(prev);
}
ft.addToBackStack(null);
try {
((DialogFragment) clazz.newInstance()).show(ft, tag);
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
}
/**
* Helper class to implement custom dialog's design.
*/
public static class Builder {
/**
* Layout where content's layout exists in a {@link android.widget.ScrollView}.
* This is nice to display simple layout without scrollable elements such as
* {@link android.widget.ListView} or any similar. Use {@link #LAYOUT_SKELETON}
* for them.
*
* @see #LAYOUT_SKELETON
* @see #createCommonView()
* @see #wrap(int)
*/
public static final int LAYOUT_COMMON = 0;
/**
* The skeleton of dialog's layout. The only thing that is here is the custom
* view you set and the title / icon. Use it to display scrollable elements such as
* {@link android.widget.ListView}.
*
* @see #LAYOUT_COMMON
* @see #createSkeletonView()
* @see #wrap(int)
*/
public static final int LAYOUT_SKELETON = 1;
protected final Context mContext;
private Drawable mIcon;
private CharSequence mTitleText;
private CharSequence mMessageText;
private View mView;
private int mViewRes;
public Builder(Context context) {
mContext = context;
}
/**
* {@inheritDoc}
*/
@Override
public int hashCode() {
return new HashCodeBuilder(201, 17)
.append(mContext)
.append(mIcon)
.append(mTitleText)
.append(mMessageText)
.append(mViewRes)
.append(mView)
.toHashCode();
}
/**
* {@inheritDoc}
*/
@Override
public boolean equals(Object o) {
if (o == null)
return false;
if (o == this)
return true;
if (!(o instanceof Builder))
return false;
Builder builder = (Builder) o;
return new EqualsBuilder()
.append(mContext, builder.mContext)
.append(mIcon, builder.mIcon)
.append(mTitleText, builder.mTitleText)
.append(mMessageText, builder.mMessageText)
.append(mViewRes, builder.mViewRes)
.append(mView, builder.mView)
.isEquals();
}
public Builder setIcon(Drawable icon) {
mIcon = icon;
return this;
}
public Builder setTitle(CharSequence title) {
mTitleText = title;
return this;
}
public Builder setMessage(CharSequence message) {
mMessageText = message;
return this;
}
public Builder setIcon(int iconRes) {
return setIcon(iconRes == 0 ? null : mContext.getResources().getDrawable(iconRes));
}
public Builder setTitle(int titleRes) {
return setTitle(titleRes == 0 ? null : getString(titleRes));
}
public Builder setMessage(int messageRes) {
return setMessage(messageRes == 0 ? null : getString(messageRes));
}
private String getString(int stringRes) {
return mContext.getResources().getString(stringRes);
}
public Builder setView(View view) {
mView = view;
mViewRes = 0;
return this;
}
public Builder setView(int layoutRes) {
mView = null;
mViewRes = layoutRes;
return this;
}
/**
* Builds dialog's view
*
* @throws IllegalArgumentException when type is not one of defined.
* @see #LAYOUT_COMMON
* @see #LAYOUT_SKELETON
*/
public View createView(int type) {
switch (type) {
case LAYOUT_COMMON:
return createCommonView();
case LAYOUT_SKELETON:
return createSkeletonView();
default:
throw new IllegalArgumentException();
}
}
/**
* Builds view that based on simple {@link android.widget.ScrollView} container.
* This is nice to display simple layout without scrollable elements such as
* {@link android.widget.ListView} or any similar. Use {@link #createSkeletonView()}
* for them.
*
* @see #LAYOUT_COMMON
* @see #createView(int)
*/
public View createCommonView() {
// Creating skeleton layout will also try
// to add custom view. Avoid of doing it.
int customViewRes = mViewRes;
View customView = mView;
mViewRes = 0;
mView = null;
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ViewGroup rootLayout = (ViewGroup) createSkeletonView();
View bodyRootView = inflater.inflate(R.layout.dialog, rootLayout, false);
ViewGroup bodyLayout = (ViewGroup) bodyRootView.findViewById(R.id.content);
TextView messageView = (TextView) bodyLayout.findViewById(R.id.message);
rootLayout.addView(bodyRootView);
// Setup content
bodyLayout.removeView(messageView);
if (!TextUtils.isEmpty(mMessageText)) {
messageView.setMovementMethod(new LinkMovementMethod());
messageView.setText(mMessageText);
bodyLayout.addView(messageView);
}
// Custom view
if (customViewRes != 0) customView = inflater.inflate(customViewRes, bodyLayout, false);
if (customView != null) bodyLayout.addView(customView);
mView = customView;
return rootLayout;
}
/**
* @see #LAYOUT_SKELETON
* @see #createView(int)
*/
public View createSkeletonView() {
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ViewGroup rootLayout = (ViewGroup) inflater.inflate(R.layout.dialog_skeleton, null);
TextView titleView = (TextView) rootLayout.findViewById(R.id.title);
// Setup title
if (mTitleText != null) {
titleView.setText(mTitleText);
titleView.setCompoundDrawablesWithIntrinsicBounds(mIcon, null, null, null);
} else {
// This also removes an icon.
rootLayout.removeView(titleView);
}
// Custom view
if (mViewRes != 0) mView = inflater.inflate(mViewRes, rootLayout, false);
if (mView != null) rootLayout.addView(mView);
return rootLayout;
}
public AlertDialog.Builder wrap() {
return wrap(LAYOUT_COMMON);
}
/**
* Creates view and {@link android.app.AlertDialog.Builder#setView(android.view.View) sets}
* to new {@link android.app.AlertDialog.Builder}.
*
* @param type type of container layout
* @return AlertDialog.Builder with set custom view
*/
public AlertDialog.Builder wrap(int type) {
return new AlertDialog.Builder(mContext).setView(createView(type));
}
}
}

View File

@ -1,73 +1,84 @@
/*
* 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.view.View;
import android.widget.ScrollView;
public class GoodScrollView extends ScrollView {
public ScrollInterface scrollInterface;
int lastY;
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 void setScrollInterface(ScrollInterface scrollInterface) {
this.scrollInterface = scrollInterface;
}
@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) > 100) {
lastY = t;
scrollInterface.onScrollChanged(l, t, oldl, oldt);
}
}
public boolean hasReachedBottom(){
View firstChild = getChildAt(getChildCount()-1);
int diff = (firstChild.getBottom()-(getHeight()+getScrollY()+firstChild.getTop()));// Calculate the scrolldiff
return diff <= 0;
}
public interface ScrollInterface {
public void onScrollChanged(int l, int t, int oldl, int oldt);
}
}
/*
* Copyright (C) 2014 Vlad Mihalachi
*
* This file is part of Text Editor 8000.
*
* Text Editor 8000 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.
*
* Text Editor 8000 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 com.maskyn.fileeditorpro.views;
import android.content.Context;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ScrollView;
public class GoodScrollView extends ScrollView {
public ScrollInterface scrollInterface;
int lastY;
boolean listenerEnabled = true;
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 void setScrollInterface(ScrollInterface scrollInterface) {
this.scrollInterface = scrollInterface;
}
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
if (scrollInterface == null || !listenerEnabled) return;
if (Math.abs(lastY - t) > 100) {
lastY = t;
scrollInterface.onScrollChanged(l, t, oldl, oldt);
}
}
public boolean hasReachedBottom() {
View firstChild = getChildAt(getChildCount() - 1);
int diff = (firstChild.getBottom() - (getHeight() + getScrollY() + firstChild.getTop()));// Calculate the scrolldiff
return diff <= 0;
}
public void tempDisableListener(int mills) {
listenerEnabled = false;
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
listenerEnabled = true;
}
}, mills);
}
public interface ScrollInterface {
public void onScrollChanged(int l, int t, int oldl, int oldt);
}
}

View File

Before

Width:  |  Height:  |  Size: 301 B

After

Width:  |  Height:  |  Size: 301 B

View File

Before

Width:  |  Height:  |  Size: 724 B

After

Width:  |  Height:  |  Size: 724 B

View File

Before

Width:  |  Height:  |  Size: 621 B

After

Width:  |  Height:  |  Size: 621 B

View File

Before

Width:  |  Height:  |  Size: 465 B

After

Width:  |  Height:  |  Size: 465 B

View File

Before

Width:  |  Height:  |  Size: 531 B

After

Width:  |  Height:  |  Size: 531 B

View File

Before

Width:  |  Height:  |  Size: 495 B

After

Width:  |  Height:  |  Size: 495 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 875 B

View File

Before

Width:  |  Height:  |  Size: 713 B

After

Width:  |  Height:  |  Size: 713 B

View File

Before

Width:  |  Height:  |  Size: 644 B

After

Width:  |  Height:  |  Size: 644 B

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 365 B

After

Width:  |  Height:  |  Size: 365 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 401 B

View File

Before

Width:  |  Height:  |  Size: 853 B

After

Width:  |  Height:  |  Size: 853 B

View File

Before

Width:  |  Height:  |  Size: 898 B

After

Width:  |  Height:  |  Size: 898 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

Before

Width:  |  Height:  |  Size: 212 B

After

Width:  |  Height:  |  Size: 212 B

View File

Before

Width:  |  Height:  |  Size: 475 B

After

Width:  |  Height:  |  Size: 475 B

View File

Before

Width:  |  Height:  |  Size: 462 B

After

Width:  |  Height:  |  Size: 462 B

View File

Before

Width:  |  Height:  |  Size: 291 B

After

Width:  |  Height:  |  Size: 291 B

View File

Before

Width:  |  Height:  |  Size: 403 B

After

Width:  |  Height:  |  Size: 403 B

View File

Before

Width:  |  Height:  |  Size: 290 B

After

Width:  |  Height:  |  Size: 290 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 596 B

View File

Before

Width:  |  Height:  |  Size: 535 B

After

Width:  |  Height:  |  Size: 535 B

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