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
This commit is contained in:
Vlad Mihalachi
2015-03-14 13:11:56 +01:00
parent 89673216e8
commit 05e4157bed
97 changed files with 1897 additions and 3789 deletions

3
.idea/dictionaries/mac.xml generated Normal file
View File

@ -0,0 +1,3 @@
<component name="ProjectDictionaryState">
<dictionary name="mac" />
</component>

View File

@ -20,15 +20,15 @@
apply plugin: 'com.android.application' apply plugin: 'com.android.application'
android { android {
compileSdkVersion 21 compileSdkVersion 22
buildToolsVersion '21.1.2' buildToolsVersion '22'
defaultConfig { defaultConfig {
applicationId "com.maskyn.fileeditorpro" applicationId "com.maskyn.fileeditorpro"
minSdkVersion 11 minSdkVersion 11
targetSdkVersion 21 targetSdkVersion 22
versionCode 35 versionCode 39
versionName "1.13.2" versionName "1.15.1"
} }
compileOptions { compileOptions {

View File

@ -0,0 +1,188 @@
-- Merging decision tree log ---
manifest
ADDED from AndroidManifest.xml:20:1
xmlns:android
ADDED from AndroidManifest.xml:20:11
package
ADDED from AndroidManifest.xml:21:5
INJECTED from AndroidManifest.xml:0:0
INJECTED from AndroidManifest.xml:0:0
android:versionName
INJECTED from AndroidManifest.xml:0:0
INJECTED from AndroidManifest.xml:0:0
android:versionCode
INJECTED from AndroidManifest.xml:0:0
INJECTED from AndroidManifest.xml:0:0
android:installLocation
ADDED from AndroidManifest.xml:22:5
uses-permission#android.permission.WRITE_EXTERNAL_STORAGE
ADDED from AndroidManifest.xml:24:5
android:name
ADDED from AndroidManifest.xml:24:22
uses-permission#android.permission.ACCESS_SUPERUSER
ADDED from AndroidManifest.xml:25:5
android:name
ADDED from AndroidManifest.xml:25:22
supports-screens
ADDED from AndroidManifest.xml:27:5
android:resizeable
ADDED from AndroidManifest.xml:31:9
android:largeScreens
ADDED from AndroidManifest.xml:29:9
android:anyDensity
ADDED from AndroidManifest.xml:28:9
android:normalScreens
ADDED from AndroidManifest.xml:30:9
android:xlargeScreens
ADDED from AndroidManifest.xml:33:9
android:smallScreens
ADDED from AndroidManifest.xml:32:9
application
ADDED from AndroidManifest.xml:35:5
MERGED from turbo-editor.libraries:RootCommands:unspecified:11:5
MERGED from turbo-editor.libraries:FloatingActionButton:unspecified:11:5
MERGED from com.android.support:appcompat-v7:21.0.3:16:5
MERGED from com.android.support:support-v4:21.0.3:16:5
MERGED from com.github.gabrielemariotti.changeloglib:library:1.5.1:11:5
android:supportsRtl
ADDED from AndroidManifest.xml:41:9
android:label
ADDED from AndroidManifest.xml:38:9
android:allowBackup
ADDED from AndroidManifest.xml:36:9
android:icon
ADDED from AndroidManifest.xml:37:9
android:hardwareAccelerated
ADDED from AndroidManifest.xml:39:9
android:largeHeap
ADDED from AndroidManifest.xml:40:9
android:name
ADDED from AndroidManifest.xml:42:9
activity#com.maskyn.fileeditorpro.HomeActivity
ADDED from AndroidManifest.xml:47:9
android:windowSoftInputMode
ADDED from AndroidManifest.xml:51:13
android:configChanges
ADDED from AndroidManifest.xml:49:13
android:theme
ADDED from AndroidManifest.xml:52:13
android:name
ADDED from AndroidManifest.xml:48:13
android:launchMode
ADDED from AndroidManifest.xml:50:13
intent-filter#android.intent.action.MAIN+android.intent.category.LAUNCHER+android.intent.category.MULTIWINDOW_LAUNCHER
ADDED from AndroidManifest.xml:53:13
action#android.intent.action.MAIN
ADDED from AndroidManifest.xml:54:17
android:name
ADDED from AndroidManifest.xml:54:25
category#android.intent.category.LAUNCHER
ADDED from AndroidManifest.xml:56:17
android:name
ADDED from AndroidManifest.xml:56:27
category#android.intent.category.MULTIWINDOW_LAUNCHER
ADDED from AndroidManifest.xml:57:17
android:name
ADDED from AndroidManifest.xml:57:27
intent-filter#android.intent.action.EDIT+android.intent.action.PICK+android.intent.action.VIEW+android.intent.category.BROWSABLE+android.intent.category.DEFAULT
ADDED from AndroidManifest.xml:59:13
action#android.intent.action.VIEW
ADDED from AndroidManifest.xml:60:17
android:name
ADDED from AndroidManifest.xml:60:25
action#android.intent.action.EDIT
ADDED from AndroidManifest.xml:61:17
android:name
ADDED from AndroidManifest.xml:61:25
action#android.intent.action.PICK
ADDED from AndroidManifest.xml:62:17
android:name
ADDED from AndroidManifest.xml:62:25
category#android.intent.category.DEFAULT
ADDED from AndroidManifest.xml:64:17
android:name
ADDED from AndroidManifest.xml:64:27
category#android.intent.category.BROWSABLE
ADDED from AndroidManifest.xml:65:17
android:name
ADDED from AndroidManifest.xml:65:27
data
ADDED from AndroidManifest.xml:67:17
android:scheme
ADDED from AndroidManifest.xml:67:23
intent-filter#android.intent.action.SEND+android.intent.category.DEFAULT
ADDED from AndroidManifest.xml:76:13
action#android.intent.action.SEND
ADDED from AndroidManifest.xml:77:17
android:name
ADDED from AndroidManifest.xml:77:25
activity#sharedcode.turboeditor.activity.SelectFileActivity
ADDED from AndroidManifest.xml:82:9
android:label
ADDED from AndroidManifest.xml:85:13
android:configChanges
ADDED from AndroidManifest.xml:84:13
android:theme
ADDED from AndroidManifest.xml:87:13
android:parentActivityName
ADDED from AndroidManifest.xml:86:13
android:name
ADDED from AndroidManifest.xml:83:13
meta-data#android.support.PARENT_ACTIVITY
ADDED from AndroidManifest.xml:88:13
android:name
ADDED from AndroidManifest.xml:89:17
android:value
ADDED from AndroidManifest.xml:90:17
activity#sharedcode.turboeditor.preferences.ExtraSettingsActivity
ADDED from AndroidManifest.xml:93:9
android:label
ADDED from AndroidManifest.xml:95:13
android:parentActivityName
ADDED from AndroidManifest.xml:96:13
android:name
ADDED from AndroidManifest.xml:94:13
meta-data#com.sec.android.support.multiwindow
ADDED from AndroidManifest.xml:102:9
android:name
ADDED from AndroidManifest.xml:103:13
android:value
ADDED from AndroidManifest.xml:104:13
meta-data#com.sec.android.multiwindow.DEFAULT_SIZE_W
ADDED from AndroidManifest.xml:105:9
android:name
ADDED from AndroidManifest.xml:106:13
android:value
ADDED from AndroidManifest.xml:107:13
meta-data#com.sec.android.multiwindow.DEFAULT_SIZE_H
ADDED from AndroidManifest.xml:108:9
android:name
ADDED from AndroidManifest.xml:109:13
android:value
ADDED from AndroidManifest.xml:110:13
meta-data#com.sec.android.multiwindow.MINIMUM_SIZE_W
ADDED from AndroidManifest.xml:111:9
android:name
ADDED from AndroidManifest.xml:112:13
android:value
ADDED from AndroidManifest.xml:113:13
meta-data#com.sec.android.multiwindow.MINIMUM_SIZE_H
ADDED from AndroidManifest.xml:114:9
android:name
ADDED from AndroidManifest.xml:115:13
android:value
ADDED from AndroidManifest.xml:116:13
uses-sdk
INJECTED from AndroidManifest.xml:0:0 reason: use-sdk injection requested
MERGED from turbo-editor.libraries:sharedCode:unspecified:25:5
MERGED from turbo-editor.libraries:RootCommands:unspecified:7:5
MERGED from turbo-editor.libraries:FloatingActionButton:unspecified:7:5
MERGED from com.android.support:appcompat-v7:21.0.3:15:5
MERGED from com.android.support:support-v4:21.0.3:15:5
MERGED from com.github.gabrielemariotti.changeloglib:library:1.5.1:7:5
android:targetSdkVersion
INJECTED from AndroidManifest.xml:0:0
INJECTED from AndroidManifest.xml:0:0
android:minSdkVersion
INJECTED from AndroidManifest.xml:0:0
INJECTED from AndroidManifest.xml:0:0

View File

@ -40,14 +40,14 @@ repositories {
android { android {
compileSdkVersion 21 compileSdkVersion 22
buildToolsVersion '21.1.2' buildToolsVersion '22'
defaultConfig { defaultConfig {
applicationId "com.maskyn.fileeditor" applicationId "com.maskyn.fileeditor"
minSdkVersion 11 minSdkVersion 11
targetSdkVersion 21 targetSdkVersion 22
versionCode 35 versionCode 39
versionName "1.13.2" versionName "1.15.1"
} }
compileOptions { compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7 sourceCompatibility JavaVersion.VERSION_1_7
@ -71,7 +71,7 @@ android {
dependencies { dependencies {
compile fileTree(dir: 'libs', include: '*.jar') compile fileTree(dir: 'libs', include: '*.jar')
compile project(':libraries:sharedCode') compile project(':libraries:sharedCode')
compile 'com.google.android.gms:play-services:6.1.71' compile 'com.google.android.gms:play-services-ads:6.5.+'
compile('com.crashlytics.sdk.android:crashlytics:2.+@aar') { compile('com.crashlytics.sdk.android:crashlytics:2.+@aar') {
transitive = true; transitive = true;
} }

View File

@ -0,0 +1,238 @@
-- Merging decision tree log ---
manifest
ADDED from AndroidManifest.xml:21:1
xmlns:android
ADDED from AndroidManifest.xml:21:11
package
ADDED from AndroidManifest.xml:22:5
INJECTED from AndroidManifest.xml:0:0
INJECTED from AndroidManifest.xml:0:0
android:versionName
INJECTED from AndroidManifest.xml:0:0
INJECTED from AndroidManifest.xml:0:0
android:versionCode
INJECTED from AndroidManifest.xml:0:0
INJECTED from AndroidManifest.xml:0:0
android:installLocation
ADDED from AndroidManifest.xml:23:5
uses-permission#android.permission.WRITE_EXTERNAL_STORAGE
ADDED from AndroidManifest.xml:25:5
android:name
ADDED from AndroidManifest.xml:25:22
uses-permission#android.permission.ACCESS_SUPERUSER
ADDED from AndroidManifest.xml:26:5
android:name
ADDED from AndroidManifest.xml:26:22
uses-permission#android.permission.INTERNET
ADDED from AndroidManifest.xml:27:5
MERGED from com.crashlytics.sdk.android:crashlytics:2.2.0:11:5
android:name
ADDED from AndroidManifest.xml:27:22
uses-permission#android.permission.ACCESS_NETWORK_STATE
ADDED from AndroidManifest.xml:28:5
android:name
ADDED from AndroidManifest.xml:28:22
uses-permission#com.android.vending.BILLING
ADDED from AndroidManifest.xml:29:5
android:name
ADDED from AndroidManifest.xml:29:22
supports-screens
ADDED from AndroidManifest.xml:31:5
android:resizeable
ADDED from AndroidManifest.xml:35:9
android:largeScreens
ADDED from AndroidManifest.xml:33:9
android:anyDensity
ADDED from AndroidManifest.xml:32:9
android:normalScreens
ADDED from AndroidManifest.xml:34:9
android:xlargeScreens
ADDED from AndroidManifest.xml:37:9
android:smallScreens
ADDED from AndroidManifest.xml:36:9
application
ADDED from AndroidManifest.xml:39:5
MERGED from turbo-editor.libraries:RootCommands:unspecified:11:5
MERGED from turbo-editor.libraries:FloatingActionButton:unspecified:11:5
MERGED from com.android.support:appcompat-v7:21.0.3:16:5
MERGED from com.android.support:support-v4:21.0.3:16:5
MERGED from com.github.gabrielemariotti.changeloglib:library:1.5.1:11:5
MERGED from com.google.android.gms:play-services-ads:6.5.87:19:5
MERGED from com.google.android.gms:play-services-base:6.5.87:20:5
MERGED from com.android.support:support-v4:21.0.3:16:5
MERGED from com.crashlytics.sdk.android:crashlytics:2.2.0:13:5
MERGED from com.crashlytics.sdk.android:answers:1.1.0:11:5
MERGED from io.fabric.sdk.android:fabric:1.1.0:11:5
MERGED from com.crashlytics.sdk.android:beta:1.1.0:11:5
MERGED from io.fabric.sdk.android:fabric:1.1.0:11:5
MERGED from io.fabric.sdk.android:fabric:1.1.0:11:5
android:supportsRtl
ADDED from AndroidManifest.xml:45:9
android:label
ADDED from AndroidManifest.xml:42:9
android:allowBackup
ADDED from AndroidManifest.xml:40:9
android:icon
ADDED from AndroidManifest.xml:41:9
android:hardwareAccelerated
ADDED from AndroidManifest.xml:43:9
android:largeHeap
ADDED from AndroidManifest.xml:44:9
android:name
ADDED from AndroidManifest.xml:46:9
meta-data#com.google.android.gms.version
ADDED from AndroidManifest.xml:51:9
MERGED from com.google.android.gms:play-services-base:6.5.87:21:9
android:name
ADDED from AndroidManifest.xml:51:20
android:value
ADDED from AndroidManifest.xml:52:13
activity#com.maskyn.fileeditor.HomeActivity
ADDED from AndroidManifest.xml:53:9
android:windowSoftInputMode
ADDED from AndroidManifest.xml:57:13
android:configChanges
ADDED from AndroidManifest.xml:55:13
android:theme
ADDED from AndroidManifest.xml:58:13
android:name
ADDED from AndroidManifest.xml:54:13
android:launchMode
ADDED from AndroidManifest.xml:56:13
intent-filter#android.intent.action.MAIN+android.intent.category.LAUNCHER+android.intent.category.MULTIWINDOW_LAUNCHER
ADDED from AndroidManifest.xml:59:13
action#android.intent.action.MAIN
ADDED from AndroidManifest.xml:60:17
android:name
ADDED from AndroidManifest.xml:60:25
category#android.intent.category.LAUNCHER
ADDED from AndroidManifest.xml:62:17
android:name
ADDED from AndroidManifest.xml:62:27
category#android.intent.category.MULTIWINDOW_LAUNCHER
ADDED from AndroidManifest.xml:63:17
android:name
ADDED from AndroidManifest.xml:63:27
intent-filter#android.intent.action.EDIT+android.intent.action.PICK+android.intent.action.VIEW+android.intent.category.BROWSABLE+android.intent.category.DEFAULT
ADDED from AndroidManifest.xml:65:13
action#android.intent.action.VIEW
ADDED from AndroidManifest.xml:66:17
android:name
ADDED from AndroidManifest.xml:66:25
action#android.intent.action.EDIT
ADDED from AndroidManifest.xml:67:17
android:name
ADDED from AndroidManifest.xml:67:25
action#android.intent.action.PICK
ADDED from AndroidManifest.xml:68:17
android:name
ADDED from AndroidManifest.xml:68:25
category#android.intent.category.DEFAULT
ADDED from AndroidManifest.xml:70:17
android:name
ADDED from AndroidManifest.xml:70:27
category#android.intent.category.BROWSABLE
ADDED from AndroidManifest.xml:71:17
android:name
ADDED from AndroidManifest.xml:71:27
data
ADDED from AndroidManifest.xml:73:17
android:scheme
ADDED from AndroidManifest.xml:73:23
intent-filter#android.intent.action.SEND+android.intent.category.DEFAULT
ADDED from AndroidManifest.xml:82:13
action#android.intent.action.SEND
ADDED from AndroidManifest.xml:83:17
android:name
ADDED from AndroidManifest.xml:83:25
activity#sharedcode.turboeditor.activity.SelectFileActivity
ADDED from AndroidManifest.xml:88:9
android:label
ADDED from AndroidManifest.xml:91:13
android:configChanges
ADDED from AndroidManifest.xml:90:13
android:theme
ADDED from AndroidManifest.xml:93:13
android:parentActivityName
ADDED from AndroidManifest.xml:92:13
android:name
ADDED from AndroidManifest.xml:89:13
meta-data#android.support.PARENT_ACTIVITY
ADDED from AndroidManifest.xml:94:9
android:name
ADDED from AndroidManifest.xml:95:13
android:value
ADDED from AndroidManifest.xml:96:13
activity#sharedcode.turboeditor.preferences.ExtraSettingsActivity
ADDED from AndroidManifest.xml:99:9
android:label
ADDED from AndroidManifest.xml:101:13
android:parentActivityName
ADDED from AndroidManifest.xml:102:13
android:name
ADDED from AndroidManifest.xml:100:13
meta-data#com.sec.android.support.multiwindow
ADDED from AndroidManifest.xml:108:9
android:name
ADDED from AndroidManifest.xml:109:13
android:value
ADDED from AndroidManifest.xml:110:13
meta-data#com.sec.android.multiwindow.DEFAULT_SIZE_W
ADDED from AndroidManifest.xml:111:9
android:name
ADDED from AndroidManifest.xml:112:13
android:value
ADDED from AndroidManifest.xml:113:13
meta-data#com.sec.android.multiwindow.DEFAULT_SIZE_H
ADDED from AndroidManifest.xml:114:9
android:name
ADDED from AndroidManifest.xml:115:13
android:value
ADDED from AndroidManifest.xml:116:13
meta-data#com.sec.android.multiwindow.MINIMUM_SIZE_W
ADDED from AndroidManifest.xml:117:9
android:name
ADDED from AndroidManifest.xml:118:13
android:value
ADDED from AndroidManifest.xml:119:13
meta-data#com.sec.android.multiwindow.MINIMUM_SIZE_H
ADDED from AndroidManifest.xml:120:9
android:name
ADDED from AndroidManifest.xml:121:13
android:value
ADDED from AndroidManifest.xml:122:13
activity#com.google.android.gms.ads.AdActivity
ADDED from AndroidManifest.xml:124:9
android:configChanges
ADDED from AndroidManifest.xml:125:13
android:name
ADDED from AndroidManifest.xml:124:19
meta-data#com.crashlytics.ApiKey
ADDED from AndroidManifest.xml:126:9
android:name
ADDED from AndroidManifest.xml:126:20
android:value
ADDED from AndroidManifest.xml:126:58
uses-sdk
INJECTED from AndroidManifest.xml:0:0 reason: use-sdk injection requested
MERGED from turbo-editor.libraries:sharedCode:unspecified:25:5
MERGED from turbo-editor.libraries:RootCommands:unspecified:7:5
MERGED from turbo-editor.libraries:FloatingActionButton:unspecified:7:5
MERGED from com.android.support:appcompat-v7:21.0.3:15:5
MERGED from com.android.support:support-v4:21.0.3:15:5
MERGED from com.github.gabrielemariotti.changeloglib:library:1.5.1:7:5
MERGED from com.google.android.gms:play-services-ads:6.5.87:18:5
MERGED from com.google.android.gms:play-services-base:6.5.87:18:5
MERGED from com.android.support:support-v4:21.0.3:15:5
MERGED from com.crashlytics.sdk.android:crashlytics:2.2.0:7:5
MERGED from com.crashlytics.sdk.android:answers:1.1.0:7:5
MERGED from io.fabric.sdk.android:fabric:1.1.0:7:5
MERGED from com.crashlytics.sdk.android:beta:1.1.0:7:5
MERGED from io.fabric.sdk.android:fabric:1.1.0:7:5
MERGED from io.fabric.sdk.android:fabric:1.1.0:7:5
android:targetSdkVersion
INJECTED from AndroidManifest.xml:0:0
INJECTED from AndroidManifest.xml:0:0
android:minSdkVersion
INJECTED from AndroidManifest.xml:0:0
INJECTED from AndroidManifest.xml:0:0

View File

@ -2,95 +2,396 @@
<items version="2" > <items version="2" >
<item <item
jar="C:\Users\Vlad\Documents\AndroidStudioProjects\turbo-editor\app-pro\build\intermediates\exploded-aar\com.android.support\support-v4\21.0.0\libs\internal_impl-21.0.0.jar" jar="/Users/mac/AndroidStudioProjects/turbo-editor/app-pro/build/intermediates/exploded-aar/turbo-editor.libraries/FloatingActionButton/unspecified/classes.jar"
jumboMode="false" jumboMode="false"
revision="21.0.2" revision="22.0.0"
sha1="1609e6d42d0480b0f4188e2c29f75388fa12a8f0"> sha1="66cee5a65742fef58c1dcdc0b892042f7bb1530b">
<dex dex="C:\Users\Vlad\Documents\AndroidStudioProjects\turbo-editor\app-pro\build\intermediates\pre-dexed\debug\internal_impl-21.0.0-b15535acecaec42d04239e17e0a03ab072a43104.jar" /> <dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app-pro/build/intermediates/pre-dexed/debug/classes-041d055cf4bc0ac183d528da81f21df261f58a2c.jar" />
</item> </item>
<item <item
jar="C:\Users\Vlad\Documents\AndroidStudioProjects\turbo-editor\app-pro\build\intermediates\exploded-aar\turbo-editor.libraries\FloatingActionButton\unspecified\classes.jar" jar="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/exploded-aar/com.android.support/support-v4/21.0.3/classes.jar"
jumboMode="false" jumboMode="false"
revision="21.0.2" revision="22.0.0"
sha1="d0b9fcf5ff71e9443e787fdeef87e6833f82498d"> sha1="2c91c949a45a21cdecf26e03951e46c7beec9ad8">
<dex dex="C:\Users\Vlad\Documents\AndroidStudioProjects\turbo-editor\app-pro\build\intermediates\pre-dexed\debug\classes-82d5b6cab7f16bad663de7c7008673037efb0e1b.jar" /> <dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/pre-dexed/release/classes-e010b6ec2ae97c8d5cf66327f984fb7645e2eacb.jar" />
</item> </item>
<item <item
jar="C:\Users\Vlad\Documents\AndroidStudioProjects\turbo-editor\app-pro\build\intermediates\exploded-aar\com.android.support\support-v4\21.0.0\classes.jar" jar="/Users/mac/AndroidStudioProjects/turbo-editor/app-pro/build/intermediates/exploded-aar/turbo-editor.libraries/sharedCode/unspecified/libs/juniversalchardet-1.0.3.jar"
jumboMode="false" jumboMode="false"
revision="21.0.2" revision="21.1.2"
sha1="686344a780033e4ba22b926cd225f8d4941247e6">
<dex dex="C:\Users\Vlad\Documents\AndroidStudioProjects\turbo-editor\app-pro\build\intermediates\pre-dexed\debug\classes-e90e1f4e06d0f5aa27166f2f8f5fcea319efbd95.jar" />
</item>
<item
jar="C:\Users\Vlad\Documents\AndroidStudioProjects\turbo-editor\app-pro\build\intermediates\exploded-aar\com.android.support\appcompat-v7\21.0.0\classes.jar"
jumboMode="false"
revision="21.0.2"
sha1="95fd37732ec852e99f07eeb516a3650172f1d136">
<dex dex="C:\Users\Vlad\Documents\AndroidStudioProjects\turbo-editor\app-pro\build\intermediates\pre-dexed\debug\classes-fb4f15a411cfb0bffc51b68ad64a4794d3d67ae4.jar" />
</item>
<item
jar="C:\Users\Vlad\.gradle\caches\modules-2\files-2.1\commons-io\commons-io\2.4\b1b6ea3b7e4aa4f492509a4952029cd8e48019ad\commons-io-2.4.jar"
jumboMode="false"
revision="21.0.2"
sha1="b1b6ea3b7e4aa4f492509a4952029cd8e48019ad">
<dex dex="C:\Users\Vlad\Documents\AndroidStudioProjects\turbo-editor\app-pro\build\intermediates\pre-dexed\debug\commons-io-2.4-63b64e68cd19031cd252ac65a3ef94421c1bf0f4.jar" />
</item>
<item
jar="C:\Users\Vlad\Documents\AndroidStudioProjects\turbo-editor\app-pro\build\intermediates\exploded-aar\turbo-editor.libraries\sharedCode\unspecified\libs\juniversalchardet-1.0.3.jar"
jumboMode="false"
revision="21.0.2"
sha1="591d72211acc0b909b79c840e0b3ed9a0982d807"> sha1="591d72211acc0b909b79c840e0b3ed9a0982d807">
<dex dex="C:\Users\Vlad\Documents\AndroidStudioProjects\turbo-editor\app-pro\build\intermediates\pre-dexed\debug\juniversalchardet-1.0.3-65b2b356e3f2da4b67e00aba70923d6321852204.jar" /> <dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app-pro/build/intermediates/pre-dexed/debug/juniversalchardet-1.0.3-79cb61d649f7a1282ccdca5a55d9edef09b984d7.jar" />
</item> </item>
<item <item
jar="C:\Users\Vlad\.gradle\caches\modules-2\files-2.1\org.apache.commons\commons-lang3\3.1\905075e6c80f206bbe6cf1e809d2caa69f420c76\commons-lang3-3.1.jar" jar="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/exploded-aar/com.android.support/support-v4/21.0.3/classes.jar"
jumboMode="false" jumboMode="false"
revision="21.0.2" revision="21.1.2"
sha1="905075e6c80f206bbe6cf1e809d2caa69f420c76"> sha1="2c91c949a45a21cdecf26e03951e46c7beec9ad8">
<dex dex="C:\Users\Vlad\Documents\AndroidStudioProjects\turbo-editor\app-pro\build\intermediates\pre-dexed\debug\commons-lang3-3.1-84728078c80f2c8637e0c3fe426ad61433c75bb6.jar" /> <dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/pre-dexed/debug/classes-e010b6ec2ae97c8d5cf66327f984fb7645e2eacb.jar" />
</item> </item>
<item <item
jar="C:\Users\Vlad\Documents\AndroidStudioProjects\turbo-editor\app-pro\build\intermediates\exploded-aar\turbo-editor.libraries\sharedCode\unspecified\classes.jar" jar="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/exploded-aar/com.crashlytics.sdk.android/answers/1.1.2/classes.jar"
jumboMode="false" jumboMode="false"
revision="21.0.2" revision="22.0.0"
sha1="fe94ead11c648222804d49f12bbe257ed8d09c4d"> sha1="158555fbeff80e5a85464a818eadda8a448a1051">
<dex dex="C:\Users\Vlad\Documents\AndroidStudioProjects\turbo-editor\app-pro\build\intermediates\pre-dexed\debug\classes-bcfe21eb1248db73c27c811996e28274cf39b024.jar" /> <dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/pre-dexed/release/classes-f91276bcf60cec32a04f3aa34394e11eb3ba3ad5.jar" />
</item> </item>
<item <item
jar="C:\Users\Vlad\Documents\AndroidStudioProjects\turbo-editor\app-pro\build\intermediates\exploded-aar\turbo-editor.libraries\sharedCode\unspecified\libs\juniversalchardet-1.0.3-sources.jar" jar="/Users/mac/.gradle/caches/modules-2/files-2.1/com.nineoldandroids/library/2.4.0/e9b63380f3a242dbdbf103a2355ad7e43bad17cb/library-2.4.0.jar"
jumboMode="false" jumboMode="false"
revision="21.0.2" revision="22.0.0"
sha1="77979eaa98f90806f984155f44f63cc1fb60ac25">
<dex dex="C:\Users\Vlad\Documents\AndroidStudioProjects\turbo-editor\app-pro\build\intermediates\pre-dexed\debug\juniversalchardet-1.0.3-sources-58cfedaebe3b94ec0eaa2ede4e66aae8dbe309b0.jar" />
</item>
<item
jar="C:\Users\Vlad\.gradle\caches\modules-2\files-2.1\com.nineoldandroids\library\2.4.0\e9b63380f3a242dbdbf103a2355ad7e43bad17cb\library-2.4.0.jar"
jumboMode="false"
revision="21.0.2"
sha1="e9b63380f3a242dbdbf103a2355ad7e43bad17cb"> sha1="e9b63380f3a242dbdbf103a2355ad7e43bad17cb">
<dex dex="C:\Users\Vlad\Documents\AndroidStudioProjects\turbo-editor\app-pro\build\intermediates\pre-dexed\debug\library-2.4.0-6b043a8574fb97c742ca3065362b2a29e8f870bc.jar" /> <dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app-pro/build/intermediates/pre-dexed/debug/library-2.4.0-fcd7bf57330797c3eaeb05d042207c4ab7ecac63.jar" />
</item> </item>
<item <item
jar="C:\Users\Vlad\Documents\AndroidStudioProjects\turbo-editor\app-pro\build\intermediates\exploded-aar\turbo-editor.libraries\RootCommands\unspecified\classes.jar" jar="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/exploded-aar/io.fabric.sdk.android/fabric/1.1.0/classes.jar"
jumboMode="false" jumboMode="false"
revision="21.0.2" revision="21.1.2"
sha1="f1cd6d34046095cac347407908d0d42858db410a"> sha1="0bb0df3bf333801406f32bdfba678bcbd38cb9ff">
<dex dex="C:\Users\Vlad\Documents\AndroidStudioProjects\turbo-editor\app-pro\build\intermediates\pre-dexed\debug\classes-30cc9565ecef1e8ae8577530d7ddd41993d192d7.jar" /> <dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/pre-dexed/debug/classes-dda140fb3d64731d445f409c3466c69c68a4c02e.jar" />
</item> </item>
<item <item
jar="C:\Users\Vlad\Documents\AndroidStudioProjects\turbo-editor\app-pro\build\intermediates\exploded-aar\com.github.gabrielemariotti.changeloglib\library\1.5.1\classes.jar" jar="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/exploded-aar/com.crashlytics.sdk.android/beta/1.1.0/classes.jar"
jumboMode="false" jumboMode="false"
revision="21.0.2" revision="21.1.2"
sha1="86a04f40b5e28f11d108171131bed57ae1443f35">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/pre-dexed/debug/classes-62dddcf21ebf8aa7fd0c965537a5ae5a1fd7b969.jar" />
</item>
<item
jar="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/exploded-aar/com.android.support/support-v4/21.0.3/libs/internal_impl-21.0.3.jar"
jumboMode="false"
revision="21.1.2"
sha1="01ec05bfbafcc07646ba813000bf2ef11742dd03">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/pre-dexed/debug/internal_impl-21.0.3-ab55349e2b318433bbd1b9509fde0bfb9f3c372f.jar" />
</item>
<item
jar="/Users/mac/.gradle/caches/modules-2/files-2.1/commons-io/commons-io/2.4/b1b6ea3b7e4aa4f492509a4952029cd8e48019ad/commons-io-2.4.jar"
jumboMode="false"
revision="22.0.0"
sha1="b1b6ea3b7e4aa4f492509a4952029cd8e48019ad">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app-pro/build/intermediates/pre-dexed/debug/commons-io-2.4-b13b4a70538d465dbbcce6e080f59071eeb53a3a.jar" />
</item>
<item
jar="/Users/mac/.gradle/caches/modules-2/files-2.1/com.nineoldandroids/library/2.4.0/e9b63380f3a242dbdbf103a2355ad7e43bad17cb/library-2.4.0.jar"
jumboMode="false"
revision="21.1.2"
sha1="e9b63380f3a242dbdbf103a2355ad7e43bad17cb">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app-pro/build/intermediates/pre-dexed/debug/library-2.4.0-fcd7bf57330797c3eaeb05d042207c4ab7ecac63.jar" />
</item>
<item
jar="/Users/mac/Library/Android/sdk/extras/android/m2repository/com/android/support/support-annotations/21.0.3/support-annotations-21.0.3.jar"
jumboMode="false"
revision="21.1.2"
sha1="4b74cefe1f0c1b819e7260c8627a14674e37fd35">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app-pro/build/intermediates/pre-dexed/debug/support-annotations-21.0.3-e2493a76c5db00c85422b927024315e9561ca8d8.jar" />
</item>
<item
jar="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/exploded-aar/turbo-editor.libraries/sharedCode/unspecified/libs/juniversalchardet-1.0.3.jar"
jumboMode="false"
revision="22.0.0"
sha1="591d72211acc0b909b79c840e0b3ed9a0982d807">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/pre-dexed/release/juniversalchardet-1.0.3-6da18fe8b14fd219de988c9272910bd26b1433a2.jar" />
</item>
<item
jar="/Users/mac/AndroidStudioProjects/turbo-editor/app-pro/build/intermediates/exploded-aar/turbo-editor.libraries/sharedCode/unspecified/classes.jar"
jumboMode="false"
revision="21.1.2"
sha1="2c3d4d7b9f51d8f85dd121d722fcdce37b6f5752">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app-pro/build/intermediates/pre-dexed/debug/classes-d2f158f0c6d8e71984e1b2f52f7c248ddf421cff.jar" />
</item>
<item
jar="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/exploded-aar/com.crashlytics.sdk.android/crashlytics/2.2.0/classes.jar"
jumboMode="false"
revision="21.1.2"
sha1="9c91cd2b5773b33e4cfe8ababb6544b54ef40335">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/pre-dexed/debug/classes-4d6daab8bd3370426d7d391572234952433e55d7.jar" />
</item>
<item
jar="/Users/mac/.gradle/caches/modules-2/files-2.1/org.apache.commons/commons-lang3/3.1/905075e6c80f206bbe6cf1e809d2caa69f420c76/commons-lang3-3.1.jar"
jumboMode="false"
revision="22.0.0"
sha1="905075e6c80f206bbe6cf1e809d2caa69f420c76">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app-pro/build/intermediates/pre-dexed/debug/commons-lang3-3.1-b10c93b68b275dbbda03ac96f3dca1760aaa7c91.jar" />
</item>
<item
jar="/Users/mac/AndroidStudioProjects/turbo-editor/app-pro/build/intermediates/exploded-aar/turbo-editor.libraries/RootCommands/unspecified/classes.jar"
jumboMode="false"
revision="22.0.0"
sha1="8fc5121de38525c53e82648c80cf0a9818b956ff">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app-pro/build/intermediates/pre-dexed/debug/classes-567cc94c1061e5bc592616d8e4440a4415900d04.jar" />
</item>
<item
jar="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/exploded-aar/com.android.support/support-v4/21.0.3/libs/internal_impl-21.0.3.jar"
jumboMode="false"
revision="22.0.0"
sha1="01ec05bfbafcc07646ba813000bf2ef11742dd03">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/pre-dexed/release/internal_impl-21.0.3-ab55349e2b318433bbd1b9509fde0bfb9f3c372f.jar" />
</item>
<item
jar="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/exploded-aar/turbo-editor.libraries/sharedCode/unspecified/libs/juniversalchardet-1.0.3-sources.jar"
jumboMode="false"
revision="21.1.2"
sha1="77979eaa98f90806f984155f44f63cc1fb60ac25">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/pre-dexed/debug/juniversalchardet-1.0.3-sources-08233ec55ae40a14eee152277d92bd7fdc527036.jar" />
</item>
<item
jar="/Users/mac/.gradle/caches/modules-2/files-2.1/org.apache.commons/commons-lang3/3.1/905075e6c80f206bbe6cf1e809d2caa69f420c76/commons-lang3-3.1.jar"
jumboMode="false"
revision="21.1.2"
sha1="905075e6c80f206bbe6cf1e809d2caa69f420c76">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app-pro/build/intermediates/pre-dexed/debug/commons-lang3-3.1-b10c93b68b275dbbda03ac96f3dca1760aaa7c91.jar" />
</item>
<item
jar="/Users/mac/AndroidStudioProjects/turbo-editor/app-pro/build/intermediates/exploded-aar/turbo-editor.libraries/sharedCode/unspecified/libs/juniversalchardet-1.0.3.jar"
jumboMode="false"
revision="22.0.0"
sha1="591d72211acc0b909b79c840e0b3ed9a0982d807">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app-pro/build/intermediates/pre-dexed/debug/juniversalchardet-1.0.3-79cb61d649f7a1282ccdca5a55d9edef09b984d7.jar" />
</item>
<item
jar="/Users/mac/AndroidStudioProjects/turbo-editor/app-pro/build/intermediates/exploded-aar/com.android.support/appcompat-v7/21.0.3/classes.jar"
jumboMode="false"
revision="22.0.0"
sha1="81d42bf983a8741f4888a6e333e454e4a5e0eeb7">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app-pro/build/intermediates/pre-dexed/debug/classes-096ca18c795fd9315d22d85121daaf850f388b92.jar" />
</item>
<item
jar="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/exploded-aar/com.github.gabrielemariotti.changeloglib/library/1.5.1/classes.jar"
jumboMode="false"
revision="21.1.2"
sha1="74a89f0f8b56d9f11d70b8d8134cf4109f4797dc"> sha1="74a89f0f8b56d9f11d70b8d8134cf4109f4797dc">
<dex dex="C:\Users\Vlad\Documents\AndroidStudioProjects\turbo-editor\app-pro\build\intermediates\pre-dexed\debug\classes-9b612f0cb16e63277808158fe971bb4f40c98d29.jar" /> <dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/pre-dexed/debug/classes-378a7c750e497deeb602597a239d4846198295a3.jar" />
</item> </item>
<item <item
jar="C:\Users\Vlad\AppData\Local\Android\android-sdk\extras\android\m2repository\com\android\support\support-annotations\21.0.0\support-annotations-21.0.0.jar" jar="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/exploded-aar/io.fabric.sdk.android/fabric/1.2.0/classes.jar"
jumboMode="false" jumboMode="false"
revision="21.0.2" revision="22.0.0"
sha1="1a578b9607b36266c63d43a4fa0ab5664dbe911e"> sha1="0a4af6a85230b990eb8690b696d2db9247338611">
<dex dex="C:\Users\Vlad\Documents\AndroidStudioProjects\turbo-editor\app-pro\build\intermediates\pre-dexed\debug\support-annotations-21.0.0-7b7e20ddbdfce40d4a29c1e68c2dbbc5bb512ab5.jar" /> <dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/pre-dexed/release/classes-42f23abde068c6b52800c8bf4e7ef109c6e55a17.jar" />
</item>
<item
jar="/Users/mac/AndroidStudioProjects/turbo-editor/app-pro/build/intermediates/exploded-aar/turbo-editor.libraries/sharedCode/unspecified/classes.jar"
jumboMode="false"
revision="22.0.0"
sha1="260866dd1d6c762019f0d580cc0263b84187529f">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app-pro/build/intermediates/pre-dexed/debug/classes-d2f158f0c6d8e71984e1b2f52f7c248ddf421cff.jar" />
</item>
<item
jar="/Users/mac/.gradle/caches/modules-2/files-2.1/commons-io/commons-io/2.4/b1b6ea3b7e4aa4f492509a4952029cd8e48019ad/commons-io-2.4.jar"
jumboMode="false"
revision="21.1.2"
sha1="b1b6ea3b7e4aa4f492509a4952029cd8e48019ad">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app-pro/build/intermediates/pre-dexed/debug/commons-io-2.4-b13b4a70538d465dbbcce6e080f59071eeb53a3a.jar" />
</item>
<item
jar="/Users/mac/AndroidStudioProjects/turbo-editor/app-pro/build/intermediates/exploded-aar/com.android.support/support-v4/21.0.3/libs/internal_impl-21.0.3.jar"
jumboMode="false"
revision="21.1.2"
sha1="01ec05bfbafcc07646ba813000bf2ef11742dd03">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app-pro/build/intermediates/pre-dexed/debug/internal_impl-21.0.3-7de4c60d78937ee823b527a87284cb0180cf25ee.jar" />
</item>
<item
jar="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/exploded-aar/turbo-editor.libraries/sharedCode/unspecified/classes.jar"
jumboMode="false"
revision="21.1.2"
sha1="5365d91f442ac54c37a5ae3ebbcd82d9f43835e9">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/pre-dexed/release/classes-7af851cddf38d5159407b847c0234eebc467ba34.jar" />
</item>
<item
jar="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/exploded-aar/com.crashlytics.sdk.android/crashlytics/2.2.2/classes.jar"
jumboMode="false"
revision="22.0.0"
sha1="1014d409d1af641616ca7a2b3fda549cf559d605">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/pre-dexed/release/classes-4d2059402647551080b92ee08cfa8e2709951308.jar" />
</item>
<item
jar="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/exploded-aar/com.crashlytics.sdk.android/answers/1.1.0/classes.jar"
jumboMode="false"
revision="21.1.2"
sha1="4d100f9e146f538d729d698a994c74c7b5fb886e">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/pre-dexed/debug/classes-b6208f732cbe2fed2537cf18d4454b88f40f0fec.jar" />
</item>
<item
jar="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/exploded-aar/turbo-editor.libraries/sharedCode/unspecified/libs/juniversalchardet-1.0.3.jar"
jumboMode="false"
revision="21.1.2"
sha1="591d72211acc0b909b79c840e0b3ed9a0982d807">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/pre-dexed/debug/juniversalchardet-1.0.3-6da18fe8b14fd219de988c9272910bd26b1433a2.jar" />
</item>
<item
jar="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/exploded-aar/turbo-editor.libraries/sharedCode/unspecified/libs/juniversalchardet-1.0.3-sources.jar"
jumboMode="false"
revision="22.0.0"
sha1="77979eaa98f90806f984155f44f63cc1fb60ac25">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/pre-dexed/release/juniversalchardet-1.0.3-sources-08233ec55ae40a14eee152277d92bd7fdc527036.jar" />
</item>
<item
jar="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/exploded-aar/turbo-editor.libraries/FloatingActionButton/unspecified/classes.jar"
jumboMode="false"
revision="21.1.2"
sha1="66cee5a65742fef58c1dcdc0b892042f7bb1530b">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/pre-dexed/debug/classes-f678c74688f3e132a975f931e58b6be06968cfee.jar" />
</item>
<item
jar="/Users/mac/AndroidStudioProjects/turbo-editor/app-pro/build/intermediates/exploded-aar/com.android.support/support-v4/21.0.3/classes.jar"
jumboMode="false"
revision="22.0.0"
sha1="2c91c949a45a21cdecf26e03951e46c7beec9ad8">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app-pro/build/intermediates/pre-dexed/debug/classes-98a4bd0d9f8dfeb621543952baf59b084db0948d.jar" />
</item>
<item
jar="/Users/mac/AndroidStudioProjects/turbo-editor/app-pro/build/intermediates/exploded-aar/turbo-editor.libraries/RootCommands/unspecified/classes.jar"
jumboMode="false"
revision="21.1.2"
sha1="8fc5121de38525c53e82648c80cf0a9818b956ff">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app-pro/build/intermediates/pre-dexed/debug/classes-567cc94c1061e5bc592616d8e4440a4415900d04.jar" />
</item>
<item
jar="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/exploded-aar/turbo-editor.libraries/sharedCode/unspecified/classes.jar"
jumboMode="false"
revision="22.0.0"
sha1="260866dd1d6c762019f0d580cc0263b84187529f">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/pre-dexed/release/classes-7af851cddf38d5159407b847c0234eebc467ba34.jar" />
</item>
<item
jar="/Users/mac/AndroidStudioProjects/turbo-editor/app-pro/build/intermediates/exploded-aar/com.android.support/support-v4/21.0.3/libs/internal_impl-21.0.3.jar"
jumboMode="false"
revision="22.0.0"
sha1="01ec05bfbafcc07646ba813000bf2ef11742dd03">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app-pro/build/intermediates/pre-dexed/debug/internal_impl-21.0.3-7de4c60d78937ee823b527a87284cb0180cf25ee.jar" />
</item>
<item
jar="/Users/mac/Library/Android/sdk/extras/android/m2repository/com/android/support/support-annotations/21.0.3/support-annotations-21.0.3.jar"
jumboMode="false"
revision="22.0.0"
sha1="4b74cefe1f0c1b819e7260c8627a14674e37fd35">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app-pro/build/intermediates/pre-dexed/debug/support-annotations-21.0.3-e2493a76c5db00c85422b927024315e9561ca8d8.jar" />
</item>
<item
jar="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/exploded-aar/com.google.android.gms/play-services-base/6.5.87/classes.jar"
jumboMode="false"
revision="21.1.2"
sha1="95482e7c792a7c0d5a9d5461e97726bd54fe9549">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/pre-dexed/release/classes-09a7a54569ddd0a2cfe86e92052f042d6061d86d.jar" />
</item>
<item
jar="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/exploded-aar/com.google.android.gms/play-services-ads/6.5.87/classes.jar"
jumboMode="false"
revision="21.1.2"
sha1="41aa21f9c5d9ea9aab32c0b8e33d0c13364063a9">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/pre-dexed/release/classes-5dc7ddf1e19c0471d2fa00010871c051400145a0.jar" />
</item>
<item
jar="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/exploded-aar/turbo-editor.libraries/RootCommands/unspecified/classes.jar"
jumboMode="false"
revision="22.0.0"
sha1="8fc5121de38525c53e82648c80cf0a9818b956ff">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/pre-dexed/release/classes-8e353cdc5188a33b2ae051656b4023deec32169f.jar" />
</item>
<item
jar="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/exploded-aar/com.crashlytics.sdk.android/beta/1.1.2/classes.jar"
jumboMode="false"
revision="22.0.0"
sha1="0d6546c1c73cb64a6907f694e6c4bf4b50fefa70">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/pre-dexed/release/classes-d7c3cbd32b25008f71bfaf501c6d05efb73f9642.jar" />
</item>
<item
jar="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/exploded-aar/com.android.support/appcompat-v7/21.0.3/classes.jar"
jumboMode="false"
revision="21.1.2"
sha1="81d42bf983a8741f4888a6e333e454e4a5e0eeb7">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/pre-dexed/debug/classes-39520468bbb3432f5f87a4442f5acf79e2176c84.jar" />
</item>
<item
jar="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/exploded-aar/com.github.gabrielemariotti.changeloglib/library/1.5.1/classes.jar"
jumboMode="false"
revision="22.0.0"
sha1="74a89f0f8b56d9f11d70b8d8134cf4109f4797dc">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/pre-dexed/release/classes-378a7c750e497deeb602597a239d4846198295a3.jar" />
</item>
<item
jar="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/exploded-aar/turbo-editor.libraries/RootCommands/unspecified/classes.jar"
jumboMode="false"
revision="21.1.2"
sha1="8fc5121de38525c53e82648c80cf0a9818b956ff">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/pre-dexed/debug/classes-8e353cdc5188a33b2ae051656b4023deec32169f.jar" />
</item>
<item
jar="/Users/mac/AndroidStudioProjects/turbo-editor/app-pro/build/intermediates/exploded-aar/turbo-editor.libraries/sharedCode/unspecified/libs/juniversalchardet-1.0.3-sources.jar"
jumboMode="false"
revision="22.0.0"
sha1="77979eaa98f90806f984155f44f63cc1fb60ac25">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app-pro/build/intermediates/pre-dexed/debug/juniversalchardet-1.0.3-sources-5e24cec968c377cba49fe4f60ed376fcd62b5a1b.jar" />
</item>
<item
jar="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/exploded-aar/turbo-editor.libraries/FloatingActionButton/unspecified/classes.jar"
jumboMode="false"
revision="22.0.0"
sha1="66cee5a65742fef58c1dcdc0b892042f7bb1530b">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/pre-dexed/release/classes-f678c74688f3e132a975f931e58b6be06968cfee.jar" />
</item>
<item
jar="/Users/mac/AndroidStudioProjects/turbo-editor/app-pro/build/intermediates/exploded-aar/turbo-editor.libraries/FloatingActionButton/unspecified/classes.jar"
jumboMode="false"
revision="21.1.2"
sha1="66cee5a65742fef58c1dcdc0b892042f7bb1530b">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app-pro/build/intermediates/pre-dexed/debug/classes-041d055cf4bc0ac183d528da81f21df261f58a2c.jar" />
</item>
<item
jar="/Users/mac/AndroidStudioProjects/turbo-editor/app-pro/build/intermediates/exploded-aar/turbo-editor.libraries/sharedCode/unspecified/libs/juniversalchardet-1.0.3-sources.jar"
jumboMode="false"
revision="21.1.2"
sha1="77979eaa98f90806f984155f44f63cc1fb60ac25">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app-pro/build/intermediates/pre-dexed/debug/juniversalchardet-1.0.3-sources-5e24cec968c377cba49fe4f60ed376fcd62b5a1b.jar" />
</item>
<item
jar="/Users/mac/AndroidStudioProjects/turbo-editor/app-pro/build/intermediates/exploded-aar/com.android.support/appcompat-v7/21.0.3/classes.jar"
jumboMode="false"
revision="21.1.2"
sha1="81d42bf983a8741f4888a6e333e454e4a5e0eeb7">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app-pro/build/intermediates/pre-dexed/debug/classes-096ca18c795fd9315d22d85121daaf850f388b92.jar" />
</item>
<item
jar="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/exploded-aar/com.google.android.gms/play-services-ads/6.5.87/classes.jar"
jumboMode="false"
revision="22.0.0"
sha1="41aa21f9c5d9ea9aab32c0b8e33d0c13364063a9">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/pre-dexed/release/classes-5dc7ddf1e19c0471d2fa00010871c051400145a0.jar" />
</item>
<item
jar="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/exploded-aar/com.android.support/appcompat-v7/21.0.3/classes.jar"
jumboMode="false"
revision="22.0.0"
sha1="81d42bf983a8741f4888a6e333e454e4a5e0eeb7">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/pre-dexed/release/classes-39520468bbb3432f5f87a4442f5acf79e2176c84.jar" />
</item>
<item
jar="/Users/mac/AndroidStudioProjects/turbo-editor/app-pro/build/intermediates/exploded-aar/com.github.gabrielemariotti.changeloglib/library/1.5.1/classes.jar"
jumboMode="false"
revision="21.1.2"
sha1="74a89f0f8b56d9f11d70b8d8134cf4109f4797dc">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app-pro/build/intermediates/pre-dexed/debug/classes-f7e6e66fb7bff101be54521eaf14ae1fefb60f08.jar" />
</item>
<item
jar="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/exploded-aar/com.google.android.gms/play-services-base/6.5.87/classes.jar"
jumboMode="false"
revision="22.0.0"
sha1="95482e7c792a7c0d5a9d5461e97726bd54fe9549">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/pre-dexed/release/classes-09a7a54569ddd0a2cfe86e92052f042d6061d86d.jar" />
</item>
<item
jar="/Users/mac/AndroidStudioProjects/turbo-editor/app-pro/build/intermediates/exploded-aar/com.android.support/support-v4/21.0.3/classes.jar"
jumboMode="false"
revision="21.1.2"
sha1="2c91c949a45a21cdecf26e03951e46c7beec9ad8">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app-pro/build/intermediates/pre-dexed/debug/classes-98a4bd0d9f8dfeb621543952baf59b084db0948d.jar" />
</item>
<item
jar="/Users/mac/AndroidStudioProjects/turbo-editor/app-pro/build/intermediates/exploded-aar/com.github.gabrielemariotti.changeloglib/library/1.5.1/classes.jar"
jumboMode="false"
revision="22.0.0"
sha1="74a89f0f8b56d9f11d70b8d8134cf4109f4797dc">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app-pro/build/intermediates/pre-dexed/debug/classes-f7e6e66fb7bff101be54521eaf14ae1fefb60f08.jar" />
</item> </item>
</items> </items>

Binary file not shown.

View File

@ -1,11 +1,11 @@
apply plugin: 'com.android.library' apply plugin: 'com.android.library'
android { android {
compileSdkVersion 21 compileSdkVersion 22
buildToolsVersion '21.1.2' buildToolsVersion '22'
defaultConfig { defaultConfig {
minSdkVersion 7 minSdkVersion 7
targetSdkVersion 21 targetSdkVersion 22
versionName "1.0" versionName "1.0"
versionCode 1 versionCode 1
} }

View File

@ -0,0 +1,13 @@
/**
* Automatically generated file. DO NOT MODIFY
*/
package com.faizmalkani.floatingactionbutton.test;
public final class BuildConfig {
public static final boolean DEBUG = Boolean.parseBoolean("true");
public static final String APPLICATION_ID = "com.faizmalkani.floatingactionbutton.test";
public static final String BUILD_TYPE = "debug";
public static final String FLAVOR = "";
public static final int VERSION_CODE = 1;
public static final String VERSION_NAME = "1.0";
}

View File

@ -0,0 +1,27 @@
/* AUTO-GENERATED FILE. DO NOT MODIFY.
*
* This class was automatically generated by the
* aapt tool from the resource data it found. It
* should not be modified by hand.
*/
package com.faizmalkani.floatingactionbutton;
public final class R {
public static final class attr {
public static final int colour = 0x7f010001;
public static final int drawable = 0x7f010000;
public static final int shadowColor = 0x7f010005;
public static final int shadowDx = 0x7f010003;
public static final int shadowDy = 0x7f010004;
public static final int shadowRadius = 0x7f010002;
}
public static final class styleable {
public static final int[] FloatingActionButton = { 0x7f010000, 0x7f010001, 0x7f010002, 0x7f010003, 0x7f010004, 0x7f010005 };
public static final int FloatingActionButton_colour = 1;
public static final int FloatingActionButton_drawable = 0;
public static final int FloatingActionButton_shadowColor = 5;
public static final int FloatingActionButton_shadowDx = 3;
public static final int FloatingActionButton_shadowDy = 4;
public static final int FloatingActionButton_shadowRadius = 2;
}
}

View File

@ -0,0 +1,173 @@
/* AUTO-GENERATED FILE. DO NOT MODIFY.
*
* This class was automatically generated by the
* aapt tool from the resource data it found. It
* should not be modified by hand.
*/
package com.faizmalkani.floatingactionbutton.test;
public final class R {
public static final class attr {
/** <p>Must be a color value, in the form of "<code>#<i>rgb</i></code>", "<code>#<i>argb</i></code>",
"<code>#<i>rrggbb</i></code>", or "<code>#<i>aarrggbb</i></code>".
<p>This may also be a reference to a resource (in the form
"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
theme attribute (in the form
"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
containing a value of this type.
*/
public static final int colour=0x7f010001;
/** <p>Must be an integer value, such as "<code>100</code>".
<p>This may also be a reference to a resource (in the form
"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
theme attribute (in the form
"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
containing a value of this type.
*/
public static final int drawable=0x7f010000;
/** <p>Must be an integer value, such as "<code>100</code>".
<p>This may also be a reference to a resource (in the form
"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
theme attribute (in the form
"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
containing a value of this type.
*/
public static final int shadowColor=0x7f010005;
/** <p>Must be a floating point value, such as "<code>1.2</code>".
<p>This may also be a reference to a resource (in the form
"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
theme attribute (in the form
"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
containing a value of this type.
*/
public static final int shadowDx=0x7f010003;
/** <p>Must be a floating point value, such as "<code>1.2</code>".
<p>This may also be a reference to a resource (in the form
"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
theme attribute (in the form
"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
containing a value of this type.
*/
public static final int shadowDy=0x7f010004;
/** <p>Must be a floating point value, such as "<code>1.2</code>".
<p>This may also be a reference to a resource (in the form
"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
theme attribute (in the form
"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
containing a value of this type.
*/
public static final int shadowRadius=0x7f010002;
}
public static final class styleable {
/** Attributes that can be used with a FloatingActionButton.
<p>Includes the following attributes:</p>
<table>
<colgroup align="left" />
<colgroup align="left" />
<tr><th>Attribute</th><th>Description</th></tr>
<tr><td><code>{@link #FloatingActionButton_colour com.faizmalkani.floatingactionbutton.test:colour}</code></td><td></td></tr>
<tr><td><code>{@link #FloatingActionButton_drawable com.faizmalkani.floatingactionbutton.test:drawable}</code></td><td></td></tr>
<tr><td><code>{@link #FloatingActionButton_shadowColor com.faizmalkani.floatingactionbutton.test:shadowColor}</code></td><td></td></tr>
<tr><td><code>{@link #FloatingActionButton_shadowDx com.faizmalkani.floatingactionbutton.test:shadowDx}</code></td><td></td></tr>
<tr><td><code>{@link #FloatingActionButton_shadowDy com.faizmalkani.floatingactionbutton.test:shadowDy}</code></td><td></td></tr>
<tr><td><code>{@link #FloatingActionButton_shadowRadius com.faizmalkani.floatingactionbutton.test:shadowRadius}</code></td><td></td></tr>
</table>
@see #FloatingActionButton_colour
@see #FloatingActionButton_drawable
@see #FloatingActionButton_shadowColor
@see #FloatingActionButton_shadowDx
@see #FloatingActionButton_shadowDy
@see #FloatingActionButton_shadowRadius
*/
public static final int[] FloatingActionButton = {
0x7f010000, 0x7f010001, 0x7f010002, 0x7f010003,
0x7f010004, 0x7f010005
};
/**
<p>This symbol is the offset where the {@link com.faizmalkani.floatingactionbutton.test.R.attr#colour}
attribute's value can be found in the {@link #FloatingActionButton} array.
<p>Must be a color value, in the form of "<code>#<i>rgb</i></code>", "<code>#<i>argb</i></code>",
"<code>#<i>rrggbb</i></code>", or "<code>#<i>aarrggbb</i></code>".
<p>This may also be a reference to a resource (in the form
"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
theme attribute (in the form
"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
containing a value of this type.
@attr name com.faizmalkani.floatingactionbutton.test:colour
*/
public static final int FloatingActionButton_colour = 1;
/**
<p>This symbol is the offset where the {@link com.faizmalkani.floatingactionbutton.test.R.attr#drawable}
attribute's value can be found in the {@link #FloatingActionButton} array.
<p>Must be an integer value, such as "<code>100</code>".
<p>This may also be a reference to a resource (in the form
"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
theme attribute (in the form
"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
containing a value of this type.
@attr name com.faizmalkani.floatingactionbutton.test:drawable
*/
public static final int FloatingActionButton_drawable = 0;
/**
<p>This symbol is the offset where the {@link com.faizmalkani.floatingactionbutton.test.R.attr#shadowColor}
attribute's value can be found in the {@link #FloatingActionButton} array.
<p>Must be an integer value, such as "<code>100</code>".
<p>This may also be a reference to a resource (in the form
"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
theme attribute (in the form
"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
containing a value of this type.
@attr name com.faizmalkani.floatingactionbutton.test:shadowColor
*/
public static final int FloatingActionButton_shadowColor = 5;
/**
<p>This symbol is the offset where the {@link com.faizmalkani.floatingactionbutton.test.R.attr#shadowDx}
attribute's value can be found in the {@link #FloatingActionButton} array.
<p>Must be a floating point value, such as "<code>1.2</code>".
<p>This may also be a reference to a resource (in the form
"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
theme attribute (in the form
"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
containing a value of this type.
@attr name com.faizmalkani.floatingactionbutton.test:shadowDx
*/
public static final int FloatingActionButton_shadowDx = 3;
/**
<p>This symbol is the offset where the {@link com.faizmalkani.floatingactionbutton.test.R.attr#shadowDy}
attribute's value can be found in the {@link #FloatingActionButton} array.
<p>Must be a floating point value, such as "<code>1.2</code>".
<p>This may also be a reference to a resource (in the form
"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
theme attribute (in the form
"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
containing a value of this type.
@attr name com.faizmalkani.floatingactionbutton.test:shadowDy
*/
public static final int FloatingActionButton_shadowDy = 4;
/**
<p>This symbol is the offset where the {@link com.faizmalkani.floatingactionbutton.test.R.attr#shadowRadius}
attribute's value can be found in the {@link #FloatingActionButton} array.
<p>Must be a floating point value, such as "<code>1.2</code>".
<p>This may also be a reference to a resource (in the form
"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
theme attribute (in the form
"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
containing a value of this type.
@attr name com.faizmalkani.floatingactionbutton.test:shadowRadius
*/
public static final int FloatingActionButton_shadowRadius = 2;
};
}

View File

@ -6,7 +6,7 @@
<uses-sdk <uses-sdk
android:minSdkVersion="7" android:minSdkVersion="7"
android:targetSdkVersion="21" /> android:targetSdkVersion="22" />
<application android:allowBackup="true" > <application android:allowBackup="true" >
</application> </application>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.faizmalkani.floatingactionbutton"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="7"
android:targetSdkVersion="22" />
<application android:allowBackup="true" >
</application>
</manifest>

View File

@ -6,7 +6,7 @@
<uses-sdk <uses-sdk
android:minSdkVersion="7" android:minSdkVersion="7"
android:targetSdkVersion="21" /> android:targetSdkVersion="22" />
<application android:allowBackup="true" > <application android:allowBackup="true" >
</application> </application>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.faizmalkani.floatingactionbutton"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="7"
android:targetSdkVersion="22" />
<application android:allowBackup="true" >
</application>
</manifest>

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<merger version="3"><dataSet config="debug"><source path="/Users/mac/AndroidStudioProjects/turbo-editor/libraries/FloatingActionButton/build/intermediates/bundles/debug/assets"/></dataSet><dataSet config="main"><source path="/Users/mac/AndroidStudioProjects/turbo-editor/libraries/FloatingActionButton/src/androidTest/assets"/></dataSet></merger>

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<merger version="3"><dataSet config="debug"><source path="/Users/mac/AndroidStudioProjects/turbo-editor/libraries/FloatingActionButton/build/intermediates/bundles/debug/res"><file path="/Users/mac/AndroidStudioProjects/turbo-editor/libraries/FloatingActionButton/build/intermediates/bundles/debug/res/values/values.xml" qualifiers=""><declare-styleable name="FloatingActionButton"><attr format="integer" name="drawable"/><attr format="color" name="colour"/><attr format="float" name="shadowRadius"/><attr format="float" name="shadowDx"/><attr format="float" name="shadowDy"/><attr format="integer" name="shadowColor"/></declare-styleable></file></source></dataSet><dataSet config="main"><source path="/Users/mac/AndroidStudioProjects/turbo-editor/libraries/FloatingActionButton/src/androidTest/res"/><source path="/Users/mac/AndroidStudioProjects/turbo-editor/libraries/FloatingActionButton/build/generated/res/rs/androidTest/debug"/><source path="/Users/mac/AndroidStudioProjects/turbo-editor/libraries/FloatingActionButton/build/generated/res/generated/androidTest/debug"/></dataSet><mergedItems><configuration qualifiers=""><declare-styleable name="FloatingActionButton"><attr format="integer" name="drawable"/><attr format="color" name="colour"/><attr format="float" name="shadowRadius"/><attr format="float" name="shadowDx"/><attr format="float" name="shadowDy"/><attr format="integer" name="shadowColor"/></declare-styleable></configuration></mergedItems></merger>

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.faizmalkani.floatingactionbutton.test" >
<uses-sdk
android:minSdkVersion="7"
android:targetSdkVersion="22" />
<instrumentation
android:name="android.test.InstrumentationTestRunner"
android:functionalTest="false"
android:handleProfiling="false"
android:label="Tests for com.faizmalkani.floatingactionbutton.test"
android:targetPackage="com.faizmalkani.floatingactionbutton.test" />
<application android:allowBackup="true" >
<uses-library android:name="android.test.runner" />
</application>
</manifest>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.faizmalkani.floatingactionbutton.test">
<uses-sdk android:minSdkVersion="7" android:targetSdkVersion="21" />
<application>
<uses-library android:name="android.test.runner" />
</application>
<instrumentation android:name="android.test.InstrumentationTestRunner"
android:targetPackage="com.faizmalkani.floatingactionbutton.test"
android:handleProfiling="false"
android:functionalTest="false"
android:label="Tests for com.faizmalkani.floatingactionbutton.test"/>
</manifest>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.faizmalkani.floatingactionbutton.test">
<uses-sdk android:minSdkVersion="7" android:targetSdkVersion="21" />
<application>
<uses-library android:name="android.test.runner" />
</application>
<instrumentation android:name="android.test.InstrumentationTestRunner"
android:targetPackage="com.faizmalkani.floatingactionbutton.test"
android:handleProfiling="false"
android:functionalTest="false"
android:label="Tests for com.faizmalkani.floatingactionbutton.test"/>
</manifest>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.faizmalkani.floatingactionbutton.test">
<uses-sdk android:minSdkVersion="7" android:targetSdkVersion="22" />
<application>
<uses-library android:name="android.test.runner" />
</application>
<instrumentation android:name="android.test.InstrumentationTestRunner"
android:targetPackage="com.faizmalkani.floatingactionbutton.test"
android:handleProfiling="false"
android:functionalTest="false"
android:label="Tests for com.faizmalkani.floatingactionbutton.test"/>
</manifest>

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="FloatingActionButton"><attr format="integer" name="drawable"/><attr format="color" name="colour"/><attr format="float" name="shadowRadius"/><attr format="float" name="shadowDx"/><attr format="float" name="shadowDy"/><attr format="integer" name="shadowColor"/></declare-styleable>
</resources>

View File

@ -0,0 +1,13 @@
int attr colour 0x7f010001
int attr drawable 0x7f010000
int attr shadowColor 0x7f010005
int attr shadowDx 0x7f010003
int attr shadowDy 0x7f010004
int attr shadowRadius 0x7f010002
int[] styleable FloatingActionButton { 0x7f010000, 0x7f010001, 0x7f010002, 0x7f010003, 0x7f010004, 0x7f010005 }
int styleable FloatingActionButton_colour 1
int styleable FloatingActionButton_drawable 0
int styleable FloatingActionButton_shadowColor 5
int styleable FloatingActionButton_shadowDx 3
int styleable FloatingActionButton_shadowDy 4
int styleable FloatingActionButton_shadowRadius 2

View File

@ -15,12 +15,12 @@ dependencies {
} }
android { android {
compileSdkVersion 21 compileSdkVersion 22
buildToolsVersion '21.1.2' buildToolsVersion '22'
defaultConfig { defaultConfig {
minSdkVersion 7 minSdkVersion 7
targetSdkVersion 21 targetSdkVersion 22
} }
compileOptions { compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7 sourceCompatibility JavaVersion.VERSION_1_7

View File

@ -26,12 +26,12 @@ android {
disable 'MissingTranslation', 'ExtraTranslation' disable 'MissingTranslation', 'ExtraTranslation'
} }
compileSdkVersion 21 compileSdkVersion 22
buildToolsVersion '21.1.2' buildToolsVersion '22'
defaultConfig { defaultConfig {
minSdkVersion 11 minSdkVersion 11
targetSdkVersion 21 targetSdkVersion 22
versionCode 1 versionCode 1
versionName "1.0" versionName "1.0"
} }
@ -61,9 +61,6 @@ dependencies {
compile fileTree(dir: 'libs', include: ['*.jar']) compile fileTree(dir: 'libs', include: ['*.jar'])
compile project(':libraries:RootCommands') compile project(':libraries:RootCommands')
compile project(':libraries:FloatingActionButton') compile project(':libraries:FloatingActionButton')
//compile('de.greenrobot:eventbus:2.2.1') {
// exclude module: 'support-v4'
// }
// compile 'com.googlecode.juniversalchardet:juniversalchardet:1.0.3' // compile 'com.googlecode.juniversalchardet:juniversalchardet:1.0.3'
compile 'org.apache.commons:commons-lang3:3.1' compile 'org.apache.commons:commons-lang3:3.1'
compile files('libs/juniversalchardet-1.0.3.jar') compile files('libs/juniversalchardet-1.0.3.jar')

View File

@ -57,7 +57,6 @@ import android.view.KeyEvent;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.EditText; import android.widget.EditText;
@ -74,8 +73,10 @@ import org.sufficientlysecure.rootcommands.Toolbox;
import java.io.File; import java.io.File;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -87,6 +88,7 @@ import sharedcode.turboeditor.dialogfragment.FindTextDialog;
import sharedcode.turboeditor.dialogfragment.NewFileDetailsDialog; import sharedcode.turboeditor.dialogfragment.NewFileDetailsDialog;
import sharedcode.turboeditor.dialogfragment.NumberPickerDialog; import sharedcode.turboeditor.dialogfragment.NumberPickerDialog;
import sharedcode.turboeditor.dialogfragment.SaveFileDialog; import sharedcode.turboeditor.dialogfragment.SaveFileDialog;
import sharedcode.turboeditor.preferences.PreferenceChangeType;
import sharedcode.turboeditor.preferences.PreferenceHelper; import sharedcode.turboeditor.preferences.PreferenceHelper;
import sharedcode.turboeditor.task.SaveFileTask; import sharedcode.turboeditor.task.SaveFileTask;
import sharedcode.turboeditor.texteditor.EditTextPadding; import sharedcode.turboeditor.texteditor.EditTextPadding;
@ -99,7 +101,6 @@ import sharedcode.turboeditor.texteditor.SearchResult;
import sharedcode.turboeditor.util.AccessStorageApi; import sharedcode.turboeditor.util.AccessStorageApi;
import sharedcode.turboeditor.util.AnimationUtils; import sharedcode.turboeditor.util.AnimationUtils;
import sharedcode.turboeditor.util.AppInfoHelper; import sharedcode.turboeditor.util.AppInfoHelper;
import sharedcode.turboeditor.util.EventBusEvents;
import sharedcode.turboeditor.util.IHomeActivity; import sharedcode.turboeditor.util.IHomeActivity;
import sharedcode.turboeditor.util.MimeTypes; import sharedcode.turboeditor.util.MimeTypes;
import sharedcode.turboeditor.util.ProCheckUtils; import sharedcode.turboeditor.util.ProCheckUtils;
@ -108,29 +109,19 @@ import sharedcode.turboeditor.views.CustomDrawerLayout;
import sharedcode.turboeditor.views.DialogHelper; import sharedcode.turboeditor.views.DialogHelper;
import sharedcode.turboeditor.views.GoodScrollView; import sharedcode.turboeditor.views.GoodScrollView;
import static sharedcode.turboeditor.util.EventBusEvents.APreferenceValueWasChanged.Type.ENCODING;
import static sharedcode.turboeditor.util.EventBusEvents.APreferenceValueWasChanged.Type.FONT_SIZE;
import static sharedcode.turboeditor.util.EventBusEvents.APreferenceValueWasChanged.Type.LINE_NUMERS;
import static sharedcode.turboeditor.util.EventBusEvents.APreferenceValueWasChanged.Type.MONOSPACE;
import static sharedcode.turboeditor.util.EventBusEvents.APreferenceValueWasChanged.Type.READ_ONLY;
import static sharedcode.turboeditor.util.EventBusEvents.APreferenceValueWasChanged.Type.SYNTAX;
import static sharedcode.turboeditor.util.EventBusEvents.APreferenceValueWasChanged.Type.TEXT_SUGGESTIONS;
import static sharedcode.turboeditor.util.EventBusEvents.APreferenceValueWasChanged.Type.THEME_CHANGE;
import static sharedcode.turboeditor.util.EventBusEvents.APreferenceValueWasChanged.Type.WRAP_CONTENT;
public abstract class MainActivity extends ActionBarActivity implements IHomeActivity, FindTextDialog public abstract class MainActivity extends ActionBarActivity implements IHomeActivity, FindTextDialog
.SearchDialogInterface, GoodScrollView.ScrollInterface, PageSystem.PageSystemInterface, .SearchDialogInterface, GoodScrollView.ScrollInterface, PageSystem.PageSystemInterface,
PageSystemButtons.PageButtonsInterface, NumberPickerDialog.INumberPickerDialog, SaveFileDialog.ISaveDialog, PageSystemButtons.PageButtonsInterface, NumberPickerDialog.INumberPickerDialog, SaveFileDialog.ISaveDialog,
AdapterView.OnItemClickListener, AdapterDrawer.Callbacks{ AdapterView.OnItemClickListener, AdapterDrawer.Callbacks{
//region VARIABLES //region VARIABLES
private static final int READ_REQUEST_CODE = 42;
private static final int private static final int
ID_SELECT_ALL = android.R.id.selectAll; ID_SELECT_ALL = android.R.id.selectAll;
private static final int ID_CUT = android.R.id.cut; private static final int ID_CUT = android.R.id.cut;
private static final int ID_COPY = android.R.id.copy; private static final int ID_COPY = android.R.id.copy;
private static final int ID_PASTE = android.R.id.paste; private static final int ID_PASTE = android.R.id.paste;
private static final int SELECT_FILE_CODE = 121; private static final int SELECT_FILE_CODE = 121;
private static final int KITKAT_OPEN_REQUEST_CODE = 41;
private static final int SYNTAX_DELAY_MILLIS_SHORT = 250; private static final int SYNTAX_DELAY_MILLIS_SHORT = 250;
private static final int SYNTAX_DELAY_MILLIS_LONG = 1500; private static final int SYNTAX_DELAY_MILLIS_LONG = 1500;
private static final int ID_UNDO = R.id.im_undo; private static final int ID_UNDO = R.id.im_undo;
@ -167,11 +158,10 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
private static String sFilePath = ""; private static String sFilePath = "";
private static Editor mEditor; private static Editor mEditor;
private static HorizontalScrollView horizontalScroll; private static HorizontalScrollView horizontalScroll;
private boolean searchingText;
private static SearchResult searchResult; private static SearchResult searchResult;
private static PageSystem pageSystem; private static PageSystem pageSystem;
private static PageSystemButtons pageSystemButtons; private static PageSystemButtons pageSystemButtons;
private static String currentEncoding = "UTF-8"; private static String currentEncoding = "UTF-16";
private static Toolbar toolbar; private static Toolbar toolbar;
/* /*
@ -236,7 +226,7 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
super.onPause(); super.onPause();
if (PreferenceHelper.getAutoSave(getBaseContext()) && mEditor.canSaveFile()) { if (PreferenceHelper.getAutoSave(getBaseContext()) && mEditor.canSaveFile()) {
saveTheFile(); saveTheFile(false);
mEditor.fileSaved(); // so it doesn't ask to save in onDetach mEditor.fileSaved(); // so it doesn't ask to save in onDetach
} }
} }
@ -311,7 +301,7 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
// Set the default title // Set the default title
getSupportActionBar().setTitle(getString(R.string.nome_app_turbo_editor)); getSupportActionBar().setTitle(getString(R.string.nome_app_turbo_editor));
onEvent(new EventBusEvents.ClosedAFile()); closedTheFile();
mDrawerLayout.openDrawer(Gravity.START); mDrawerLayout.openDrawer(Gravity.START);
mDrawerLayout.closeDrawer(Gravity.END); mDrawerLayout.closeDrawer(Gravity.END);
@ -335,15 +325,15 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
path = AccessStorageApi.getPath(getBaseContext(), data.getData()); path = AccessStorageApi.getPath(getBaseContext(), data.getData());
} }
if (requestCode == KITKAT_OPEN_REQUEST_CODE) { if (requestCode == READ_REQUEST_CODE) {
path = AccessStorageApi.getPath(getBaseContext(), data.getData()); path = AccessStorageApi.getPath(getBaseContext(), data.getData());
} }
if (!TextUtils.isEmpty(path)) { if (!TextUtils.isEmpty(path)) {
File file = new File(path); File file = new File(path);
if (file.isFile() && file.exists()) { if (file.isFile() && file.exists()) {
onEvent(new EventBusEvents.NewFileToOpen(new File newFileToOpen(new File
(path))); (path), "");
} }
} }
@ -355,7 +345,7 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
// Path of the file selected // Path of the file selected
String filePath = files.get(position).getAbsolutePath(); String filePath = files.get(position).getAbsolutePath();
// Send the event that a file was selected // Send the event that a file was selected
onEvent(new EventBusEvents.NewFileToOpen(new File(filePath))); newFileToOpen(new File(filePath), "");
} }
//endregion //endregion
@ -364,7 +354,7 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
@Override @Override
public boolean onCreateOptionsMenu(Menu menu) { public boolean onCreateOptionsMenu(Menu menu) {
if (fileOpened && searchingText) if (fileOpened && searchResult != null)
getMenuInflater().inflate(R.menu.fragment_editor_search, menu); getMenuInflater().inflate(R.menu.fragment_editor_search, menu);
else if (fileOpened) else if (fileOpened)
getMenuInflater().inflate(R.menu.fragment_editor, menu); getMenuInflater().inflate(R.menu.fragment_editor, menu);
@ -374,14 +364,18 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
@Override @Override
public boolean onPrepareOptionsMenu(Menu menu) { public boolean onPrepareOptionsMenu(Menu menu) {
if (fileOpened && searchingText) { if (fileOpened && searchResult != null) {
MenuItem imReplace = menu.findItem(R.id.im_replace); MenuItem imReplace = menu.findItem(R.id.im_replace);
MenuItem imReplaceAll = menu.findItem(R.id.im_replace_all);
MenuItem imPrev = menu.findItem(R.id.im_previous_item); MenuItem imPrev = menu.findItem(R.id.im_previous_item);
MenuItem imNext = menu.findItem(R.id.im_next_item); MenuItem imNext = menu.findItem(R.id.im_next_item);
if (imReplace != null) if (imReplace != null)
imReplace.setVisible(searchResult.canReplaceSomething()); imReplace.setVisible(searchResult.canReplaceSomething());
if (imReplaceAll != null)
imReplaceAll.setVisible(searchResult.canReplaceSomething());
if (imPrev != null) if (imPrev != null)
imPrev.setVisible(searchResult.hasPrevious()); imPrev.setVisible(searchResult.hasPrevious());
@ -432,8 +426,11 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
Toast.makeText(getBaseContext(), "drawer click", Toast.LENGTH_SHORT).show(); Toast.makeText(getBaseContext(), "drawer click", Toast.LENGTH_SHORT).show();
mDrawerLayout.closeDrawer(Gravity.END); mDrawerLayout.closeDrawer(Gravity.END);
return true; return true;
} else if (i == R.id.im_save) { } else if (i == R.id.im_save_normaly) {
saveTheFile(); saveTheFile(false);
} else if (i == R.id.im_save_as) {
saveTheFile(true);
} else if (i == R.id.im_undo) { } else if (i == R.id.im_undo) {
mEditor.onTextContextMenuItem(ID_UNDO); mEditor.onTextContextMenuItem(ID_UNDO);
@ -445,11 +442,14 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
FindTextDialog.newInstance(mEditor.getText().toString()).show(getFragmentManager() FindTextDialog.newInstance(mEditor.getText().toString()).show(getFragmentManager()
.beginTransaction(), "dialog"); .beginTransaction(), "dialog");
} else if (i == R.id.im_cancel) { } else if (i == R.id.im_cancel) {
searchingText = false; searchResult = null;
invalidateOptionsMenu(); invalidateOptionsMenu();
} else if (i == R.id.im_replace) { } else if (i == R.id.im_replace) {
replaceText(); replaceText(false);
} else if (i == R.id.im_replace_all) {
replaceText(true);
} else if (i == R.id.im_next_item) { } else if (i == R.id.im_next_item) {
nextResult(); nextResult();
@ -475,27 +475,30 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
} else if (i == R.id.im_info) { } else if (i == R.id.im_info) {
FileInfoDialog.newInstance(sFilePath).show(getFragmentManager().beginTransaction(), "dialog"); FileInfoDialog.newInstance(sFilePath).show(getFragmentManager().beginTransaction(), "dialog");
} }
else if (i == R.id.im_donate) {
DialogHelper.showDonateDialog(this);
}
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
} }
//endregion //endregion
// region OTHER THINGS // region OTHER THINGS
void replaceText() { void replaceText(boolean all) {
int start = searchResult.foundIndex.get(searchResult.index); if (all) {
int end = start + searchResult.textLength; mEditor.setText(mEditor.getText().toString().replaceAll(searchResult.whatToSearch, searchResult.textToReplace));
mEditor.setText(mEditor.getText().replace(start, end, searchResult.textToReplace));
searchResult.doneReplace();
invalidateOptionsMenu(); searchResult = null;
invalidateOptionsMenu();
} else {
int start = searchResult.foundIndex.get(searchResult.index);
int end = start + searchResult.textLength;
mEditor.setText(mEditor.getText().replace(start, end, searchResult.textToReplace));
searchResult.doneReplace();
if (searchResult.hasNext()) invalidateOptionsMenu();
nextResult();
else if (searchResult.hasPrevious()) if (searchResult.hasNext())
previousResult(); nextResult();
else if (searchResult.hasPrevious())
previousResult();
}
} }
void nextResult() { void nextResult() {
@ -561,14 +564,18 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
invalidateOptionsMenu(); invalidateOptionsMenu();
} }
private void saveTheFile() { private void saveTheFile(boolean saveAs) {
File file = new File(sFilePath); File file = new File(sFilePath);
if (!file.getName().isEmpty()) if (!file.getName().isEmpty() && !saveAs)
new SaveFileTask(this, sFilePath, pageSystem.getAllText(mEditor.getText() new SaveFileTask(this, sFilePath, pageSystem.getAllText(mEditor.getText()
.toString()), currentEncoding).execute(); .toString()), currentEncoding).execute();
else { else {
NewFileDetailsDialog.newInstance NewFileDetailsDialog.newInstance(
(pageSystem.getAllText(mEditor.getText().toString()), currentEncoding).show(getFragmentManager().beginTransaction(), "dialog"); file.getParent(),
file.getName(),
pageSystem.getAllText(mEditor.getText().toString()),
currentEncoding
).show(getFragmentManager().beginTransaction(), "dialog");
} }
} }
@ -631,12 +638,6 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
verticalScroll.addView(mEditor); verticalScroll.addView(mEditor);
} }
if (PreferenceHelper.getReadOnly(this)) {
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
} else {
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED);
}
verticalScroll.setScrollInterface(this); verticalScroll.setScrollInterface(this);
pageSystem = new PageSystem(this, this, "", null); pageSystem = new PageSystem(this, this, "", null);
@ -655,7 +656,6 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
mEditor.resetVariables(); mEditor.resetVariables();
searchResult = null; searchResult = null;
searchingText = false;
invalidateOptionsMenu(); invalidateOptionsMenu();
@ -692,11 +692,11 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
|| Intent.ACTION_PICK.equals(action) || Intent.ACTION_PICK.equals(action)
&& type != null) { && type != null) {
// Post event // Post event
onEvent(new EventBusEvents.NewFileToOpen(new File(intent newFileToOpen(new File(intent
.getData().getPath()))); .getData().getPath()), "");
} else if (Intent.ACTION_SEND.equals(action) && type != null) { } else if (Intent.ACTION_SEND.equals(action) && type != null) {
if ("text/plain".equals(type)) { if ("text/plain".equals(type)) {
onEvent(new EventBusEvents.NewFileToOpen(intent.getStringExtra(Intent.EXTRA_TEXT))); newFileToOpen(null, intent.getStringExtra(Intent.EXTRA_TEXT));
} }
} }
} }
@ -784,11 +784,11 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
//endregion //endregion
//region EVENTBUS //region EVENTBUS
void onEvent(final EventBusEvents.NewFileToOpen event) { public void newFileToOpen(final File newFile, final String newFileText) {
if (fileOpened && mEditor.canSaveFile()) { if (fileOpened && mEditor.canSaveFile()) {
SaveFileDialog.newInstance(sFilePath, pageSystem.getAllText(mEditor SaveFileDialog.newInstance(sFilePath, pageSystem.getAllText(mEditor
.getText().toString()), currentEncoding, true, event.getFile().getAbsolutePath()).show(getFragmentManager(), .getText().toString()), currentEncoding, true, newFile.getAbsolutePath()).show(getFragmentManager(),
"dialog"); "dialog");
return; return;
} }
@ -814,10 +814,13 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
@Override @Override
protected Void doInBackground(Void... params) { protected Void doInBackground(Void... params) {
file = event.getFile(); file = newFile;
if (file == null) {
file = new File("");
}
try { try {
if (!file.exists() || !file.isFile()) { if (!file.exists() || !file.isFile()) {
fileText = event.getFileText(); fileText = newFileText;
sFilePath = file.getAbsolutePath(); sFilePath = file.getAbsolutePath();
fileExtension = "txt"; fileExtension = "txt";
return null; return null;
@ -839,7 +842,7 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
File tempFile = new File(getFilesDir(), "temp.root.file"); File tempFile = new File(getFilesDir(), "temp.root.file");
if (!tempFile.exists()) if (!tempFile.exists())
tempFile.createNewFile(); tempFile.createNewFile();
tb.copyFile(event.getFile().getAbsolutePath(), tb.copyFile(file.getAbsolutePath(),
tempFile.getAbsolutePath(), false, false); tempFile.getAbsolutePath(), false, false);
file = new File(tempFile.getAbsolutePath()); file = new File(tempFile.getAbsolutePath());
} }
@ -879,13 +882,13 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
if (!message.isEmpty()) { if (!message.isEmpty()) {
Toast.makeText(MainActivity.this, message, Toast.LENGTH_LONG).show(); Toast.makeText(MainActivity.this, message, Toast.LENGTH_LONG).show();
onEvent(new EventBusEvents.CannotOpenAFile()); cannotOpenFile();
} else { } else {
pageSystem = new PageSystem(MainActivity.this, MainActivity.this, fileText, new File(sFilePath)); pageSystem = new PageSystem(MainActivity.this, MainActivity.this, fileText, new File(sFilePath));
currentEncoding = encoding; currentEncoding = encoding;
onEvent(new EventBusEvents.AFileIsSelected(sFilePath)); aFileWasSelected(sFilePath);
showTextEditor(); showTextEditor();
@ -904,11 +907,13 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
}.execute(); }.execute();
} }
public void onEvent(EventBusEvents.SavedAFile event) { public void savedAFile(String filePath) {
sFilePath = event.getPath(); sFilePath = filePath;
fileExtension = FilenameUtils.getExtension(sFilePath).toLowerCase(); fileExtension = FilenameUtils.getExtension(sFilePath).toLowerCase();
toolbar.setTitle(FilenameUtils.getName(sFilePath));
mEditor.clearHistory(); mEditor.clearHistory();
mEditor.fileSaved(); mEditor.fileSaved();
invalidateOptionsMenu(); invalidateOptionsMenu();
@ -919,10 +924,8 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
e.printStackTrace(); e.printStackTrace();
} }
refreshList(event.getPath(), true, false); refreshList(filePath, true, false);
arrayAdapter.selectView(event.getPath()); arrayAdapter.selectView(filePath);
showInterstitial();
} }
/** /**
@ -931,7 +934,7 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
* *
* @param event The event called * @param event The event called
*/ */
void onEvent(EventBusEvents.CannotOpenAFile event) { public void cannotOpenFile() {
// //
mDrawerLayout.openDrawer(Gravity.LEFT); mDrawerLayout.openDrawer(Gravity.LEFT);
// //
@ -942,13 +945,17 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
hideTextEditor(); hideTextEditor();
} }
public void onEvent(EventBusEvents.APreferenceValueWasChanged event) { public void aPreferenceValueWasChanged(final PreferenceChangeType type) {
this.aPreferenceValueWasChanged(new ArrayList<PreferenceChangeType>() {{add(type);}});
}
if (event.hasType(EventBusEvents.APreferenceValueWasChanged.Type.THEME_CHANGE)) { public void aPreferenceValueWasChanged(List<PreferenceChangeType> types) {
if (types.contains(PreferenceChangeType.THEME_CHANGE)) {
ThemeUtils.setWindowsBackground(this); ThemeUtils.setWindowsBackground(this);
} }
if (event.hasType(WRAP_CONTENT)) { if (types.contains(PreferenceChangeType.WRAP_CONTENT)) {
if (PreferenceHelper.getWrapContent(this)) { if (PreferenceHelper.getWrapContent(this)) {
horizontalScroll.removeView(mEditor); horizontalScroll.removeView(mEditor);
verticalScroll.removeView(horizontalScroll); verticalScroll.removeView(horizontalScroll);
@ -958,41 +965,42 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
verticalScroll.addView(horizontalScroll); verticalScroll.addView(horizontalScroll);
horizontalScroll.addView(mEditor); horizontalScroll.addView(mEditor);
} }
} else if (event.hasType(LINE_NUMERS)) { } else if (types.contains(PreferenceChangeType.LINE_NUMERS)) {
mEditor.disableTextChangedListener(); mEditor.disableTextChangedListener();
mEditor.replaceTextKeepCursor(null, true); mEditor.replaceTextKeepCursor(null, true);
mEditor.enableTextChangedListener(); mEditor.enableTextChangedListener();
if (PreferenceHelper.getLineNumbers(this)) { if (PreferenceHelper.getLineNumbers(this)) {
mEditor.setPadding(EditTextPadding.getPaddingWithLineNumbers(this, mEditor.setPadding(
PreferenceHelper.getFontSize(this)), EditTextPadding.getPaddingWithLineNumbers(this, PreferenceHelper.getFontSize(this)),
EditTextPadding.getPaddingTop(this), 0, 0); EditTextPadding.getPaddingTop(this),
EditTextPadding.getPaddingTop(this),
0);
} else { } else {
mEditor.setPadding(EditTextPadding.getPaddingWithoutLineNumbers(this) mEditor.setPadding(
, EditTextPadding.getPaddingTop(this), 0, 0); EditTextPadding.getPaddingWithoutLineNumbers(this),
EditTextPadding.getPaddingTop(this),
EditTextPadding.getPaddingTop(this),
0);
} }
} else if (event.hasType(SYNTAX)) { } else if (types.contains(PreferenceChangeType.SYNTAX)) {
mEditor.disableTextChangedListener(); mEditor.disableTextChangedListener();
mEditor.replaceTextKeepCursor(null, true); mEditor.replaceTextKeepCursor(null, true);
mEditor.enableTextChangedListener(); mEditor.enableTextChangedListener();
} else if (event.hasType(MONOSPACE)) { } else if (types.contains(PreferenceChangeType.MONOSPACE)) {
if (PreferenceHelper.getUseMonospace(this)) if (PreferenceHelper.getUseMonospace(this))
mEditor.setTypeface(Typeface.MONOSPACE); mEditor.setTypeface(Typeface.MONOSPACE);
else else
mEditor.setTypeface(Typeface.DEFAULT); mEditor.setTypeface(Typeface.DEFAULT);
} else if (event.hasType(THEME_CHANGE)) { } else if (types.contains(PreferenceChangeType.THEME_CHANGE)) {
if (PreferenceHelper.getLightTheme(this)) { if (PreferenceHelper.getLightTheme(this)) {
mEditor.setTextColor(getResources().getColor(R.color.textColorInverted)); mEditor.setTextColor(getResources().getColor(R.color.textColorInverted));
} else { } else {
mEditor.setTextColor(getResources().getColor(R.color.textColor)); mEditor.setTextColor(getResources().getColor(R.color.textColor));
} }
} else if (event.hasType(TEXT_SUGGESTIONS) || event.hasType(READ_ONLY)) { } else if (types.contains(PreferenceChangeType.TEXT_SUGGESTIONS) || types.contains(PreferenceChangeType.READ_ONLY)) {
if (PreferenceHelper.getReadOnly(this)) { if (PreferenceHelper.getReadOnly(this)) {
getWindow().setSoftInputMode(WindowManager.LayoutParams
.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
mEditor.setReadOnly(true); mEditor.setReadOnly(true);
} else { } else {
getWindow().setSoftInputMode(WindowManager.LayoutParams
.SOFT_INPUT_STATE_UNSPECIFIED);
mEditor.setReadOnly(false); mEditor.setReadOnly(false);
if (PreferenceHelper.getSuggestionActive(this)) { if (PreferenceHelper.getSuggestionActive(this)) {
mEditor.setInputType(InputType.TYPE_CLASS_TEXT | InputType mEditor.setInputType(InputType.TYPE_CLASS_TEXT | InputType
@ -1009,17 +1017,22 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
mEditor.setTypeface(Typeface.MONOSPACE); mEditor.setTypeface(Typeface.MONOSPACE);
else else
mEditor.setTypeface(Typeface.DEFAULT); mEditor.setTypeface(Typeface.DEFAULT);
} else if (event.hasType(FONT_SIZE)) { } else if (types.contains(PreferenceChangeType.FONT_SIZE)) {
if (PreferenceHelper.getLineNumbers(this)) { if (PreferenceHelper.getLineNumbers(this)) {
mEditor.setPadding(EditTextPadding.getPaddingWithLineNumbers(this, mEditor.setPadding(
PreferenceHelper.getFontSize(this)), EditTextPadding.getPaddingWithLineNumbers(this, PreferenceHelper.getFontSize(this)),
EditTextPadding.getPaddingTop(this), 0, 0); EditTextPadding.getPaddingTop(this),
EditTextPadding.getPaddingTop(this),
0);
} else { } else {
mEditor.setPadding(EditTextPadding.getPaddingWithoutLineNumbers(this) mEditor.setPadding(
, EditTextPadding.getPaddingTop(this), 0, 0); EditTextPadding.getPaddingWithoutLineNumbers(this),
EditTextPadding.getPaddingTop(this),
EditTextPadding.getPaddingTop(this),
0);
} }
mEditor.setTextSize(PreferenceHelper.getFontSize(this)); mEditor.setTextSize(PreferenceHelper.getFontSize(this));
} else if (event.hasType(ENCODING)) { } else if (types.contains(PreferenceChangeType.ENCODING)) {
String oldEncoding, newEncoding; String oldEncoding, newEncoding;
oldEncoding = currentEncoding; oldEncoding = currentEncoding;
newEncoding = PreferenceHelper.getEncoding(this); newEncoding = PreferenceHelper.getEncoding(this);
@ -1033,7 +1046,7 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
try { try {
final byte[] oldText = mEditor.getText().toString().getBytes(oldEncoding); final byte[] oldText = mEditor.getText().toString().getBytes(oldEncoding);
mEditor.disableTextChangedListener(); mEditor.disableTextChangedListener();
mEditor.replaceTextKeepCursor(new String(oldText, "UTF-8"), true); mEditor.replaceTextKeepCursor(new String(oldText, "UTF-16"), true);
mEditor.enableTextChangedListener(); mEditor.enableTextChangedListener();
} catch (UnsupportedEncodingException ignored2) { } catch (UnsupportedEncodingException ignored2) {
} }
@ -1041,24 +1054,43 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
} }
} }
void onEvent(EventBusEvents.AFileIsSelected event) { public void aFileWasSelected(String filePath) {
arrayAdapter.selectView(event.getPath()); arrayAdapter.selectView(filePath);
} }
void onEvent(EventBusEvents.ClosedAFile event) { public void closedTheFile() {
arrayAdapter.selectView(""); arrayAdapter.selectView("");
} }
//endregion //endregion
//region Calls from the layout //region Calls from the layout
public void OpenFile(View view) { public void OpenFile(View view) {
Intent subActivity = new Intent(MainActivity.this, SelectFileActivity.class);
subActivity.putExtra("action", SelectFileActivity.Actions.SelectFile); // if (Device.hasKitKatApi()) {
AnimationUtils.startActivityWithScale(this, subActivity, true, SELECT_FILE_CODE, view); // // ACTION_OPEN_DOCUMENT is the intent to choose a file via the system's file
// // browser.
// Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
//
// // Filter to only show results that can be "opened", such as a
// // file (as opposed to a list of contacts or timezones)
// //intent.addCategory(Intent.CATEGORY_OPENABLE);
//
// // Filter to show only images, using the image MIME data type.
// // If one wanted to search for ogg vorbis files, the type would be "audio/ogg".
// // To search for all documents available via installed storage providers,
// // it would be "*/*".
// intent.setType("*/*");
//
// startActivityForResult(intent, READ_REQUEST_CODE);
// } else {
Intent subActivity = new Intent(MainActivity.this, SelectFileActivity.class);
subActivity.putExtra("action", SelectFileActivity.Actions.SelectFile);
AnimationUtils.startActivityWithScale(this, subActivity, true, SELECT_FILE_CODE, view);
// }
} }
public void CreateFile(View view) { public void CreateFile(View view) {
onEvent(new EventBusEvents.NewFileToOpen("")); // do not send the event to others newFileToOpen(null, ""); // do not send the event to others
} }
public void OpenInfo(View view) { public void OpenInfo(View view) {
@ -1137,7 +1169,6 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
@Override @Override
public void onSearchDone(SearchResult searchResult) { public void onSearchDone(SearchResult searchResult) {
MainActivity.searchResult = searchResult; MainActivity.searchResult = searchResult;
searchingText = true;
invalidateOptionsMenu(); invalidateOptionsMenu();
final int line = LineUtils.getLineFromIndex(searchResult.foundIndex.getFirst final int line = LineUtils.getLineFromIndex(searchResult.foundIndex.getFirst
@ -1165,7 +1196,7 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
@Override @Override
public void onPageChanged(int page) { public void onPageChanged(int page) {
pageSystemButtons.updateVisibility(false); pageSystemButtons.updateVisibility(false);
searchingText = false; searchResult = null;
mEditor.clearHistory(); mEditor.clearHistory();
invalidateOptionsMenu(); invalidateOptionsMenu();
} }
@ -1175,7 +1206,7 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
pageSystemButtons.updateVisibility(Math.abs(t) > 10); pageSystemButtons.updateVisibility(Math.abs(t) > 10);
if (!PreferenceHelper.getSyntaxHighlight(this) || (mEditor.hasSelection() && if (!PreferenceHelper.getSyntaxHighlight(this) || (mEditor.hasSelection() &&
!searchingText) || updateHandler == null || colorRunnable_duringScroll == null) searchResult == null) || updateHandler == null || colorRunnable_duringScroll == null)
return; return;
updateHandler.removeCallbacks(colorRunnable_duringEditing); updateHandler.removeCallbacks(colorRunnable_duringEditing);
@ -1219,16 +1250,16 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
public void userDoesntWantToSave(boolean openNewFile, String pathOfNewFile) { public void userDoesntWantToSave(boolean openNewFile, String pathOfNewFile) {
Editor.canSaveFile = false; Editor.canSaveFile = false;
if(openNewFile) if(openNewFile)
onEvent(new EventBusEvents.NewFileToOpen(new File(pathOfNewFile))); newFileToOpen(new File(pathOfNewFile), "");
else else
onEvent(new EventBusEvents.CannotOpenAFile()); cannotOpenFile();
} }
@Override @Override
public void CancelItem(int position, boolean andCloseOpenedFile) { public void CancelItem(int position, boolean andCloseOpenedFile) {
refreshList(files.get(position).getAbsolutePath(), false, true); refreshList(files.get(position).getAbsolutePath(), false, true);
if (andCloseOpenedFile) if (andCloseOpenedFile)
onEvent(new EventBusEvents.CannotOpenAFile()); cannotOpenFile();
} }
//endregion //endregion
@ -1271,11 +1302,11 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
private static int firstVisibleIndex, firstColoredIndex; private static int firstVisibleIndex, firstColoredIndex;
private static int deviceHeight; private static int deviceHeight;
private static int editorHeight; private static int editorHeight;
private static boolean[] hasNewLineArray; private static boolean[] isGoodLineArray;
private static int[] realLines; private static int[] realLines;
private static boolean wrapContent; private static boolean wrapContent;
private static int lastLine; //private static int lastLine;
private static int firstLine; //private static int firstLine;
private static CharSequence textToHighlight; private static CharSequence textToHighlight;
private static int lastVisibleIndex; private static int lastVisibleIndex;
private static int i; private static int i;
@ -1306,12 +1337,17 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
setTextColor(getResources().getColor(R.color.textColor)); setTextColor(getResources().getColor(R.color.textColor));
} }
if (PreferenceHelper.getLineNumbers(getContext())) { if (PreferenceHelper.getLineNumbers(getContext())) {
setPadding(EditTextPadding.getPaddingWithLineNumbers(getContext(), setPadding(
PreferenceHelper.getFontSize(getContext())), EditTextPadding.getPaddingWithLineNumbers(getContext(), PreferenceHelper.getFontSize(getContext())),
EditTextPadding.getPaddingTop(getContext()), 0, 0); EditTextPadding.getPaddingTop(getContext()),
EditTextPadding.getPaddingTop(getContext()),
0);
} else { } else {
setPadding(EditTextPadding.getPaddingWithoutLineNumbers(getContext()), setPadding(
EditTextPadding.getPaddingTop(getContext()), 0, 0); EditTextPadding.getPaddingWithoutLineNumbers(getContext()),
EditTextPadding.getPaddingTop(getContext()),
EditTextPadding.getPaddingTop(getContext()),
0);
} }
if (PreferenceHelper.getReadOnly(getContext())) { if (PreferenceHelper.getReadOnly(getContext())) {
@ -1397,24 +1433,20 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
lineUtils.updateHasNewLineArray(pageSystem lineUtils.updateHasNewLineArray(pageSystem
.getStartingLine(), lineCount, getLayout(), getText().toString()); .getStartingLine(), lineCount, getLayout(), getText().toString());
hasNewLineArray = lineUtils.getToCountLinesArray(); isGoodLineArray = lineUtils.getGoodLines();
realLines = lineUtils.getRealLines(); realLines = lineUtils.getRealLines();
} }
editorHeight = getHeight(); //editorHeight = getHeight();
firstLine = lineUtils.getFirstVisibleLine(verticalScroll, editorHeight, lineCount);
lastLine = lineUtils.getLastVisibleLine(verticalScroll, editorHeight, lineCount, deviceHeight);
if (PreferenceHelper.getLineNumbers(getContext())) { if (PreferenceHelper.getLineNumbers(getContext())) {
wrapContent = PreferenceHelper.getWrapContent(getContext()); wrapContent = PreferenceHelper.getWrapContent(getContext());
i = firstLine;
while (i < lastLine) { for (i = 0; i < lineCount; i++) {
// if last line we count it anyway // if last line we count it anyway
if (!wrapContent if (!wrapContent
|| hasNewLineArray[i] || isGoodLineArray[i]) {
|| i == lastLine - 1) {
realLine = realLines[i]; realLine = realLines[i];
canvas.drawText(String.valueOf(realLine), canvas.drawText(String.valueOf(realLine),
@ -1422,7 +1454,6 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
paddingTop + lineHeight * (i + 1), paddingTop + lineHeight * (i + 1),
mPaintNumbers); mPaintNumbers);
} }
i++;
} }
} }
@ -1456,7 +1487,7 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
return onTextContextMenuItem(ID_REDO); return onTextContextMenuItem(ID_REDO);
} }
case KeyEvent.KEYCODE_S: case KeyEvent.KEYCODE_S:
((MainActivity) getContext()).saveTheFile(); ((MainActivity) getContext()).saveTheFile(false);
return true; return true;
default: default:
return super.onKeyDown(keyCode, event); return super.onKeyDown(keyCode, event);
@ -1638,20 +1669,23 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
cursorPos = getSelectionStart(); cursorPos = getSelectionStart();
cursorPosEnd = getSelectionEnd(); cursorPosEnd = getSelectionEnd();
} }
disableTextChangedListener(); disableTextChangedListener();
if (PreferenceHelper.getSyntaxHighlight(getContext())) if (PreferenceHelper.getSyntaxHighlight(getContext())) {
setText(highlight(textToUpdate == null ? getEditableText() : Editable.Factory setText(highlight(textToUpdate == null ? getEditableText() : Editable.Factory
.getInstance().newEditable(textToUpdate), textToUpdate != null)); .getInstance().newEditable(textToUpdate), textToUpdate != null));
else }
setText(textToUpdate == null ? getText().toString() : textToUpdate); else {
setText(textToUpdate == null ? getEditableText() : textToUpdate);
}
enableTextChangedListener(); enableTextChangedListener();
if (mantainCursorPos) if (mantainCursorPos)
firstVisibleIndex = cursorPos; firstVisibleIndex = cursorPos;
if (firstVisibleIndex > -1) { if (firstVisibleIndex > -1 && firstVisibleIndex < length()) {
if (cursorPosEnd != cursorPos) if (cursorPosEnd != cursorPos)
setSelection(cursorPos, cursorPosEnd); setSelection(cursorPos, cursorPosEnd);
else else
@ -1667,7 +1701,7 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
removeTextChangedListener(mChangeListener); removeTextChangedListener(mChangeListener);
} }
public CharSequence highlight(Editable editable, boolean newText) { public Editable highlight(Editable editable, boolean newText) {
editable.clearSpans(); editable.clearSpans();
if (editable.length() == 0) { if (editable.length() == 0) {
@ -1677,10 +1711,8 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
editorHeight = getHeight(); editorHeight = getHeight();
if (!newText && editorHeight > 0) { if (!newText && editorHeight > 0) {
firstLine = lineUtils.getFirstVisibleLine(verticalScroll, editorHeight, lineCount); firstVisibleIndex = getLayout().getLineStart(lineUtils.getFirstVisibleLine(verticalScroll, editorHeight, lineCount));
lastLine = lineUtils.getLastVisibleLine(verticalScroll, editorHeight, lineCount, deviceHeight); lastVisibleIndex = getLayout().getLineStart(lineUtils.getLastVisibleLine(verticalScroll, editorHeight, lineCount, deviceHeight));
firstVisibleIndex = getLayout().getLineStart(firstLine);
lastVisibleIndex = getLayout().getLineStart(lastLine);
} else { } else {
firstVisibleIndex = 0; firstVisibleIndex = 0;
lastVisibleIndex = CHARS_TO_COLOR; lastVisibleIndex = CHARS_TO_COLOR;
@ -1701,8 +1733,7 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
if (fileExtension.contains("htm") if (fileExtension.contains("htm")
|| fileExtension.contains("xml")) { || fileExtension.contains("xml")) {
color(Patterns.HTML_OPEN_TAGS, editable, textToHighlight, firstColoredIndex); color(Patterns.HTML_TAGS, editable, textToHighlight, firstColoredIndex);
color(Patterns.HTML_CLOSE_TAGS, editable, textToHighlight, firstColoredIndex);
color(Patterns.HTML_ATTRS, editable, textToHighlight, firstColoredIndex); color(Patterns.HTML_ATTRS, editable, textToHighlight, firstColoredIndex);
color(Patterns.GENERAL_STRINGS, editable, textToHighlight, firstColoredIndex); color(Patterns.GENERAL_STRINGS, editable, textToHighlight, firstColoredIndex);
color(Patterns.XML_COMMENTS, editable, textToHighlight, firstColoredIndex); color(Patterns.XML_COMMENTS, editable, textToHighlight, firstColoredIndex);
@ -1768,8 +1799,7 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
CharSequence textToHighlight, CharSequence textToHighlight,
int start) { int start) {
int color = 0; int color = 0;
if (pattern.equals(Patterns.HTML_OPEN_TAGS) if (pattern.equals(Patterns.HTML_TAGS)
|| pattern.equals(Patterns.HTML_CLOSE_TAGS)
|| pattern.equals(Patterns.GENERAL_KEYWORDS) || pattern.equals(Patterns.GENERAL_KEYWORDS)
|| pattern.equals(Patterns.SQL_KEYWORDS) || pattern.equals(Patterns.SQL_KEYWORDS)
|| pattern.equals(Patterns.PY_KEYWORDS) || pattern.equals(Patterns.PY_KEYWORDS)

View File

@ -60,6 +60,7 @@ public class EncodingDialog extends DialogFragment implements AdapterView.OnItem
Constants.CHARSET_UTF_32BE, Constants.CHARSET_UTF_32BE,
Constants.CHARSET_UTF_32LE, Constants.CHARSET_UTF_32LE,
Constants.CHARSET_UTF_8, Constants.CHARSET_UTF_8,
"UTF-16",
Constants.CHARSET_WINDOWS_1251, Constants.CHARSET_WINDOWS_1251,
Constants.CHARSET_WINDOWS_1252, Constants.CHARSET_WINDOWS_1252,
Constants.CHARSET_WINDOWS_1253, Constants.CHARSET_WINDOWS_1253,

View File

@ -193,7 +193,7 @@ public class FindTextDialog extends DialogFragment {
return; return;
// else we return positions and other things // else we return positions and other things
else { else {
SearchResult searchResult = new SearchResult(foundIndex, textToFind.length(), replaceCheck.isChecked(), textToReplace.getText().toString()); SearchResult searchResult = new SearchResult(foundIndex, textToFind.length(), replaceCheck.isChecked(), textToFind.getText().toString(), textToReplace.getText().toString());
searchDialogInterface.onSearchDone(searchResult); searchDialogInterface.onSearchDone(searchResult);
} }
} else { } else {

View File

@ -24,16 +24,21 @@ import android.app.Dialog;
import android.app.DialogFragment; import android.app.DialogFragment;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.os.Bundle; import android.os.Bundle;
import android.text.TextUtils;
import android.view.View; import android.view.View;
import android.view.WindowManager; import android.view.WindowManager;
import android.widget.CheckBox;
import android.widget.EditText; import android.widget.EditText;
import org.apache.commons.io.FileUtils;
import java.io.File; import java.io.File;
import sharedcode.turboeditor.R; import sharedcode.turboeditor.R;
import sharedcode.turboeditor.activity.MainActivity; import sharedcode.turboeditor.activity.MainActivity;
import sharedcode.turboeditor.preferences.PreferenceHelper; import sharedcode.turboeditor.preferences.PreferenceHelper;
import sharedcode.turboeditor.task.SaveFileTask; import sharedcode.turboeditor.task.SaveFileTask;
import sharedcode.turboeditor.util.ViewUtils;
import sharedcode.turboeditor.views.DialogHelper; import sharedcode.turboeditor.views.DialogHelper;
// ... // ...
@ -41,10 +46,13 @@ public class NewFileDetailsDialog extends DialogFragment {
private EditText mName; private EditText mName;
private EditText mFolder; private EditText mFolder;
private CheckBox mDeleteCurrentFile;
public static NewFileDetailsDialog newInstance(String fileText, String fileEncoding) { public static NewFileDetailsDialog newInstance(String currentPath, String currentName, String fileText, String fileEncoding) {
final NewFileDetailsDialog f = new NewFileDetailsDialog(); final NewFileDetailsDialog f = new NewFileDetailsDialog();
final Bundle args = new Bundle(); final Bundle args = new Bundle();
args.putString("path", currentPath);
args.putString("name", currentName);
args.putString("fileText", fileText); args.putString("fileText", fileText);
args.putString("fileEncoding", fileEncoding); args.putString("fileEncoding", fileEncoding);
f.setArguments(args); f.setArguments(args);
@ -55,15 +63,29 @@ public class NewFileDetailsDialog extends DialogFragment {
public Dialog onCreateDialog(Bundle savedInstanceState) { public Dialog onCreateDialog(Bundle savedInstanceState) {
View view = new DialogHelper.Builder(getActivity()) View view = new DialogHelper.Builder(getActivity())
.setTitle(R.string.file) .setTitle(R.string.save_as)
.setView(R.layout.dialog_fragment_new_file_details) .setView(R.layout.dialog_fragment_new_file_details)
.createSkeletonView(); .createSkeletonView();
this.mName = (EditText) view.findViewById(android.R.id.text1); this.mName = (EditText) view.findViewById(android.R.id.text1);
this.mFolder = (EditText) view.findViewById(android.R.id.text2); this.mFolder = (EditText) view.findViewById(android.R.id.text2);
this.mName.setText(".txt"); boolean noName = TextUtils.isEmpty(getArguments().getString("name"));
this.mFolder.setText(PreferenceHelper.getWorkingFolder(getActivity())); boolean noPath = TextUtils.isEmpty(getArguments().getString("path"));
if (noName) {
this.mName.setText(".txt");
} else {
this.mName.setText(getArguments().getString("name"));
}
if (noPath) {
this.mFolder.setText(PreferenceHelper.getWorkingFolder(getActivity()));
} else {
this.mFolder.setText(getArguments().getString("path"));
}
this.mDeleteCurrentFile = (CheckBox) view.findViewById(R.id.delete_current_file);
ViewUtils.setVisible(mDeleteCurrentFile, !noName);
// Show soft keyboard automatically // Show soft keyboard automatically
this.mName.requestFocus(); this.mName.requestFocus();
@ -76,6 +98,11 @@ public class NewFileDetailsDialog extends DialogFragment {
new DialogInterface.OnClickListener() { new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
if (mDeleteCurrentFile.isChecked()) {
FileUtils.deleteQuietly(new File(getArguments().getString("path"), getArguments().getString("name")));
}
if (!mName.getText().toString().isEmpty() && !mFolder.getText().toString().isEmpty()) { if (!mName.getText().toString().isEmpty() && !mFolder.getText().toString().isEmpty()) {
File file = new File(mFolder.getText().toString(), mName.getText().toString()); File file = new File(mFolder.getText().toString(), mName.getText().toString());
new SaveFileTask((MainActivity) getActivity(), file.getPath(), getArguments().getString("fileText"), getArguments().getString("fileEncoding")).execute(); new SaveFileTask((MainActivity) getActivity(), file.getPath(), getArguments().getString("fileText"), getArguments().getString("fileEncoding")).execute();

View File

@ -80,7 +80,7 @@ public class SaveFileDialog extends DialogFragment {
encoding).execute(); encoding).execute();
else { else {
NewFileDetailsDialog dialogFrag = NewFileDetailsDialog dialogFrag =
NewFileDetailsDialog.newInstance(text, NewFileDetailsDialog.newInstance("","",text,
encoding); encoding);
dialogFrag.show(getFragmentManager().beginTransaction(), dialogFrag.show(getFragmentManager().beginTransaction(),
"dialog"); "dialog");

View File

@ -1,78 +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 sharedcode.turboeditor.iab;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
/**
* The helper class of donation item.
*
* @author Artem Chepurnoy
*/
public class Donation {
public final int amount;
public final String sku;
public final String text;
public Donation(int amount, String text) {
this.amount = amount;
this.text = text;
// Notice that all of them are defined in
// my Play Store's account!
this.sku = "donation_" + amount;
}
/**
* {@inheritDoc}
*/
@Override
public int hashCode() {
return new HashCodeBuilder(9, 51)
.append(amount)
.append(text)
.append(sku)
.toHashCode();
}
/**
* {@inheritDoc}
*/
@Override
public boolean equals(Object o) {
if (o == null)
return false;
if (o == this)
return true;
if (!(o instanceof Donation))
return false;
Donation donation = (Donation) o;
return new EqualsBuilder()
.append(amount, donation.amount)
.append(text, donation.text)
.append(sku, donation.sku)
.isEquals();
}
}

View File

@ -1,98 +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 sharedcode.turboeditor.iab;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Paint;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import java.util.HashSet;
import sharedcode.turboeditor.R;
/**
* Created by achep on 06.05.14 for AcDisplay.
*
* @author Artem Chepurnoy
*/
public class DonationAdapter extends ArrayAdapter<Donation> {
private final HashSet<String> mInventorySet;
private final LayoutInflater mInflater;
private final String mDonationAmountLabel;
private final int mColorNormal;
private final int mColorPurchased;
public DonationAdapter(Context context, Donation[] items, HashSet<String> inventory) {
super(context, 0, items);
mInventorySet = inventory;
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
Resources res = context.getResources();
mDonationAmountLabel = res.getString(R.string.donation_item_label);
mColorNormal = res.getColor(R.color.donation_normal);
mColorPurchased = res.getColor(R.color.donation_purchased);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final Donation donation = getItem(position);
final Holder holder;
final View view;
if (convertView == null) {
holder = new Holder();
view = mInflater.inflate(R.layout.donation_iab_item, parent, false);
assert view != null;
holder.title = (TextView) view.findViewById(android.R.id.title);
holder.summary = (TextView) view.findViewById(android.R.id.summary);
view.setTag(holder);
} else {
view = convertView;
holder = (Holder) view.getTag();
}
boolean bought = mInventorySet.contains(donation.sku);
String amount = Integer.toString(donation.amount);
holder.title.setText(String.format(mDonationAmountLabel, amount));
holder.title.setTextColor(bought ? mColorNormal : mColorPurchased);
holder.summary.setText(donation.text);
holder.summary.setPaintFlags(bought
? holder.summary.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG
: holder.summary.getPaintFlags() & (~Paint.STRIKE_THRU_TEXT_FLAG));
return view;
}
private static class Holder {
TextView title;
TextView summary;
}
}

View File

@ -1,370 +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 sharedcode.turboeditor.iab;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.ActivityNotFoundException;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.text.Html;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.method.LinkMovementMethod;
import android.text.style.ImageSpan;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.GridView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import java.util.HashSet;
import sharedcode.turboeditor.R;
import sharedcode.turboeditor.iab.utils.IabHelper;
import sharedcode.turboeditor.iab.utils.IabResult;
import sharedcode.turboeditor.iab.utils.Inventory;
import sharedcode.turboeditor.iab.utils.Purchase;
import sharedcode.turboeditor.preferences.PreferenceHelper;
import sharedcode.turboeditor.util.Build;
import sharedcode.turboeditor.util.ToastUtils;
import sharedcode.turboeditor.util.ViewUtils;
import sharedcode.turboeditor.views.DialogHelper;
/**
* Fragment that represents an ability to donate to me. Be sure to redirect
* {@link android.app.Activity#onActivityResult(int, int, android.content.Intent)}
* to this fragment!
*
* @author Artem Chepurnoy
*/
public class DonationFragment extends DialogFragment {
public static final int RC_REQUEST = 10001;
private static final String TAG = "DonationFragment";
private final HashSet<String> mInventorySet = new HashSet<>();
private GridView mGridView;
private ProgressBar mProgressBar;
private TextView mError;
private IabHelper mHelper;
private final IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener =
new IabHelper.OnIabPurchaseFinishedListener() {
public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
if (mHelper == null) return;
if (result.isFailure()) {
complain("Error purchasing: " + result);
setWaitScreen(false);
return;
}
if (!verifyDeveloperPayload(purchase)) {
complain("Error purchasing. Authenticity verification failed.");
setWaitScreen(false);
return;
}
// else, it is a success, the user has donated!
String sku = purchase.getSku();
mInventorySet.add(sku);
PreferenceHelper.setHasDonated(getActivity(), true);
}
};
private Donation[] mDonationList;
private final IabHelper.QueryInventoryFinishedListener mGotInventoryListener =
new IabHelper.QueryInventoryFinishedListener() {
public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
if (mHelper == null) return;
if (result.isFailure()) {
complain("Failed to query inventory: " + result);
return;
}
mInventorySet.clear();
for (Donation donation : mDonationList) {
Purchase purchase = inventory.getPurchase(donation.sku);
boolean isBought = (purchase != null && verifyDeveloperPayload(purchase));
if (isBought) {
mInventorySet.add(donation.sku);
PreferenceHelper.setHasDonated(getActivity(), true);
}
}
/*
// Fake items to debug user interface.
mInventorySet.add(mDonationList[0].sku);
mInventorySet.add(mDonationList[1].sku);
mInventorySet.add(mDonationList[2].sku);
*/
updateUi();
setWaitScreen(false);
}
};
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mDonationList = DonationItems.get(getResources());
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Activity activity = getActivity();
assert activity != null;
View view = new DialogHelper.Builder(activity)
.setTitle(R.string.donation_title)
.setView(R.layout.donation_dialog)
.createSkeletonView();
AlertDialog.Builder builder = new AlertDialog.Builder(activity)
.setView(view)
.setNegativeButton(android.R.string.cancel, null);
TextView info = (TextView) view.findViewById(R.id.info);
info.setText(Html.fromHtml(getString(R.string.donation_info)));
info.setMovementMethod(new LinkMovementMethod());
mError = (TextView) view.findViewById(R.id.error);
mProgressBar = (ProgressBar) view.findViewById(android.R.id.progress);
mGridView = (GridView) view.findViewById(R.id.grid);
mGridView.setAdapter(new DonationAdapter(getActivity(), mDonationList, mInventorySet));
mGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
DonationAdapter adapter = (DonationAdapter) parent.getAdapter();
Donation donation = adapter.getItem(position);
if (!mInventorySet.contains(donation.sku)) {
/**
* See {@link sharedcode.turboeditor.iab.DonationFragment#verifyDeveloperPayload(Purchase)}.
*/
String payload = "";
try {
mHelper.launchPurchaseFlow(
getActivity(), donation.sku, RC_REQUEST,
mPurchaseFinishedListener, payload);
} catch (Exception e) {
ToastUtils.showShort(getActivity(), "Failed to launch a purchase flow.");
}
} else {
ToastUtils.showShort(getActivity(), getString(R.string.donation_item_bought));
}
}
});
final AlertDialog alertDialog;
// Show PayPal button.
final Intent paypalIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(Build.Links.DONATE));
builder.setNeutralButton(R.string.paypal, null);
alertDialog = builder.create();
alertDialog.setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
Data[] datas = new Data[]{
new Data(
alertDialog.getButton(DialogInterface.BUTTON_NEUTRAL),
paypalIntent, R.drawable.ic_action_paypal)
};
ImageSpan span;
SpannableString text;
for (final Data data : datas) {
final Button btn = data.button;
if (btn != null) {
span = new ImageSpan(getActivity(), data.iconResource);
// Replace text with an icon.
// This is a workaround to fix compound button's aligment.
text = new SpannableString(" ");
text.setSpan(span, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
btn.setText(text);
// Eat default weight.
btn.setLayoutParams(new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startPaymentIntentWithWarningAlertDialog(data.intent);
}
});
}
}
}
final class Data {
private final Button button;
private final Intent intent;
private final int iconResource;
private Data(Button button, Intent intent, int iconResource) {
this.button = button;
this.intent = intent;
this.iconResource = iconResource;
}
}
});
initBilling();
return alertDialog;
}
/**
* Shows a warning alert dialog to note, that those methods
* may suck hard and nobody will care about it.<br/>
* Starts an intent if user is agree with it.
*/
private void startPaymentIntentWithWarningAlertDialog(final Intent intent) {
CharSequence messageText = getString(R.string.donation_no_responsibility);
new DialogHelper.Builder(getActivity())
.setMessage(messageText)
.wrap()
.setNegativeButton(android.R.string.cancel, null)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
try {
startActivity(intent);
dismiss(); // Dismiss main fragment
} catch (ActivityNotFoundException e) { /* hell no */ }
}
})
.create()
.show();
}
private void setWaitScreen(boolean loading) {
ViewUtils.setVisible(mProgressBar, loading);
ViewUtils.setVisible(mGridView, !loading);
ViewUtils.setVisible(mError, false);
}
private void setErrorScreen(String errorMessage, final Runnable runnable) {
mProgressBar.setVisibility(View.GONE);
mGridView.setVisibility(View.GONE);
mError.setVisibility(View.VISIBLE);
mError.setText(errorMessage);
mError.setOnClickListener(runnable != null ? new View.OnClickListener() {
@Override
public void onClick(View v) {
runnable.run();
}
} : null);
}
/**
* Updates GUI to display changes.
*/
private void updateUi() {
DonationAdapter adapter = (DonationAdapter) mGridView.getAdapter();
adapter.notifyDataSetChanged();
}
@Override
public void onDestroy() {
super.onDestroy();
disposeBilling();
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (mHelper.handleActivityResult(requestCode, resultCode, data)) {
return;
}
super.onActivityResult(requestCode, resultCode, data);
}
/**
* Releases billing service.
*
* @see #initBilling()
*/
private void disposeBilling() {
if (mHelper != null) {
mHelper.dispose();
mHelper = null;
}
}
/**
* <b>Make sure you call {@link #disposeBilling()}!</b>
*
* @see #disposeBilling()
*/
private void initBilling() {
setWaitScreen(true);
disposeBilling();
String base64EncodedPublicKey = Build.GOOGLE_PLAY_PUBLIC_KEY;
mHelper = new IabHelper(getActivity(), base64EncodedPublicKey);
mHelper.enableDebugLogging(Build.DEBUG);
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
public void onIabSetupFinished(IabResult result) {
if (mHelper == null) return;
if (!result.isSuccess()) {
setErrorScreen(getString(R.string.donation_error_iab_setup), new Runnable() {
@Override
public void run() {
// Try to initialize billings again.
initBilling();
}
});
return;
}
setWaitScreen(false);
mHelper.queryInventoryAsync(mGotInventoryListener);
}
});
}
private boolean verifyDeveloperPayload(Purchase purchase) {
// TODO: This method itself is a big question.
// Personally, I think that this whole best practices part
// is confusing and is trying to make you do work that the API
// should really be doing. Since the purchase is tied to a Google account,
// and the Play Store obviously saves this information, they should
// just give you this in the purchase details. Getting a proper user ID
// requires additional permissions that you shouldnt need to add just
// to cover for the deficiencies of the IAB API.
return true;
}
private void complain(String message) {
ToastUtils.showShort(getActivity(), message);
}
}

View File

@ -1,53 +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 sharedcode.turboeditor.iab;
import android.content.res.Resources;
import sharedcode.turboeditor.R;
/**
* Created by achep on 07.05.14 for AcDisplay.
*
* @author Artem Chepurnoy
*/
public class DonationItems {
public static Donation[] get(Resources res) {
int[] data = new int[]{
2, R.string.donation_2,
4, R.string.donation_4,
10, R.string.donation_10,
20, R.string.donation_20,
50, R.string.donation_50,
99, R.string.donation_99,
};
Donation[] donation = new Donation[data.length / 2];
int length = donation.length;
for (int i = 0; i < length; i++) {
donation[i] = new Donation(data[i * 2],
res.getString(data[i * 2 + 1]));
}
return donation;
}
}

View File

@ -1,582 +0,0 @@
// Portions copyright 2002, Google, Inc.
//
// 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 sharedcode.turboeditor.iab.utils;
// This code was converted from code at http://iharder.sourceforge.net/base64/
// Lots of extraneous features were removed.
/* The original code said:
* <p>
* I am placing this code in the Public Domain. Do with it as you will.
* This software comes with no guarantees or warranties but with
* plenty of well-wishing instead!
* Please visit
* <a href="http://iharder.net/xmlizable">http://iharder.net/xmlizable</a>
* periodically to check for updates or to contribute improvements.
* </p>
*
* @author Robert Harder
* @author rharder@usa.net
* @version 1.3
*/
/**
* Base64 converter class. This code is not a complete MIME encoder;
* it simply converts binary data to base64 data and back.
* <p/>
* <p>Note {@link CharBase64} is a GWT-compatible implementation of this
* class.
*/
public class Base64 {
/**
* Specify encoding (value is {@code true}).
*/
public final static boolean ENCODE = true;
/**
* Specify decoding (value is {@code false}).
*/
public final static boolean DECODE = false;
/**
* The equals sign (=) as a byte.
*/
private final static byte EQUALS_SIGN = (byte) '=';
/**
* The new line character (\n) as a byte.
*/
private final static byte NEW_LINE = (byte) '\n';
/**
* The 64 valid Base64 values.
*/
private final static byte[] ALPHABET =
{(byte) 'A', (byte) 'B', (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F',
(byte) 'G', (byte) 'H', (byte) 'I', (byte) 'J', (byte) 'K',
(byte) 'L', (byte) 'M', (byte) 'N', (byte) 'O', (byte) 'P',
(byte) 'Q', (byte) 'R', (byte) 'S', (byte) 'T', (byte) 'U',
(byte) 'V', (byte) 'W', (byte) 'X', (byte) 'Y', (byte) 'Z',
(byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e',
(byte) 'f', (byte) 'g', (byte) 'h', (byte) 'i', (byte) 'j',
(byte) 'k', (byte) 'l', (byte) 'm', (byte) 'n', (byte) 'o',
(byte) 'p', (byte) 'q', (byte) 'r', (byte) 's', (byte) 't',
(byte) 'u', (byte) 'v', (byte) 'w', (byte) 'x', (byte) 'y',
(byte) 'z', (byte) '0', (byte) '1', (byte) '2', (byte) '3',
(byte) '4', (byte) '5', (byte) '6', (byte) '7', (byte) '8',
(byte) '9', (byte) '+', (byte) '/'};
/**
* The 64 valid web safe Base64 values.
*/
private final static byte[] WEBSAFE_ALPHABET =
{(byte) 'A', (byte) 'B', (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F',
(byte) 'G', (byte) 'H', (byte) 'I', (byte) 'J', (byte) 'K',
(byte) 'L', (byte) 'M', (byte) 'N', (byte) 'O', (byte) 'P',
(byte) 'Q', (byte) 'R', (byte) 'S', (byte) 'T', (byte) 'U',
(byte) 'V', (byte) 'W', (byte) 'X', (byte) 'Y', (byte) 'Z',
(byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e',
(byte) 'f', (byte) 'g', (byte) 'h', (byte) 'i', (byte) 'j',
(byte) 'k', (byte) 'l', (byte) 'm', (byte) 'n', (byte) 'o',
(byte) 'p', (byte) 'q', (byte) 'r', (byte) 's', (byte) 't',
(byte) 'u', (byte) 'v', (byte) 'w', (byte) 'x', (byte) 'y',
(byte) 'z', (byte) '0', (byte) '1', (byte) '2', (byte) '3',
(byte) '4', (byte) '5', (byte) '6', (byte) '7', (byte) '8',
(byte) '9', (byte) '-', (byte) '_'};
/**
* Translates a Base64 value to either its 6-bit reconstruction value
* or a negative number indicating some other meaning.
*/
private final static byte[] DECODABET = {-9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 0 - 8
-5, -5, // Whitespace: Tab and Linefeed
-9, -9, // Decimal 11 - 12
-5, // Whitespace: Carriage Return
-9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 14 - 26
-9, -9, -9, -9, -9, // Decimal 27 - 31
-5, // Whitespace: Space
-9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 33 - 42
62, // Plus sign at decimal 43
-9, -9, -9, // Decimal 44 - 46
63, // Slash at decimal 47
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // Numbers zero through nine
-9, -9, -9, // Decimal 58 - 60
-1, // Equals sign at decimal 61
-9, -9, -9, // Decimal 62 - 64
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, // Letters 'A' through 'N'
14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // Letters 'O' through 'Z'
-9, -9, -9, -9, -9, -9, // Decimal 91 - 96
26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, // Letters 'a' through 'm'
39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // Letters 'n' through 'z'
-9, -9, -9, -9, -9 // Decimal 123 - 127
/* ,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 128 - 139
-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 140 - 152
-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 153 - 165
-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 166 - 178
-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 179 - 191
-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 192 - 204
-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 205 - 217
-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 218 - 230
-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 231 - 243
-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 // Decimal 244 - 255 */
};
/**
* The web safe decodabet
*/
private final static byte[] WEBSAFE_DECODABET =
{-9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 0 - 8
-5, -5, // Whitespace: Tab and Linefeed
-9, -9, // Decimal 11 - 12
-5, // Whitespace: Carriage Return
-9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 14 - 26
-9, -9, -9, -9, -9, // Decimal 27 - 31
-5, // Whitespace: Space
-9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 33 - 44
62, // Dash '-' sign at decimal 45
-9, -9, // Decimal 46-47
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // Numbers zero through nine
-9, -9, -9, // Decimal 58 - 60
-1, // Equals sign at decimal 61
-9, -9, -9, // Decimal 62 - 64
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, // Letters 'A' through 'N'
14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // Letters 'O' through 'Z'
-9, -9, -9, -9, // Decimal 91-94
63, // Underscore '_' at decimal 95
-9, // Decimal 96
26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, // Letters 'a' through 'm'
39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // Letters 'n' through 'z'
-9, -9, -9, -9, -9 // Decimal 123 - 127
/* ,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 128 - 139
-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 140 - 152
-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 153 - 165
-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 166 - 178
-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 179 - 191
-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 192 - 204
-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 205 - 217
-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 218 - 230
-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 231 - 243
-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 // Decimal 244 - 255 */
};
// Indicates white space in encoding
private final static byte WHITE_SPACE_ENC = -5;
// Indicates equals sign in encoding
private final static byte EQUALS_SIGN_ENC = -1;
/**
* Defeats instantiation.
*/
private Base64() {
}
/* ******** E N C O D I N G M E T H O D S ******** */
/**
* Encodes up to three bytes of the array <var>source</var>
* and writes the resulting four Base64 bytes to <var>destination</var>.
* The source and destination arrays can be manipulated
* anywhere along their length by specifying
* <var>srcOffset</var> and <var>destOffset</var>.
* This method does not check to make sure your arrays
* are large enough to accommodate <var>srcOffset</var> + 3 for
* the <var>source</var> array or <var>destOffset</var> + 4 for
* the <var>destination</var> array.
* The actual number of significant bytes in your array is
* given by <var>numSigBytes</var>.
*
* @param source the array to convert
* @param srcOffset the index where conversion begins
* @param numSigBytes the number of significant bytes in your array
* @param destination the array to hold the conversion
* @param destOffset the index where output will be put
* @param alphabet is the encoding alphabet
* @return the <var>destination</var> array
* @since 1.3
*/
private static byte[] encode3to4(byte[] source, int srcOffset,
int numSigBytes, byte[] destination, int destOffset, byte[] alphabet) {
// 1 2 3
// 01234567890123456789012345678901 Bit position
// --------000000001111111122222222 Array position from threeBytes
// --------| || || || | Six bit groups to index alphabet
// >>18 >>12 >> 6 >> 0 Right shift necessary
// 0x3f 0x3f 0x3f Additional AND
// Create buffer with zero-padding if there are only one or two
// significant bytes passed in the array.
// We have to shift left 24 in order to flush out the 1's that appear
// when Java treats a value as negative that is cast from a byte to an int.
int inBuff =
(numSigBytes > 0 ? ((source[srcOffset] << 24) >>> 8) : 0)
| (numSigBytes > 1 ? ((source[srcOffset + 1] << 24) >>> 16) : 0)
| (numSigBytes > 2 ? ((source[srcOffset + 2] << 24) >>> 24) : 0);
switch (numSigBytes) {
case 3:
destination[destOffset] = alphabet[(inBuff >>> 18)];
destination[destOffset + 1] = alphabet[(inBuff >>> 12) & 0x3f];
destination[destOffset + 2] = alphabet[(inBuff >>> 6) & 0x3f];
destination[destOffset + 3] = alphabet[(inBuff) & 0x3f];
return destination;
case 2:
destination[destOffset] = alphabet[(inBuff >>> 18)];
destination[destOffset + 1] = alphabet[(inBuff >>> 12) & 0x3f];
destination[destOffset + 2] = alphabet[(inBuff >>> 6) & 0x3f];
destination[destOffset + 3] = EQUALS_SIGN;
return destination;
case 1:
destination[destOffset] = alphabet[(inBuff >>> 18)];
destination[destOffset + 1] = alphabet[(inBuff >>> 12) & 0x3f];
destination[destOffset + 2] = EQUALS_SIGN;
destination[destOffset + 3] = EQUALS_SIGN;
return destination;
default:
return destination;
} // end switch
} // end encode3to4
/**
* Encodes a byte array into Base64 notation.
* Equivalent to calling
* {@code encodeBytes(source, 0, source.length)}
*
* @param source The data to convert
* @since 1.4
*/
public static String encode(byte[] source) {
return encode(source, 0, source.length, ALPHABET, true);
}
/**
* Encodes a byte array into web safe Base64 notation.
*
* @param source The data to convert
* @param doPadding is {@code true} to pad result with '=' chars
* if it does not fall on 3 byte boundaries
*/
public static String encodeWebSafe(byte[] source, boolean doPadding) {
return encode(source, 0, source.length, WEBSAFE_ALPHABET, doPadding);
}
/**
* Encodes a byte array into Base64 notation.
*
* @param source the data to convert
* @param off offset in array where conversion should begin
* @param len length of data to convert
* @param alphabet the encoding alphabet
* @param doPadding is {@code true} to pad result with '=' chars
* if it does not fall on 3 byte boundaries
* @since 1.4
*/
public static String encode(byte[] source, int off, int len, byte[] alphabet,
boolean doPadding) {
byte[] outBuff = encode(source, off, len, alphabet, Integer.MAX_VALUE);
int outLen = outBuff.length;
// If doPadding is false, set length to truncate '='
// padding characters
while (doPadding == false && outLen > 0) {
if (outBuff[outLen - 1] != '=') {
break;
}
outLen -= 1;
}
return new String(outBuff, 0, outLen);
}
/**
* Encodes a byte array into Base64 notation.
*
* @param source the data to convert
* @param off offset in array where conversion should begin
* @param len length of data to convert
* @param alphabet is the encoding alphabet
* @param maxLineLength maximum length of one line.
* @return the BASE64-encoded byte array
*/
public static byte[] encode(byte[] source, int off, int len, byte[] alphabet,
int maxLineLength) {
int lenDiv3 = (len + 2) / 3; // ceil(len / 3)
int len43 = lenDiv3 * 4;
byte[] outBuff = new byte[len43 // Main 4:3
+ (len43 / maxLineLength)]; // New lines
int d = 0;
int e = 0;
int len2 = len - 2;
int lineLength = 0;
for (; d < len2; d += 3, e += 4) {
// The following block of code is the same as
// encode3to4( source, d + off, 3, outBuff, e, alphabet );
// but inlined for faster encoding (~20% improvement)
int inBuff =
((source[d + off] << 24) >>> 8)
| ((source[d + 1 + off] << 24) >>> 16)
| ((source[d + 2 + off] << 24) >>> 24);
outBuff[e] = alphabet[(inBuff >>> 18)];
outBuff[e + 1] = alphabet[(inBuff >>> 12) & 0x3f];
outBuff[e + 2] = alphabet[(inBuff >>> 6) & 0x3f];
outBuff[e + 3] = alphabet[(inBuff) & 0x3f];
lineLength += 4;
if (lineLength == maxLineLength) {
outBuff[e + 4] = NEW_LINE;
e++;
lineLength = 0;
} // end if: end of line
} // end for: each piece of array
if (d < len) {
encode3to4(source, d + off, len - d, outBuff, e, alphabet);
lineLength += 4;
if (lineLength == maxLineLength) {
// Add a last newline
outBuff[e + 4] = NEW_LINE;
e++;
}
e += 4;
}
assert (e == outBuff.length);
return outBuff;
}
/* ******** D E C O D I N G M E T H O D S ******** */
/**
* Decodes four bytes from array <var>source</var>
* and writes the resulting bytes (up to three of them)
* to <var>destination</var>.
* The source and destination arrays can be manipulated
* anywhere along their length by specifying
* <var>srcOffset</var> and <var>destOffset</var>.
* This method does not check to make sure your arrays
* are large enough to accommodate <var>srcOffset</var> + 4 for
* the <var>source</var> array or <var>destOffset</var> + 3 for
* the <var>destination</var> array.
* This method returns the actual number of bytes that
* were converted from the Base64 encoding.
*
* @param source the array to convert
* @param srcOffset the index where conversion begins
* @param destination the array to hold the conversion
* @param destOffset the index where output will be put
* @param decodabet the decodabet for decoding Base64 content
* @return the number of decoded bytes converted
* @since 1.3
*/
private static int decode4to3(byte[] source, int srcOffset,
byte[] destination, int destOffset, byte[] decodabet) {
// Example: Dk==
if (source[srcOffset + 2] == EQUALS_SIGN) {
int outBuff =
((decodabet[source[srcOffset]] << 24) >>> 6)
| ((decodabet[source[srcOffset + 1]] << 24) >>> 12);
destination[destOffset] = (byte) (outBuff >>> 16);
return 1;
} else if (source[srcOffset + 3] == EQUALS_SIGN) {
// Example: DkL=
int outBuff =
((decodabet[source[srcOffset]] << 24) >>> 6)
| ((decodabet[source[srcOffset + 1]] << 24) >>> 12)
| ((decodabet[source[srcOffset + 2]] << 24) >>> 18);
destination[destOffset] = (byte) (outBuff >>> 16);
destination[destOffset + 1] = (byte) (outBuff >>> 8);
return 2;
} else {
// Example: DkLE
int outBuff =
((decodabet[source[srcOffset]] << 24) >>> 6)
| ((decodabet[source[srcOffset + 1]] << 24) >>> 12)
| ((decodabet[source[srcOffset + 2]] << 24) >>> 18)
| ((decodabet[source[srcOffset + 3]] << 24) >>> 24);
destination[destOffset] = (byte) (outBuff >> 16);
destination[destOffset + 1] = (byte) (outBuff >> 8);
destination[destOffset + 2] = (byte) (outBuff);
return 3;
}
} // end decodeToBytes
/**
* Decodes data from Base64 notation.
*
* @param s the string to decode (decoded in default encoding)
* @return the decoded data
* @since 1.4
*/
public static byte[] decode(String s) throws Base64DecoderException {
byte[] bytes = s.getBytes();
return decode(bytes, 0, bytes.length);
}
/**
* Decodes data from web safe Base64 notation.
* Web safe encoding uses '-' instead of '+', '_' instead of '/'
*
* @param s the string to decode (decoded in default encoding)
* @return the decoded data
*/
public static byte[] decodeWebSafe(String s) throws Base64DecoderException {
byte[] bytes = s.getBytes();
return decodeWebSafe(bytes, 0, bytes.length);
}
/**
* Decodes Base64 content in byte array format and returns
* the decoded byte array.
*
* @param source The Base64 encoded data
* @return decoded data
* @throws Base64DecoderException
* @since 1.3
*/
public static byte[] decode(byte[] source) throws Base64DecoderException {
return decode(source, 0, source.length);
}
/**
* Decodes web safe Base64 content in byte array format and returns
* the decoded data.
* Web safe encoding uses '-' instead of '+', '_' instead of '/'
*
* @param source the string to decode (decoded in default encoding)
* @return the decoded data
*/
public static byte[] decodeWebSafe(byte[] source)
throws Base64DecoderException {
return decodeWebSafe(source, 0, source.length);
}
/**
* Decodes Base64 content in byte array format and returns
* the decoded byte array.
*
* @param source the Base64 encoded data
* @param off the offset of where to begin decoding
* @param len the length of characters to decode
* @return decoded data
* @throws Base64DecoderException
* @since 1.3
*/
public static byte[] decode(byte[] source, int off, int len)
throws Base64DecoderException {
return decode(source, off, len, DECODABET);
}
/**
* Decodes web safe Base64 content in byte array format and returns
* the decoded byte array.
* Web safe encoding uses '-' instead of '+', '_' instead of '/'
*
* @param source the Base64 encoded data
* @param off the offset of where to begin decoding
* @param len the length of characters to decode
* @return decoded data
*/
public static byte[] decodeWebSafe(byte[] source, int off, int len)
throws Base64DecoderException {
return decode(source, off, len, WEBSAFE_DECODABET);
}
/**
* Decodes Base64 content using the supplied decodabet and returns
* the decoded byte array.
*
* @param source the Base64 encoded data
* @param off the offset of where to begin decoding
* @param len the length of characters to decode
* @param decodabet the decodabet for decoding Base64 content
* @return decoded data
*/
public static byte[] decode(byte[] source, int off, int len, byte[] decodabet)
throws Base64DecoderException {
int len34 = len * 3 / 4;
byte[] outBuff = new byte[2 + len34]; // Upper limit on size of output
int outBuffPosn = 0;
byte[] b4 = new byte[4];
int b4Posn = 0;
int i = 0;
byte sbiCrop = 0;
byte sbiDecode = 0;
for (i = 0; i < len; i++) {
sbiCrop = (byte) (source[i + off] & 0x7f); // Only the low seven bits
sbiDecode = decodabet[sbiCrop];
if (sbiDecode >= WHITE_SPACE_ENC) { // White space Equals sign or better
if (sbiDecode >= EQUALS_SIGN_ENC) {
// An equals sign (for padding) must not occur at position 0 or 1
// and must be the last byte[s] in the encoded value
if (sbiCrop == EQUALS_SIGN) {
int bytesLeft = len - i;
byte lastByte = (byte) (source[len - 1 + off] & 0x7f);
if (b4Posn == 0 || b4Posn == 1) {
throw new Base64DecoderException(
"invalid padding byte '=' at byte offset " + i);
} else if ((b4Posn == 3 && bytesLeft > 2)
|| (b4Posn == 4 && bytesLeft > 1)) {
throw new Base64DecoderException(
"padding byte '=' falsely signals end of encoded value "
+ "at offset " + i
);
} else if (lastByte != EQUALS_SIGN && lastByte != NEW_LINE) {
throw new Base64DecoderException(
"encoded value has invalid trailing byte");
}
break;
}
b4[b4Posn++] = sbiCrop;
if (b4Posn == 4) {
outBuffPosn += decode4to3(b4, 0, outBuff, outBuffPosn, decodabet);
b4Posn = 0;
}
}
} else {
throw new Base64DecoderException("Bad Base64 input character at " + i
+ ": " + source[i + off] + "(decimal)");
}
}
// Because web safe encoding allows non padding base64 encodes, we
// need to pad the rest of the b4 buffer with equal signs when
// b4Posn != 0. There can be at most 2 equal signs at the end of
// four characters, so the b4 buffer must have two or three
// characters. This also catches the case where the input is
// padded with EQUALS_SIGN
if (b4Posn != 0) {
if (b4Posn == 1) {
throw new Base64DecoderException("single trailing character at offset "
+ (len - 1));
}
b4[b4Posn++] = EQUALS_SIGN;
outBuffPosn += decode4to3(b4, 0, outBuff, outBuffPosn, decodabet);
}
byte[] out = new byte[outBuffPosn];
System.arraycopy(outBuff, 0, out, 0, outBuffPosn);
return out;
}
}

View File

@ -1,54 +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 sharedcode.turboeditor.iab.utils;
/**
* Exception thrown when something went wrong with in-app billing.
* An IabException has an associated IabResult (an error).
* To get the IAB result that caused this exception to be thrown,
* call {@link #getResult()}.
*/
public class IabException extends Exception {
IabResult mResult;
public IabException(IabResult r) {
this(r, null);
}
public IabException(int response, String message) {
this(new IabResult(response, message));
}
public IabException(IabResult r, Exception cause) {
super(r.getMessage(), cause);
mResult = r;
}
public IabException(int response, String message, Exception cause) {
this(new IabResult(response, message), cause);
}
/**
* Returns the IAB result (error) that this exception signals.
*/
public IabResult getResult() {
return mResult;
}
}

View File

@ -1,966 +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 sharedcode.turboeditor.iab.utils;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender.SendIntentException;
import android.content.ServiceConnection;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.text.TextUtils;
import android.util.Log;
import org.json.JSONException;
import com.android.vending.billing.*;
import java.util.ArrayList;
import java.util.List;
/**
* Provides convenience methods for in-app billing. You can create one instance of this
* class for your application and use it to process in-app billing operations.
* It provides synchronous (blocking) and asynchronous (non-blocking) methods for
* many common in-app billing operations, as well as automatic signature
* verification.
* <p/>
* After instantiating, you must perform setup in order to start using the object.
* To perform setup, call the {@link #startSetup} method and provide a listener;
* that listener will be notified when setup is complete, after which (and not before)
* you may call other methods.
* <p/>
* After setup is complete, you will typically want to request an inventory of owned
* items and subscriptions. See {@link #queryInventory}, {@link #queryInventoryAsync}
* and related methods.
* <p/>
* When you are done with this object, don't forget to call {@link #dispose}
* to ensure proper cleanup. This object holds a binding to the in-app billing
* service, which will leak unless you dispose of it correctly. If you created
* the object on an Activity's onCreate method, then the recommended
* place to dispose of it is the Activity's onDestroy method.
* <p/>
* A note about threading: When using this object from a background thread, you may
* call the blocking versions of methods; when using from a UI thread, call
* only the asynchronous versions and handle the results via callbacks.
* Also, notice that you can only call one asynchronous operation at a time;
* attempting to start a second asynchronous operation while the first one
* has not yet completed will result in an exception being thrown.
*
* @author Bruno Oliveira (Google)
*/
public class IabHelper {
// Billing response codes
public static final int BILLING_RESPONSE_RESULT_OK = 0;
public static final int BILLING_RESPONSE_RESULT_USER_CANCELED = 1;
public static final int BILLING_RESPONSE_RESULT_BILLING_UNAVAILABLE = 3;
public static final int BILLING_RESPONSE_RESULT_ITEM_UNAVAILABLE = 4;
public static final int BILLING_RESPONSE_RESULT_DEVELOPER_ERROR = 5;
public static final int BILLING_RESPONSE_RESULT_ERROR = 6;
public static final int BILLING_RESPONSE_RESULT_ITEM_ALREADY_OWNED = 7;
public static final int BILLING_RESPONSE_RESULT_ITEM_NOT_OWNED = 8;
// IAB Helper error codes
public static final int IABHELPER_ERROR_BASE = -1000;
public static final int IABHELPER_REMOTE_EXCEPTION = -1001;
public static final int IABHELPER_BAD_RESPONSE = -1002;
public static final int IABHELPER_VERIFICATION_FAILED = -1003;
public static final int IABHELPER_SEND_INTENT_FAILED = -1004;
public static final int IABHELPER_USER_CANCELLED = -1005;
public static final int IABHELPER_UNKNOWN_PURCHASE_RESPONSE = -1006;
public static final int IABHELPER_MISSING_TOKEN = -1007;
public static final int IABHELPER_UNKNOWN_ERROR = -1008;
public static final int IABHELPER_SUBSCRIPTIONS_NOT_AVAILABLE = -1009;
public static final int IABHELPER_INVALID_CONSUMPTION = -1010;
// Keys for the responses from InAppBillingService
public static final String RESPONSE_CODE = "RESPONSE_CODE";
public static final String RESPONSE_GET_SKU_DETAILS_LIST = "DETAILS_LIST";
public static final String RESPONSE_BUY_INTENT = "BUY_INTENT";
public static final String RESPONSE_INAPP_PURCHASE_DATA = "INAPP_PURCHASE_DATA";
public static final String RESPONSE_INAPP_SIGNATURE = "INAPP_DATA_SIGNATURE";
public static final String RESPONSE_INAPP_ITEM_LIST = "INAPP_PURCHASE_ITEM_LIST";
public static final String RESPONSE_INAPP_PURCHASE_DATA_LIST = "INAPP_PURCHASE_DATA_LIST";
public static final String RESPONSE_INAPP_SIGNATURE_LIST = "INAPP_DATA_SIGNATURE_LIST";
public static final String INAPP_CONTINUATION_TOKEN = "INAPP_CONTINUATION_TOKEN";
// Item types
public static final String ITEM_TYPE_INAPP = "inapp";
public static final String ITEM_TYPE_SUBS = "subs";
// some fields on the getSkuDetails response bundle
public static final String GET_SKU_DETAILS_ITEM_LIST = "ITEM_ID_LIST";
public static final String GET_SKU_DETAILS_ITEM_TYPE_LIST = "ITEM_TYPE_LIST";
// Is debug logging enabled?
boolean mDebugLog = false;
String mDebugTag = "IabHelper";
// Is setup done?
boolean mSetupDone = false;
// Has this object been disposed of? (If so, we should ignore callbacks, etc)
boolean mDisposed = false;
boolean mIsBound = false;
// Are subscriptions supported?
boolean mSubscriptionsSupported = false;
// Is an asynchronous operation in progress?
// (only one at a time can be in progress)
boolean mAsyncInProgress = false;
// (for logging/debugging)
// if mAsyncInProgress == true, what asynchronous operation is in progress?
String mAsyncOperation = "";
// Context we were passed during initialization
Context mContext;
// Connection to the service
IInAppBillingService mService;
ServiceConnection mServiceConn;
// The request code used to launch purchase flow
int mRequestCode;
// The item type of the current purchase flow
String mPurchasingItemType;
// Public key for verifying signature, in base64 encoding
String mSignatureBase64 = null;
// The listener registered on launchPurchaseFlow, which we have to call back when
// the purchase finishes
OnIabPurchaseFinishedListener mPurchaseListener;
/**
* Creates an instance. After creation, it will not yet be ready to use. You must perform
* setup by calling {@link #startSetup} and wait for setup to complete. This constructor does not
* block and is safe to call from a UI thread.
*
* @param ctx Your application or Activity context. Needed to bind to the in-app billing service.
* @param base64PublicKey Your application's public key, encoded in base64.
* This is used for verification of purchase signatures. You can find your app's base64-encoded
* public key in your application's page on Google Play Developer Console. Note that this
* is NOT your "developer public key".
*/
public IabHelper(Context ctx, String base64PublicKey) {
mContext = ctx.getApplicationContext();
mSignatureBase64 = base64PublicKey;
logDebug("IAB helper created.");
}
/**
* Returns a human-readable description for the given response code.
*
* @param code The response code
* @return A human-readable string explaining the result code.
* It also includes the result code numerically.
*/
public static String getResponseDesc(int code) {
String[] iab_msgs = ("0:OK/1:User Canceled/2:Unknown/" +
"3:Billing Unavailable/4:Item unavailable/" +
"5:Developer Error/6:Error/7:Item Already Owned/" +
"8:Item not owned").split("/");
String[] iabhelper_msgs = ("0:OK/-1001:Remote exception during initialization/" +
"-1002:Bad response received/" +
"-1003:Purchase signature verification failed/" +
"-1004:Send intent failed/" +
"-1005:User cancelled/" +
"-1006:Unknown purchase response/" +
"-1007:Missing token/" +
"-1008:Unknown error/" +
"-1009:Subscriptions not available/" +
"-1010:Invalid consumption attempt").split("/");
if (code <= IABHELPER_ERROR_BASE) {
int index = IABHELPER_ERROR_BASE - code;
if (index >= 0 && index < iabhelper_msgs.length) return iabhelper_msgs[index];
else return String.valueOf(code) + ":Unknown IAB Helper Error";
} else if (code < 0 || code >= iab_msgs.length)
return String.valueOf(code) + ":Unknown";
else
return iab_msgs[code];
}
/**
* Enables or disable debug logging through LogCat.
*/
public void enableDebugLogging(boolean enable, String tag) {
checkNotDisposed();
mDebugLog = enable;
mDebugTag = tag;
}
public void enableDebugLogging(boolean enable) {
checkNotDisposed();
mDebugLog = enable;
}
/**
* Starts the setup process. This will start up the setup process asynchronously.
* You will be notified through the listener when the setup process is complete.
* This method is safe to call from a UI thread.
*
* @param listener The listener to notify when the setup process is complete.
*/
public void startSetup(final OnIabSetupFinishedListener listener) {
// If already set up, can't do it again.
checkNotDisposed();
if (mSetupDone) throw new IllegalStateException("IAB helper is already set up.");
// Connection to IAB service
logDebug("Starting in-app billing setup.");
mServiceConn = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
logDebug("Billing service disconnected.");
mService = null;
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
if (mDisposed) return;
logDebug("Billing service connected.");
mService = IInAppBillingService.Stub.asInterface(service);
String packageName = mContext.getPackageName();
try {
logDebug("Checking for in-app billing 3 support.");
// check for in-app billing v3 support
int response = mService.isBillingSupported(3, packageName, ITEM_TYPE_INAPP);
if (response != BILLING_RESPONSE_RESULT_OK) {
if (listener != null) listener.onIabSetupFinished(new IabResult(response,
"Error checking for billing v3 support."));
// if in-app purchases aren't supported, neither are subscriptions.
mSubscriptionsSupported = false;
return;
}
logDebug("In-app billing version 3 supported for " + packageName);
// check for v3 subscriptions support
response = mService.isBillingSupported(3, packageName, ITEM_TYPE_SUBS);
if (response == BILLING_RESPONSE_RESULT_OK) {
logDebug("Subscriptions AVAILABLE.");
mSubscriptionsSupported = true;
} else {
logDebug("Subscriptions NOT AVAILABLE. Response: " + response);
}
mSetupDone = true;
} catch (RemoteException e) {
if (listener != null) {
listener.onIabSetupFinished(new IabResult(IABHELPER_REMOTE_EXCEPTION,
"RemoteException while setting up in-app billing."));
}
e.printStackTrace();
return;
}
if (listener != null) {
listener.onIabSetupFinished(new IabResult(BILLING_RESPONSE_RESULT_OK, "Setup successful."));
}
}
};
Intent serviceIntent = new Intent("com.android.vending.billing.InAppBillingService.BIND");
serviceIntent.setPackage("com.android.vending");
List<ResolveInfo> ri = mContext.getPackageManager().queryIntentServices(serviceIntent, 0);
if (ri != null && !ri.isEmpty()) {
// service available to handle that Intent
mIsBound = mContext.bindService(serviceIntent, mServiceConn, Context.BIND_AUTO_CREATE);
} else {
// no service available to handle that Intent
if (listener != null) {
listener.onIabSetupFinished(
new IabResult(BILLING_RESPONSE_RESULT_BILLING_UNAVAILABLE,
"Billing service unavailable on device.")
);
}
}
}
/**
* Dispose of object, releasing resources. It's very important to call this
* method when you are done with this object. It will release any resources
* used by it such as service connections. Naturally, once the object is
* disposed of, it can't be used again.
*/
public void dispose() {
logDebug("Disposing.");
mSetupDone = false;
if (mServiceConn != null) {
logDebug("Unbinding from service.");
if (mContext != null && mIsBound) {
mContext.unbindService(mServiceConn);
}
}
mDisposed = true;
mContext = null;
mServiceConn = null;
mService = null;
mPurchaseListener = null;
}
private void checkNotDisposed() {
if (mDisposed)
throw new IllegalStateException("IabHelper was disposed of, so it cannot be used.");
}
/**
* Returns whether subscriptions are supported.
*/
public boolean subscriptionsSupported() {
checkNotDisposed();
return mSubscriptionsSupported;
}
public void launchPurchaseFlow(Activity act, String sku, int requestCode, OnIabPurchaseFinishedListener listener) {
launchPurchaseFlow(act, sku, requestCode, listener, "");
}
public void launchPurchaseFlow(Activity act, String sku, int requestCode,
OnIabPurchaseFinishedListener listener, String extraData) {
launchPurchaseFlow(act, sku, ITEM_TYPE_INAPP, requestCode, listener, extraData);
}
public void launchSubscriptionPurchaseFlow(Activity act, String sku, int requestCode,
OnIabPurchaseFinishedListener listener) {
launchSubscriptionPurchaseFlow(act, sku, requestCode, listener, "");
}
public void launchSubscriptionPurchaseFlow(Activity act, String sku, int requestCode,
OnIabPurchaseFinishedListener listener, String extraData) {
launchPurchaseFlow(act, sku, ITEM_TYPE_SUBS, requestCode, listener, extraData);
}
/**
* Initiate the UI flow for an in-app purchase. Call this method to initiate an in-app purchase,
* which will involve bringing up the Google Play screen. The calling activity will be paused while
* the user interacts with Google Play, and the result will be delivered via the activity's
* {@link android.app.Activity#onActivityResult} method, at which point you must call
* this object's {@link #handleActivityResult} method to continue the purchase flow. This method
* MUST be called from the UI thread of the Activity.
*
* @param act The calling activity.
* @param sku The sku of the item to purchase.
* @param itemType indicates if it's a product or a subscription (ITEM_TYPE_INAPP or ITEM_TYPE_SUBS)
* @param requestCode A request code (to differentiate from other responses --
* as in {@link android.app.Activity#startActivityForResult}).
* @param listener The listener to notify when the purchase process finishes
* @param extraData Extra data (developer payload), which will be returned with the purchase data
* when the purchase completes. This extra data will be permanently bound to that purchase
* and will always be returned when the purchase is queried.
*/
public void launchPurchaseFlow(Activity act, String sku, String itemType, int requestCode,
OnIabPurchaseFinishedListener listener, String extraData) {
checkNotDisposed();
checkSetupDone("launchPurchaseFlow");
flagStartAsync("launchPurchaseFlow");
IabResult result;
if (itemType.equals(ITEM_TYPE_SUBS) && !mSubscriptionsSupported) {
IabResult r = new IabResult(IABHELPER_SUBSCRIPTIONS_NOT_AVAILABLE,
"Subscriptions are not available.");
flagEndAsync();
if (listener != null) listener.onIabPurchaseFinished(r, null);
return;
}
try {
logDebug("Constructing buy intent for " + sku + ", item type: " + itemType);
Bundle buyIntentBundle = mService.getBuyIntent(3, mContext.getPackageName(), sku, itemType, extraData);
int response = getResponseCodeFromBundle(buyIntentBundle);
if (response != BILLING_RESPONSE_RESULT_OK) {
logError("Unable to buy item, Error response: " + getResponseDesc(response));
flagEndAsync();
result = new IabResult(response, "Unable to buy item");
if (listener != null) listener.onIabPurchaseFinished(result, null);
return;
}
PendingIntent pendingIntent = buyIntentBundle.getParcelable(RESPONSE_BUY_INTENT);
logDebug("Launching buy intent for " + sku + ". Request code: " + requestCode);
mRequestCode = requestCode;
mPurchaseListener = listener;
mPurchasingItemType = itemType;
act.startIntentSenderForResult(pendingIntent.getIntentSender(),
requestCode, new Intent(),
0, 0,
0);
} catch (SendIntentException e) {
logError("SendIntentException while launching purchase flow for sku " + sku);
e.printStackTrace();
flagEndAsync();
result = new IabResult(IABHELPER_SEND_INTENT_FAILED, "Failed to send intent.");
if (listener != null) listener.onIabPurchaseFinished(result, null);
} catch (RemoteException e) {
logError("RemoteException while launching purchase flow for sku " + sku);
e.printStackTrace();
flagEndAsync();
result = new IabResult(IABHELPER_REMOTE_EXCEPTION, "Remote exception while starting purchase flow");
if (listener != null) listener.onIabPurchaseFinished(result, null);
}
}
/**
* Handles an activity result that's part of the purchase flow in in-app billing. If you
* are calling {@link #launchPurchaseFlow}, then you must call this method from your
* Activity's {@link android.app.Activity@onActivityResult} method. This method
* MUST be called from the UI thread of the Activity.
*
* @param requestCode The requestCode as you received it.
* @param resultCode The resultCode as you received it.
* @param data The data (Intent) as you received it.
* @return Returns true if the result was related to a purchase flow and was handled;
* false if the result was not related to a purchase, in which case you should
* handle it normally.
*/
public boolean handleActivityResult(int requestCode, int resultCode, Intent data) {
IabResult result;
if (requestCode != mRequestCode) return false;
checkNotDisposed();
checkSetupDone("handleActivityResult");
// end of async purchase operation that started on launchPurchaseFlow
flagEndAsync();
if (data == null) {
logError("Null data in IAB activity result.");
result = new IabResult(IABHELPER_BAD_RESPONSE, "Null data in IAB result");
if (mPurchaseListener != null) mPurchaseListener.onIabPurchaseFinished(result, null);
return true;
}
int responseCode = getResponseCodeFromIntent(data);
String purchaseData = data.getStringExtra(RESPONSE_INAPP_PURCHASE_DATA);
String dataSignature = data.getStringExtra(RESPONSE_INAPP_SIGNATURE);
if (resultCode == Activity.RESULT_OK && responseCode == BILLING_RESPONSE_RESULT_OK) {
logDebug("Successful resultcode from purchase activity.");
logDebug("Purchase data: " + purchaseData);
logDebug("Data signature: " + dataSignature);
logDebug("Extras: " + data.getExtras());
logDebug("Expected item type: " + mPurchasingItemType);
if (purchaseData == null || dataSignature == null) {
logError("BUG: either purchaseData or dataSignature is null.");
logDebug("Extras: " + data.getExtras().toString());
result = new IabResult(IABHELPER_UNKNOWN_ERROR, "IAB returned null purchaseData or dataSignature");
if (mPurchaseListener != null)
mPurchaseListener.onIabPurchaseFinished(result, null);
return true;
}
@SuppressWarnings("UnusedAssignment") Purchase purchase = null;
try {
purchase = new Purchase(mPurchasingItemType, purchaseData, dataSignature);
String sku = purchase.getSku();
// Verify signature
if (!Security.verifyPurchase(mSignatureBase64, purchaseData, dataSignature)) {
logError("Purchase signature verification FAILED for sku " + sku);
result = new IabResult(IABHELPER_VERIFICATION_FAILED, "Signature verification failed for sku " + sku);
if (mPurchaseListener != null)
mPurchaseListener.onIabPurchaseFinished(result, purchase);
return true;
}
logDebug("Purchase signature successfully verified.");
} catch (JSONException e) {
logError("Failed to parse purchase data.");
e.printStackTrace();
result = new IabResult(IABHELPER_BAD_RESPONSE, "Failed to parse purchase data.");
if (mPurchaseListener != null)
mPurchaseListener.onIabPurchaseFinished(result, null);
return true;
}
if (mPurchaseListener != null) {
mPurchaseListener.onIabPurchaseFinished(new IabResult(BILLING_RESPONSE_RESULT_OK, "Success"), purchase);
}
} else if (resultCode == Activity.RESULT_OK) {
// result code was OK, but in-app billing response was not OK.
logDebug("Result code was OK but in-app billing response was not OK: " + getResponseDesc(responseCode));
if (mPurchaseListener != null) {
result = new IabResult(responseCode, "Problem purchashing item.");
mPurchaseListener.onIabPurchaseFinished(result, null);
}
} else if (resultCode == Activity.RESULT_CANCELED) {
logDebug("Purchase canceled - Response: " + getResponseDesc(responseCode));
result = new IabResult(IABHELPER_USER_CANCELLED, "User canceled.");
if (mPurchaseListener != null) mPurchaseListener.onIabPurchaseFinished(result, null);
} else {
logError("Purchase failed. Result code: " + Integer.toString(resultCode)
+ ". Response: " + getResponseDesc(responseCode));
result = new IabResult(IABHELPER_UNKNOWN_PURCHASE_RESPONSE, "Unknown purchase response.");
if (mPurchaseListener != null) mPurchaseListener.onIabPurchaseFinished(result, null);
}
return true;
}
public Inventory queryInventory(boolean querySkuDetails, List<String> moreSkus) throws IabException {
return queryInventory(querySkuDetails, moreSkus, null);
}
/**
* Queries the inventory. This will query all owned items from the server, as well as
* information on additional skus, if specified. This method may block or take long to execute.
* Do not call from a UI thread. For that, use the non-blocking version {@link #refreshInventoryAsync}.
*
* @param querySkuDetails if true, SKU details (price, description, etc) will be queried as well
* as purchase information.
* @param moreItemSkus additional PRODUCT skus to query information on, regardless of ownership.
* Ignored if null or if querySkuDetails is false.
* @param moreSubsSkus additional SUBSCRIPTIONS skus to query information on, regardless of ownership.
* Ignored if null or if querySkuDetails is false.
* @throws IabException if a problem occurs while refreshing the inventory.
*/
public Inventory queryInventory(boolean querySkuDetails, List<String> moreItemSkus,
List<String> moreSubsSkus) throws IabException {
checkNotDisposed();
checkSetupDone("queryInventory");
try {
Inventory inv = new Inventory();
int r = queryPurchases(inv, ITEM_TYPE_INAPP);
if (r != BILLING_RESPONSE_RESULT_OK) {
throw new IabException(r, "Error refreshing inventory (querying owned items).");
}
if (querySkuDetails) {
r = querySkuDetails(ITEM_TYPE_INAPP, inv, moreItemSkus);
if (r != BILLING_RESPONSE_RESULT_OK) {
throw new IabException(r, "Error refreshing inventory (querying prices of items).");
}
}
// if subscriptions are supported, then also query for subscriptions
if (mSubscriptionsSupported) {
r = queryPurchases(inv, ITEM_TYPE_SUBS);
if (r != BILLING_RESPONSE_RESULT_OK) {
throw new IabException(r, "Error refreshing inventory (querying owned subscriptions).");
}
if (querySkuDetails) {
r = querySkuDetails(ITEM_TYPE_SUBS, inv, moreItemSkus);
if (r != BILLING_RESPONSE_RESULT_OK) {
throw new IabException(r, "Error refreshing inventory (querying prices of subscriptions).");
}
}
}
return inv;
} catch (RemoteException e) {
throw new IabException(IABHELPER_REMOTE_EXCEPTION, "Remote exception while refreshing inventory.", e);
} catch (JSONException e) {
throw new IabException(IABHELPER_BAD_RESPONSE, "Error parsing JSON response while refreshing inventory.", e);
}
}
/**
* Asynchronous wrapper for inventory query. This will perform an inventory
* query as described in {@link #queryInventory}, but will do so asynchronously
* and call back the specified listener upon completion. This method is safe to
* call from a UI thread.
*
* @param querySkuDetails as in {@link #queryInventory}
* @param moreSkus as in {@link #queryInventory}
* @param listener The listener to notify when the refresh operation completes.
*/
public void queryInventoryAsync(final boolean querySkuDetails,
final List<String> moreSkus,
final QueryInventoryFinishedListener listener) {
final Handler handler = new Handler();
checkNotDisposed();
checkSetupDone("queryInventory");
flagStartAsync("refresh inventory");
(new Thread(new Runnable() {
public void run() {
IabResult result = new IabResult(BILLING_RESPONSE_RESULT_OK, "Inventory refresh successful.");
Inventory inv = null;
try {
inv = queryInventory(querySkuDetails, moreSkus);
} catch (IabException ex) {
result = ex.getResult();
}
flagEndAsync();
final IabResult result_f = result;
final Inventory inv_f = inv;
if (!mDisposed && listener != null) {
handler.post(new Runnable() {
public void run() {
listener.onQueryInventoryFinished(result_f, inv_f);
}
});
}
}
})).start();
}
public void queryInventoryAsync(QueryInventoryFinishedListener listener) {
queryInventoryAsync(true, null, listener);
}
public void queryInventoryAsync(boolean querySkuDetails, QueryInventoryFinishedListener listener) {
queryInventoryAsync(querySkuDetails, null, listener);
}
/**
* Consumes a given in-app product. Consuming can only be done on an item
* that's owned, and as a result of consumption, the user will no longer own it.
* This method may block or take long to return. Do not call from the UI thread.
* For that, see {@link #consumeAsync}.
*
* @param itemInfo The PurchaseInfo that represents the item to consume.
* @throws IabException if there is a problem during consumption.
*/
void consume(Purchase itemInfo) throws IabException {
checkNotDisposed();
checkSetupDone("consume");
if (!itemInfo.mItemType.equals(ITEM_TYPE_INAPP)) {
throw new IabException(IABHELPER_INVALID_CONSUMPTION,
"Items of type '" + itemInfo.mItemType + "' can't be consumed.");
}
try {
String token = itemInfo.getToken();
String sku = itemInfo.getSku();
if (token == null || token.equals("")) {
logError("Can't consume " + sku + ". No token.");
throw new IabException(IABHELPER_MISSING_TOKEN, "PurchaseInfo is missing token for sku: "
+ sku + " " + itemInfo);
}
logDebug("Consuming sku: " + sku + ", token: " + token);
int response = mService.consumePurchase(3, mContext.getPackageName(), token);
if (response == BILLING_RESPONSE_RESULT_OK) {
logDebug("Successfully consumed sku: " + sku);
} else {
logDebug("Error consuming consuming sku " + sku + ". " + getResponseDesc(response));
throw new IabException(response, "Error consuming sku " + sku);
}
} catch (RemoteException e) {
throw new IabException(IABHELPER_REMOTE_EXCEPTION, "Remote exception while consuming. PurchaseInfo: " + itemInfo, e);
}
}
/**
* Asynchronous wrapper to item consumption. Works like {@link #consume}, but
* performs the consumption in the background and notifies completion through
* the provided listener. This method is safe to call from a UI thread.
*
* @param purchase The purchase to be consumed.
* @param listener The listener to notify when the consumption operation finishes.
*/
public void consumeAsync(Purchase purchase, OnConsumeFinishedListener listener) {
checkNotDisposed();
checkSetupDone("consume");
List<Purchase> purchases = new ArrayList<>();
purchases.add(purchase);
consumeAsyncInternal(purchases, listener, null);
}
/**
* Same as {@link consumeAsync}, but for multiple items at once.
*
* @param purchases The list of PurchaseInfo objects representing the purchases to consume.
* @param listener The listener to notify when the consumption operation finishes.
*/
public void consumeAsync(List<Purchase> purchases, OnConsumeMultiFinishedListener listener) {
checkNotDisposed();
checkSetupDone("consume");
consumeAsyncInternal(purchases, null, listener);
}
// Checks that setup was done; if not, throws an exception.
void checkSetupDone(String operation) {
if (!mSetupDone) {
logError("Illegal state for operation (" + operation + "): IAB helper is not set up.");
throw new IllegalStateException("IAB helper is not set up. Can't perform operation: " + operation);
}
}
// Workaround to bug where sometimes response codes come as Long instead of Integer
int getResponseCodeFromBundle(Bundle b) {
Object o = b.get(RESPONSE_CODE);
if (o == null) {
logDebug("Bundle with null response code, assuming OK (known issue)");
return BILLING_RESPONSE_RESULT_OK;
} else if (o instanceof Integer) return (Integer) o;
else if (o instanceof Long) return (int) ((Long) o).longValue();
else {
logError("Unexpected type for bundle response code.");
logError(o.getClass().getName());
throw new RuntimeException("Unexpected type for bundle response code: " + o.getClass().getName());
}
}
// Workaround to bug where sometimes response codes come as Long instead of Integer
int getResponseCodeFromIntent(Intent i) {
Object o = i.getExtras().get(RESPONSE_CODE);
if (o == null) {
logError("Intent with no response code, assuming OK (known issue)");
return BILLING_RESPONSE_RESULT_OK;
} else if (o instanceof Integer) return (Integer) o;
else if (o instanceof Long) return (int) ((Long) o).longValue();
else {
logError("Unexpected type for intent response code.");
logError(o.getClass().getName());
throw new RuntimeException("Unexpected type for intent response code: " + o.getClass().getName());
}
}
void flagStartAsync(String operation) {
if (mAsyncInProgress) throw new IllegalStateException("Can't start async operation (" +
operation + ") because another async operation(" + mAsyncOperation + ") is in progress.");
mAsyncOperation = operation;
mAsyncInProgress = true;
logDebug("Starting async operation: " + operation);
}
void flagEndAsync() {
logDebug("Ending async operation: " + mAsyncOperation);
mAsyncOperation = "";
mAsyncInProgress = false;
}
int queryPurchases(Inventory inv, String itemType) throws JSONException, RemoteException {
// Query purchases
logDebug("Querying owned items, item type: " + itemType);
logDebug("Package name: " + mContext.getPackageName());
boolean verificationFailed = false;
String continueToken = null;
do {
logDebug("Calling getPurchases with continuation token: " + continueToken);
Bundle ownedItems = mService.getPurchases(3, mContext.getPackageName(),
itemType, continueToken);
int response = getResponseCodeFromBundle(ownedItems);
logDebug("Owned items response: " + String.valueOf(response));
if (response != BILLING_RESPONSE_RESULT_OK) {
logDebug("getPurchases() failed: " + getResponseDesc(response));
return response;
}
if (!ownedItems.containsKey(RESPONSE_INAPP_ITEM_LIST)
|| !ownedItems.containsKey(RESPONSE_INAPP_PURCHASE_DATA_LIST)
|| !ownedItems.containsKey(RESPONSE_INAPP_SIGNATURE_LIST)) {
logError("Bundle returned from getPurchases() doesn't contain required fields.");
return IABHELPER_BAD_RESPONSE;
}
ArrayList<String> ownedSkus = ownedItems.getStringArrayList(
RESPONSE_INAPP_ITEM_LIST);
ArrayList<String> purchaseDataList = ownedItems.getStringArrayList(
RESPONSE_INAPP_PURCHASE_DATA_LIST);
ArrayList<String> signatureList = ownedItems.getStringArrayList(
RESPONSE_INAPP_SIGNATURE_LIST);
for (int i = 0; i < purchaseDataList.size(); ++i) {
String purchaseData = purchaseDataList.get(i);
String signature = signatureList.get(i);
String sku = ownedSkus.get(i);
if (Security.verifyPurchase(mSignatureBase64, purchaseData, signature)) {
logDebug("Sku is owned: " + sku);
Purchase purchase = new Purchase(itemType, purchaseData, signature);
if (TextUtils.isEmpty(purchase.getToken())) {
logWarn("BUG: empty/null token!");
logDebug("Purchase data: " + purchaseData);
}
// Record ownership and token
inv.addPurchase(purchase);
} else {
logWarn("Purchase signature verification **FAILED**. Not adding item.");
logDebug(" Purchase data: " + purchaseData);
logDebug(" Signature: " + signature);
verificationFailed = true;
}
}
continueToken = ownedItems.getString(INAPP_CONTINUATION_TOKEN);
logDebug("Continuation token: " + continueToken);
} while (!TextUtils.isEmpty(continueToken));
return verificationFailed ? IABHELPER_VERIFICATION_FAILED : BILLING_RESPONSE_RESULT_OK;
}
int querySkuDetails(String itemType, Inventory inv, List<String> moreSkus)
throws RemoteException, JSONException {
logDebug("Querying SKU details.");
ArrayList<String> skuList = new ArrayList<>();
skuList.addAll(inv.getAllOwnedSkus(itemType));
if (moreSkus != null) {
for (String sku : moreSkus) {
if (!skuList.contains(sku)) {
skuList.add(sku);
}
}
}
if (skuList.size() == 0) {
logDebug("queryPrices: nothing to do because there are no SKUs.");
return BILLING_RESPONSE_RESULT_OK;
}
Bundle querySkus = new Bundle();
querySkus.putStringArrayList(GET_SKU_DETAILS_ITEM_LIST, skuList);
Bundle skuDetails = mService.getSkuDetails(3, mContext.getPackageName(),
itemType, querySkus);
if (!skuDetails.containsKey(RESPONSE_GET_SKU_DETAILS_LIST)) {
int response = getResponseCodeFromBundle(skuDetails);
if (response != BILLING_RESPONSE_RESULT_OK) {
logDebug("getSkuDetails() failed: " + getResponseDesc(response));
return response;
} else {
logError("getSkuDetails() returned a bundle with neither an error nor a detail list.");
return IABHELPER_BAD_RESPONSE;
}
}
ArrayList<String> responseList = skuDetails.getStringArrayList(
RESPONSE_GET_SKU_DETAILS_LIST);
for (String thisResponse : responseList) {
SkuDetails d = new SkuDetails(itemType, thisResponse);
logDebug("Got sku details: " + d);
inv.addSkuDetails(d);
}
return BILLING_RESPONSE_RESULT_OK;
}
void consumeAsyncInternal(final List<Purchase> purchases,
final OnConsumeFinishedListener singleListener,
final OnConsumeMultiFinishedListener multiListener) {
final Handler handler = new Handler();
flagStartAsync("consume");
(new Thread(new Runnable() {
public void run() {
final List<IabResult> results = new ArrayList<>();
for (Purchase purchase : purchases) {
try {
consume(purchase);
results.add(new IabResult(BILLING_RESPONSE_RESULT_OK, "Successful consume of sku " + purchase.getSku()));
} catch (IabException ex) {
results.add(ex.getResult());
}
}
flagEndAsync();
if (!mDisposed && singleListener != null) {
handler.post(new Runnable() {
public void run() {
singleListener.onConsumeFinished(purchases.get(0), results.get(0));
}
});
}
if (!mDisposed && multiListener != null) {
handler.post(new Runnable() {
public void run() {
multiListener.onConsumeMultiFinished(purchases, results);
}
});
}
}
})).start();
}
void logDebug(String msg) {
if (mDebugLog) Log.d(mDebugTag, msg);
}
void logError(String msg) {
Log.e(mDebugTag, "In-app billing error: " + msg);
}
void logWarn(String msg) {
Log.w(mDebugTag, "In-app billing warning: " + msg);
}
/**
* Callback for setup process. This listener's {@link #onIabSetupFinished} method is called
* when the setup process is complete.
*/
public interface OnIabSetupFinishedListener {
/**
* Called to notify that setup is complete.
*
* @param result The result of the setup process.
*/
public void onIabSetupFinished(IabResult result);
}
/**
* Callback that notifies when a purchase is finished.
*/
public interface OnIabPurchaseFinishedListener {
/**
* Called to notify that an in-app purchase finished. If the purchase was successful,
* then the sku parameter specifies which item was purchased. If the purchase failed,
* the sku and extraData parameters may or may not be null, depending on how far the purchase
* process went.
*
* @param result The result of the purchase.
* @param info The purchase information (null if purchase failed)
*/
public void onIabPurchaseFinished(IabResult result, Purchase info);
}
/**
* Listener that notifies when an inventory query operation completes.
*/
public interface QueryInventoryFinishedListener {
/**
* Called to notify that an inventory query operation completed.
*
* @param result The result of the operation.
* @param inv The inventory.
*/
public void onQueryInventoryFinished(IabResult result, Inventory inv);
}
/**
* Callback that notifies when a consumption operation finishes.
*/
public interface OnConsumeFinishedListener {
/**
* Called to notify that a consumption has finished.
*
* @param purchase The purchase that was (or was to be) consumed.
* @param result The result of the consumption operation.
*/
public void onConsumeFinished(Purchase purchase, IabResult result);
}
/**
* Callback that notifies when a multi-item consumption operation finishes.
*/
public interface OnConsumeMultiFinishedListener {
/**
* Called to notify that a consumption of multiple items has finished.
*
* @param purchases The purchases that were (or were to be) consumed.
* @param results The results of each consumption operation, corresponding to each
* sku.
*/
public void onConsumeMultiFinished(List<Purchase> purchases, List<IabResult> results);
}
}

View File

@ -1,63 +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 sharedcode.turboeditor.iab.utils;
/**
* Represents the result of an in-app billing operation.
* A result is composed of a response code (an integer) and possibly a
* message (String). You can get those by calling
* {@link #getResponse} and {@link #getMessage()}, respectively. You
* can also inquire whether a result is a success or a failure by
* calling {@link #isSuccess()} and {@link #isFailure()}.
*/
public class IabResult {
int mResponse;
String mMessage;
public IabResult(int response, String message) {
mResponse = response;
if (message == null || message.trim().length() == 0) {
mMessage = IabHelper.getResponseDesc(response);
} else {
mMessage = message + " (response: " + IabHelper.getResponseDesc(response) + ")";
}
}
public int getResponse() {
return mResponse;
}
public String getMessage() {
return mMessage;
}
public boolean isSuccess() {
return mResponse == IabHelper.BILLING_RESPONSE_RESULT_OK;
}
public boolean isFailure() {
return !isSuccess();
}
public String toString() {
return "IabResult: " + getMessage();
}
}

View File

@ -1,110 +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 sharedcode.turboeditor.iab.utils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Represents a block of information about in-app items.
* An Inventory is returned by such methods as {@link IabHelper#queryInventory}.
*/
public class Inventory {
Map<String, SkuDetails> mSkuMap = new HashMap<>();
Map<String, Purchase> mPurchaseMap = new HashMap<>();
Inventory() {
}
/**
* Returns the listing details for an in-app product.
*/
public SkuDetails getSkuDetails(String sku) {
return mSkuMap.get(sku);
}
/**
* Returns purchase information for a given product, or null if there is no purchase.
*/
public Purchase getPurchase(String sku) {
return mPurchaseMap.get(sku);
}
/**
* Returns whether or not there exists a purchase of the given product.
*/
public boolean hasPurchase(String sku) {
return mPurchaseMap.containsKey(sku);
}
/**
* Return whether or not details about the given product are available.
*/
public boolean hasDetails(String sku) {
return mSkuMap.containsKey(sku);
}
/**
* Erase a purchase (locally) from the inventory, given its product ID. This just
* modifies the Inventory object locally and has no effect on the server! This is
* useful when you have an existing Inventory object which you know to be up to date,
* and you have just consumed an item successfully, which means that erasing its
* purchase data from the Inventory you already have is quicker than querying for
* a new Inventory.
*/
public void erasePurchase(String sku) {
if (mPurchaseMap.containsKey(sku)) mPurchaseMap.remove(sku);
}
/**
* Returns a list of all owned product IDs.
*/
List<String> getAllOwnedSkus() {
return new ArrayList<>(mPurchaseMap.keySet());
}
/**
* Returns a list of all owned product IDs of a given type
*/
List<String> getAllOwnedSkus(String itemType) {
List<String> result = new ArrayList<>();
for (Purchase p : mPurchaseMap.values()) {
if (p.getItemType().equals(itemType)) result.add(p.getSku());
}
return result;
}
/**
* Returns a list of all purchases.
*/
List<Purchase> getAllPurchases() {
return new ArrayList<>(mPurchaseMap.values());
}
void addSkuDetails(SkuDetails d) {
mSkuMap.put(d.getSku(), d);
}
void addPurchase(Purchase p) {
mPurchaseMap.put(p.getSku(), p);
}
}

View File

@ -1,98 +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 sharedcode.turboeditor.iab.utils;
import org.json.JSONException;
import org.json.JSONObject;
/**
* Represents an in-app billing purchase.
*/
public class Purchase {
String mItemType; // ITEM_TYPE_INAPP or ITEM_TYPE_SUBS
String mOrderId;
String mPackageName;
String mSku;
long mPurchaseTime;
int mPurchaseState;
String mDeveloperPayload;
String mToken;
String mOriginalJson;
String mSignature;
public Purchase(String itemType, String jsonPurchaseInfo, String signature) throws JSONException {
mItemType = itemType;
mOriginalJson = jsonPurchaseInfo;
JSONObject o = new JSONObject(mOriginalJson);
mOrderId = o.optString("orderId");
mPackageName = o.optString("packageName");
mSku = o.optString("productId");
mPurchaseTime = o.optLong("purchaseTime");
mPurchaseState = o.optInt("purchaseState");
mDeveloperPayload = o.optString("developerPayload");
mToken = o.optString("token", o.optString("purchaseToken"));
mSignature = signature;
}
public String getItemType() {
return mItemType;
}
public String getOrderId() {
return mOrderId;
}
public String getPackageName() {
return mPackageName;
}
public String getSku() {
return mSku;
}
public long getPurchaseTime() {
return mPurchaseTime;
}
public int getPurchaseState() {
return mPurchaseState;
}
public String getDeveloperPayload() {
return mDeveloperPayload;
}
public String getToken() {
return mToken;
}
public String getOriginalJson() {
return mOriginalJson;
}
public String getSignature() {
return mSignature;
}
@Override
public String toString() {
return "PurchaseInfo(type:" + mItemType + "):" + mOriginalJson;
}
}

View File

@ -1,124 +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 sharedcode.turboeditor.iab.utils;
import android.text.TextUtils;
import android.util.Log;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
/**
* Security-related methods. For a secure implementation, all of this code
* should be implemented on a server that communicates with the
* application on the device. For the sake of simplicity and clarity of this
* example, this code is included here and is executed on the device. If you
* must verify the purchases on the phone, you should obfuscate this code to
* make it harder for an attacker to replace the code with stubs that treat all
* purchases as verified.
*/
public class Security {
private static final String TAG = "IABUtil/Security";
private static final String KEY_FACTORY_ALGORITHM = "RSA";
private static final String SIGNATURE_ALGORITHM = "SHA1withRSA";
/**
* Verifies that the data was signed with the given signature, and returns
* the verified purchase. The data is in JSON format and signed
* with a private key. The data also contains the {@link PurchaseState}
* and product ID of the purchase.
*
* @param base64PublicKey the base64-encoded public key to use for verifying.
* @param signedData the signed JSON string (signed, not encrypted)
* @param signature the signature for the data, signed with the private key
*/
public static boolean verifyPurchase(String base64PublicKey, String signedData, String signature) {
if (TextUtils.isEmpty(signedData) || TextUtils.isEmpty(base64PublicKey) ||
TextUtils.isEmpty(signature)) {
Log.e(TAG, "Purchase verification failed: missing data.");
return false;
}
PublicKey key = Security.generatePublicKey(base64PublicKey);
return Security.verify(key, signedData, signature);
}
/**
* Generates a PublicKey instance from a string containing the
* Base64-encoded public key.
*
* @param encodedPublicKey Base64-encoded public key
* @throws IllegalArgumentException if encodedPublicKey is invalid
*/
public static PublicKey generatePublicKey(String encodedPublicKey) {
try {
byte[] decodedKey = Base64.decode(encodedPublicKey);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_FACTORY_ALGORITHM);
return keyFactory.generatePublic(new X509EncodedKeySpec(decodedKey));
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
} catch (InvalidKeySpecException e) {
Log.e(TAG, "Invalid key specification.");
throw new IllegalArgumentException(e);
} catch (Base64DecoderException e) {
Log.e(TAG, "Base64 decoding failed.");
throw new IllegalArgumentException(e);
}
}
/**
* Verifies that the signature from the server matches the computed
* signature on the data. Returns true if the data is correctly signed.
*
* @param publicKey public key associated with the developer account
* @param signedData signed data from server
* @param signature server signature
* @return true if the data and signature match
*/
public static boolean verify(PublicKey publicKey, String signedData, String signature) {
Signature sig;
try {
sig = Signature.getInstance(SIGNATURE_ALGORITHM);
sig.initVerify(publicKey);
sig.update(signedData.getBytes());
if (!sig.verify(Base64.decode(signature))) {
Log.e(TAG, "Signature verification failed.");
return false;
}
return true;
} catch (NoSuchAlgorithmException e) {
Log.e(TAG, "NoSuchAlgorithmException.");
} catch (InvalidKeyException e) {
Log.e(TAG, "Invalid key specification.");
} catch (SignatureException e) {
Log.e(TAG, "Signature exception.");
} catch (Base64DecoderException e) {
Log.e(TAG, "Base64 decoding failed.");
}
return false;
}
}

View File

@ -1,76 +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 sharedcode.turboeditor.iab.utils;
import org.json.JSONException;
import org.json.JSONObject;
/**
* Represents an in-app product's listing details.
*/
public class SkuDetails {
String mItemType;
String mSku;
String mType;
String mPrice;
String mTitle;
String mDescription;
String mJson;
public SkuDetails(String jsonSkuDetails) throws JSONException {
this(IabHelper.ITEM_TYPE_INAPP, jsonSkuDetails);
}
public SkuDetails(String itemType, String jsonSkuDetails) throws JSONException {
mItemType = itemType;
mJson = jsonSkuDetails;
JSONObject o = new JSONObject(mJson);
mSku = o.optString("productId");
mType = o.optString("type");
mPrice = o.optString("price");
mTitle = o.optString("title");
mDescription = o.optString("description");
}
public String getSku() {
return mSku;
}
public String getType() {
return mType;
}
public String getPrice() {
return mPrice;
}
public String getTitle() {
return mTitle;
}
public String getDescription() {
return mDescription;
}
@Override
public String toString() {
return "SkuDetails:" + mJson;
}
}

View File

@ -17,21 +17,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package sharedcode.turboeditor.iab.utils; package sharedcode.turboeditor.preferences;
/** public enum PreferenceChangeType {
* Exception thrown when encountering an invalid Base64 input character. FONT_SIZE, ENCODING, SYNTAX, WRAP_CONTENT, MONOSPACE, LINE_NUMERS, THEME_CHANGE, TEXT_SUGGESTIONS, READ_ONLY,
* }
* @author nelson
*/
public class Base64DecoderException extends Exception {
private static final long serialVersionUID = 1L;
public Base64DecoderException() {
super();
}
public Base64DecoderException(String s) {
super(s);
}
}

View File

@ -74,7 +74,7 @@ public final class PreferenceHelper {
} }
public static String getEncoding(Context context) { public static String getEncoding(Context context) {
return getPrefs(context).getString("editor_encoding", "UTF-8"); return getPrefs(context).getString("editor_encoding", "UTF-16");
} }
public static int getFontSize(Context context) { public static int getFontSize(Context context) {

View File

@ -32,20 +32,7 @@ import sharedcode.turboeditor.R;
import sharedcode.turboeditor.activity.MainActivity; import sharedcode.turboeditor.activity.MainActivity;
import sharedcode.turboeditor.dialogfragment.EncodingDialog; import sharedcode.turboeditor.dialogfragment.EncodingDialog;
import sharedcode.turboeditor.dialogfragment.NumberPickerDialog; import sharedcode.turboeditor.dialogfragment.NumberPickerDialog;
import sharedcode.turboeditor.util.ProCheckUtils;
import sharedcode.turboeditor.util.ViewUtils; import sharedcode.turboeditor.util.ViewUtils;
import sharedcode.turboeditor.views.DialogHelper;
import static sharedcode.turboeditor.util.EventBusEvents.APreferenceValueWasChanged;
import static sharedcode.turboeditor.util.EventBusEvents.APreferenceValueWasChanged.Type.ENCODING;
import static sharedcode.turboeditor.util.EventBusEvents.APreferenceValueWasChanged.Type.FONT_SIZE;
import static sharedcode.turboeditor.util.EventBusEvents.APreferenceValueWasChanged.Type.LINE_NUMERS;
import static sharedcode.turboeditor.util.EventBusEvents.APreferenceValueWasChanged.Type.MONOSPACE;
import static sharedcode.turboeditor.util.EventBusEvents.APreferenceValueWasChanged.Type.READ_ONLY;
import static sharedcode.turboeditor.util.EventBusEvents.APreferenceValueWasChanged.Type.SYNTAX;
import static sharedcode.turboeditor.util.EventBusEvents.APreferenceValueWasChanged.Type.TEXT_SUGGESTIONS;
import static sharedcode.turboeditor.util.EventBusEvents.APreferenceValueWasChanged.Type.THEME_CHANGE;
import static sharedcode.turboeditor.util.EventBusEvents.APreferenceValueWasChanged.Type.WRAP_CONTENT;
public class SettingsFragment extends Fragment implements NumberPickerDialog.INumberPickerDialog, EncodingDialog.DialogListener { public class SettingsFragment extends Fragment implements NumberPickerDialog.INumberPickerDialog, EncodingDialog.DialogListener {
@ -118,16 +105,12 @@ public class SettingsFragment extends Fragment implements NumberPickerDialog.INu
fontSizeView = (TextView) rootView.findViewById(R.id.drawer_button_font_size); fontSizeView = (TextView) rootView.findViewById(R.id.drawer_button_font_size);
encodingView = (TextView) rootView.findViewById(R.id.drawer_button_encoding); encodingView = (TextView) rootView.findViewById(R.id.drawer_button_encoding);
extraOptionsView = (TextView) rootView.findViewById(R.id.drawer_button_extra_options); extraOptionsView = (TextView) rootView.findViewById(R.id.drawer_button_extra_options);
donateView = (TextView) rootView.findViewById(R.id.drawer_button_go_pro);
if(ProCheckUtils.isPro(getActivity(), false))
ViewUtils.setVisible(donateView, false);
swLineNumbers.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { swLineNumbers.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override @Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
PreferenceHelper.setLineNumbers(getActivity(), isChecked); PreferenceHelper.setLineNumbers(getActivity(), isChecked);
((MainActivity) getActivity()).onEvent(new APreferenceValueWasChanged(LINE_NUMERS)); ((MainActivity) getActivity()).aPreferenceValueWasChanged(PreferenceChangeType.LINE_NUMERS);
} }
}); });
@ -136,7 +119,7 @@ public class SettingsFragment extends Fragment implements NumberPickerDialog.INu
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
sColorSyntax = isChecked; sColorSyntax = isChecked;
PreferenceHelper.setSyntaxHighlight(getActivity(), isChecked); PreferenceHelper.setSyntaxHighlight(getActivity(), isChecked);
((MainActivity) getActivity()).onEvent(new APreferenceValueWasChanged(SYNTAX)); ((MainActivity) getActivity()).aPreferenceValueWasChanged(PreferenceChangeType.SYNTAX);
} }
}); });
@ -145,7 +128,7 @@ public class SettingsFragment extends Fragment implements NumberPickerDialog.INu
@Override @Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
PreferenceHelper.setWrapContent(getActivity(), isChecked); PreferenceHelper.setWrapContent(getActivity(), isChecked);
((MainActivity) getActivity()).onEvent(new APreferenceValueWasChanged(WRAP_CONTENT)); ((MainActivity) getActivity()).aPreferenceValueWasChanged(PreferenceChangeType.WRAP_CONTENT);
} }
}); });
@ -154,7 +137,7 @@ public class SettingsFragment extends Fragment implements NumberPickerDialog.INu
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
sUseMonospace = isChecked; sUseMonospace = isChecked;
PreferenceHelper.setUseMonospace(getActivity(), isChecked); PreferenceHelper.setUseMonospace(getActivity(), isChecked);
((MainActivity) getActivity()).onEvent(new APreferenceValueWasChanged(MONOSPACE)); ((MainActivity) getActivity()).aPreferenceValueWasChanged(PreferenceChangeType.MONOSPACE);
} }
}); });
@ -163,7 +146,7 @@ public class SettingsFragment extends Fragment implements NumberPickerDialog.INu
@Override @Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
PreferenceHelper.setReadOnly(getActivity(), isChecked); PreferenceHelper.setReadOnly(getActivity(), isChecked);
((MainActivity) getActivity()).onEvent(new APreferenceValueWasChanged(READ_ONLY)); ((MainActivity) getActivity()).aPreferenceValueWasChanged(PreferenceChangeType.READ_ONLY);
} }
}); });
@ -200,18 +183,11 @@ public class SettingsFragment extends Fragment implements NumberPickerDialog.INu
} }
}); });
donateView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
DialogHelper.showDonateDialog(getActivity());
}
});
swLightTheme.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { swLightTheme.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override @Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
PreferenceHelper.setLightTheme(getActivity(), isChecked); PreferenceHelper.setLightTheme(getActivity(), isChecked);
((MainActivity) getActivity()).onEvent(new APreferenceValueWasChanged(THEME_CHANGE)); ((MainActivity) getActivity()).aPreferenceValueWasChanged(PreferenceChangeType.THEME_CHANGE);
} }
}); });
@ -219,7 +195,7 @@ public class SettingsFragment extends Fragment implements NumberPickerDialog.INu
@Override @Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
PreferenceHelper.setSuggestionsActive(getActivity(), isChecked); PreferenceHelper.setSuggestionsActive(getActivity(), isChecked);
((MainActivity) getActivity()).onEvent(new APreferenceValueWasChanged(TEXT_SUGGESTIONS)); ((MainActivity) getActivity()).aPreferenceValueWasChanged(PreferenceChangeType.TEXT_SUGGESTIONS);
} }
}); });
@ -257,13 +233,13 @@ public class SettingsFragment extends Fragment implements NumberPickerDialog.INu
@Override @Override
public void onNumberPickerDialogDismissed(NumberPickerDialog.Actions action, int value) { public void onNumberPickerDialogDismissed(NumberPickerDialog.Actions action, int value) {
PreferenceHelper.setFontSize(getActivity(), value); PreferenceHelper.setFontSize(getActivity(), value);
((MainActivity) getActivity()).onEvent(new APreferenceValueWasChanged(FONT_SIZE)); ((MainActivity) getActivity()).aPreferenceValueWasChanged(PreferenceChangeType.FONT_SIZE);
} }
@Override @Override
public void onEncodingSelected(String result) { public void onEncodingSelected(String result) {
PreferenceHelper.setEncoding(getActivity(), result); PreferenceHelper.setEncoding(getActivity(), result);
((MainActivity) getActivity()).onEvent(new APreferenceValueWasChanged(ENCODING)); ((MainActivity) getActivity()).aPreferenceValueWasChanged(PreferenceChangeType.ENCODING);
} }
} }

View File

@ -32,7 +32,6 @@ import java.util.concurrent.TimeoutException;
import sharedcode.turboeditor.R; import sharedcode.turboeditor.R;
import sharedcode.turboeditor.activity.MainActivity; import sharedcode.turboeditor.activity.MainActivity;
import sharedcode.turboeditor.root.RootUtils; import sharedcode.turboeditor.root.RootUtils;
import sharedcode.turboeditor.util.EventBusEvents;
public class SaveFileTask extends AsyncTask<Void, Void, Void> { public class SaveFileTask extends AsyncTask<Void, Void, Void> {
@ -101,6 +100,6 @@ public class SaveFileTask extends AsyncTask<Void, Void, Void> {
super.onPostExecute(aVoid); super.onPostExecute(aVoid);
Toast.makeText(activity, message, Toast.LENGTH_LONG).show(); Toast.makeText(activity, message, Toast.LENGTH_LONG).show();
if (message.equals(positiveMessage)) if (message.equals(positiveMessage))
activity.onEvent(new EventBusEvents.SavedAFile(filePath)); activity.savedAFile(filePath);
} }
} }

View File

@ -27,7 +27,7 @@ public class LineUtils {
private boolean[] toCountLinesArray; private boolean[] toCountLinesArray;
private int[] realLines; private int[] realLines;
public boolean[] getToCountLinesArray() { public boolean[] getGoodLines() {
return toCountLinesArray; return toCountLinesArray;
} }
@ -81,6 +81,8 @@ public class LineUtils {
} }
} }
toCountLinesArray[lineCount-1] = true;
int realLine = startingLine; // the first line is not 0, is 1. We start counting from 1 int realLine = startingLine; // the first line is not 0, is 1. We start counting from 1
for (i = 0; i < toCountLinesArray.length; i++) { for (i = 0; i < toCountLinesArray.length; i++) {

View File

@ -35,10 +35,8 @@ public class Patterns {
// Strings // Strings
public static final Pattern GENERAL_STRINGS = Pattern.compile("\"(.*?)\"|'(.*?)'"); public static final Pattern GENERAL_STRINGS = Pattern.compile("\"(.*?)\"|'(.*?)'");
public static final Pattern HTML_OPEN_TAGS = 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[^>]*>|</([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( public static final Pattern HTML_ATTRS = Pattern.compile(
"(\\S+)=[\"']?((?:.(?![\"']?\\s+(?:\\S+)=|[>\"']))+.)[\"']?"); "(\\S+)=[\"']?((?:.(?![\"']?\\s+(?:\\S+)=|[>\"']))+.)[\"']?");
@ -54,7 +52,7 @@ public class Patterns {
//public static final Pattern CSS_NUMBERS = Pattern.compile( //public static final Pattern CSS_NUMBERS = Pattern.compile(
// "/^auto$|^[+-]?[0-9]+\\.?([0-9]+)?(px|em|ex|%|in|cm|mm|pt|pc)?$/ig"); // "/^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 SYMBOLS = Pattern.compile(
"(!|,|\\(|\\)|\\+|\\-|\\*|<|>|=|\\.|\\?|;|\\{|\\}|\\[|\\])"); "(!|,|\\(|\\)|\\+|\\-|\\*|<|>|=|\\.|\\?|;|\\{|\\}|\\[|\\]|\\|)");
public static final Pattern NUMBERS_OR_SYMBOLS = Pattern.compile(NUMBERS.pattern()+"|"+SYMBOLS.pattern()); public static final Pattern NUMBERS_OR_SYMBOLS = Pattern.compile(NUMBERS.pattern()+"|"+SYMBOLS.pattern());
public static final Pattern GENERAL_KEYWORDS = Pattern.compile( public static final Pattern GENERAL_KEYWORDS = Pattern.compile(
"\\b(alignas|alignof|and|and_eq|asm|auto|bitand|bitorbool|break|case|catch|char|" "\\b(alignas|alignof|and|and_eq|asm|auto|bitand|bitorbool|break|case|catch|char|"

View File

@ -28,11 +28,14 @@ public class SearchResult {
public boolean isReplace; public boolean isReplace;
public String textToReplace; public String textToReplace;
public int index; public int index;
public String whatToSearch;
public SearchResult(LinkedList<Integer> foundIndex, int textLength, boolean isReplace, String textToReplace) {
public SearchResult(LinkedList<Integer> foundIndex, int textLength, boolean isReplace, String whatToSearch, String textToReplace) {
this.foundIndex = foundIndex; this.foundIndex = foundIndex;
this.textLength = textLength; this.textLength = textLength;
this.isReplace = isReplace; this.isReplace = isReplace;
this.whatToSearch = whatToSearch;
this.textToReplace = textToReplace; this.textToReplace = textToReplace;
} }

View File

@ -1,115 +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 sharedcode.turboeditor.util;
import java.io.File;
import java.util.List;
public class EventBusEvents {
public static class CannotOpenAFile {
}
public static class NewFileToOpen {
private final File file;
private final String fileText;
public NewFileToOpen(File file) {
this.file = file;
this.fileText = "";
}
public NewFileToOpen(String fileText) {
this.file = new File("");
this.fileText = fileText;
}
public File getFile() {
return file;
}
public String getFileText() {
return fileText;
}
}
public static class AFileIsSelected {
private final String path;
public AFileIsSelected(String path) {
this.path = path;
}
public String getPath() {
return path;
}
}
public static class APreferenceValueWasChanged {
private Type type;
private List<Type> types;
public APreferenceValueWasChanged(Type type) {
this.type = type;
}
public APreferenceValueWasChanged(List<Type> types) {
this.types = types;
}
public boolean hasType(Type value) {
if (type != null) {
return value == type;
} else {
return types.contains(value);
}
}
public enum Type {
FONT_SIZE, ENCODING, SYNTAX, WRAP_CONTENT, MONOSPACE, LINE_NUMERS, THEME_CHANGE, TEXT_SUGGESTIONS, READ_ONLY,
}
}
public static class SaveAFile {
}
public static class SavedAFile {
private final String path;
public SavedAFile(String path) {
this.path = path;
}
public String getPath() {
return path;
}
}
public static class ClosedAFile {
}
public static class InvalideTheMenu {
}
}

View File

@ -21,21 +21,20 @@ package sharedcode.turboeditor.util;
import android.content.Context; import android.content.Context;
import sharedcode.turboeditor.preferences.PreferenceHelper;
public class ProCheckUtils { public class ProCheckUtils {
public static boolean isPro(Context context, boolean includeDonations) { public static boolean isPro(Context context, boolean includeDonations) {
String packageName = context.getPackageName(); // happy new year
return true;
/*
if (Build.FOR_AMAZON) if (Build.FOR_AMAZON)
return true; return true;
else if (packageName.equals("com.maskyn.fileeditorpro")) else if (context.getPackageName().equals("com.maskyn.fileeditorpro"))
return true; return true;
else if (includeDonations && PreferenceHelper.hasDonated(context)) else if (includeDonations && PreferenceHelper.hasDonated(context))
return true; return true;
else else
return false; return false;*/
} }
public static boolean isPro(Context context) { public static boolean isPro(Context context) {

View File

@ -39,7 +39,6 @@ import org.apache.commons.lang3.builder.HashCodeBuilder;
import sharedcode.turboeditor.R; import sharedcode.turboeditor.R;
import sharedcode.turboeditor.dialogfragment.AboutDialog; import sharedcode.turboeditor.dialogfragment.AboutDialog;
import sharedcode.turboeditor.iab.DonationFragment;
/** /**
* Helper class for showing fragment dialogs. * Helper class for showing fragment dialogs.
@ -48,13 +47,8 @@ public class DialogHelper {
public static final String TAG_FRAGMENT_ABOUT = "dialog_about"; public static final String TAG_FRAGMENT_ABOUT = "dialog_about";
public static final String TAG_FRAGMENT_HELP = "dialog_help"; public static final String TAG_FRAGMENT_HELP = "dialog_help";
public static final String TAG_FRAGMENT_DONATION = "dialog_donate";
public static final String TAG_FRAGMENT_FEEDBACK = "dialog_feedback"; public static final String TAG_FRAGMENT_FEEDBACK = "dialog_feedback";
public static void showDonateDialog(Activity activity) {
showDialog(activity, DonationFragment.class, TAG_FRAGMENT_DONATION);
}
public static void showAboutDialog(Activity activity) { public static void showAboutDialog(Activity activity) {
showDialog(activity, AboutDialog.class, TAG_FRAGMENT_ABOUT); showDialog(activity, AboutDialog.class, TAG_FRAGMENT_ABOUT);
} }

View File

@ -18,16 +18,11 @@
~ You should have received a copy of the GNU General Public License ~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <http://www.gnu.org/licenses/>. ~ along with this program. If not, see <http://www.gnu.org/licenses/>.
--> -->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/toolbar"/>
<sharedcode.turboeditor.views.CustomDrawerLayout <sharedcode.turboeditor.views.CustomDrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@id/drawer_layout" android:id="@id/drawer_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
@ -43,6 +38,14 @@
android:textColor="@android:color/secondary_text_dark" android:textColor="@android:color/secondary_text_dark"
android:id="@id/no_file_opened_messagge"/> android:id="@id/no_file_opened_messagge"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/toolbar"/>
<FrameLayout <FrameLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
@ -102,7 +105,7 @@
android:visibility="invisible"/> android:visibility="invisible"/>
</FrameLayout> </FrameLayout>
</LinearLayout>
<RelativeLayout <RelativeLayout
@ -141,7 +144,7 @@
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="192dp" android:layout_height="216dp"
android:id="@id/drawer_buttons" android:id="@id/drawer_buttons"
android:layout_alignParentBottom="true" android:layout_alignParentBottom="true"
android:orientation="vertical"> android:orientation="vertical">
@ -153,7 +156,7 @@
<TextView <TextView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="48dp" android:layout_height="54dp"
android:text="@string/new_file" android:text="@string/new_file"
android:gravity="center_vertical" android:gravity="center_vertical"
android:paddingStart="20dp" android:paddingStart="20dp"
@ -168,7 +171,7 @@
<TextView <TextView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="48dp" android:layout_height="54dp"
android:text="@string/open_a_file" android:text="@string/open_a_file"
android:gravity="center_vertical" android:gravity="center_vertical"
android:paddingStart="20dp" android:paddingStart="20dp"
@ -183,7 +186,7 @@
<TextView <TextView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="48dp" android:layout_height="54dp"
android:text="@string/preferenze" android:text="@string/preferenze"
android:gravity="center_vertical" android:gravity="center_vertical"
android:paddingStart="20dp" android:paddingStart="20dp"
@ -349,5 +352,3 @@
</sharedcode.turboeditor.views.CustomDrawerLayout> </sharedcode.turboeditor.views.CustomDrawerLayout>
</LinearLayout>

View File

@ -58,4 +58,14 @@
android:hint="@string/folder" android:hint="@string/folder"
android:padding="5dp" android:padding="5dp"
android:textSize="12sp"/> android:textSize="12sp"/>
<CheckBox
android:layout_width="match_parent"
android:layout_height="56dp"
android:text="@string/delete_current_file"
android:id="@id/delete_current_file"
android:layout_weight="1"
android:singleLine="true"
android:textSize="12sp"
android:textAllCaps="true"/>
</LinearLayout> </LinearLayout>

View File

@ -1,89 +0,0 @@
<?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/>.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingStart="@dimen/activity_horizontal_margin"
android:paddingEnd="@dimen/activity_horizontal_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
style="?textAppearanceDialogMessage"/>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp">
<TextView
android:id="@+id/error"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:layout_marginBottom="@dimen/activity_vertical_margin"
android:layout_marginStart="@dimen/activity_horizontal_margin"
android:layout_marginEnd="@dimen/activity_horizontal_margin"
android:layout_marginLeft="@dimen/activity_horizontal_margin"
android:layout_marginRight="@dimen/activity_horizontal_margin"
android:layout_gravity="center"
android:maxWidth="200dp"
android:background="?android:listChoiceBackgroundIndicator"
android:drawablePadding="4dp"
android:padding="8dp"
android:fontFamily="sans-serif-condensed"
android:textStyle="italic"
android:gravity="center_horizontal" />
<ProgressBar
android:id="@android:id/progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:layout_marginBottom="@dimen/activity_vertical_margin"
android:layout_marginStart="@dimen/activity_horizontal_margin"
android:layout_marginEnd="@dimen/activity_horizontal_margin"
android:layout_marginLeft="@dimen/activity_horizontal_margin"
android:layout_marginRight="@dimen/activity_horizontal_margin"
android:layout_gravity="center"
android:padding="8dp" />
<GridView
android:id="@+id/grid"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="@dimen/activity_horizontal_margin"
android:paddingEnd="@dimen/activity_horizontal_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:scrollbarStyle="outsideOverlay"
android:stretchMode="columnWidth"
android:numColumns="auto_fit" />
</FrameLayout>
</LinearLayout>

View File

@ -1,50 +0,0 @@
<?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/>.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="48dp"
android:padding="8dip"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:id="@android:id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="54sp"
android:fontFamily="sans-serif-light"
android:textSize="32sp"
android:textColor="@color/donation_normal"/>
<TextView
android:id="@android:id/summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:layout_marginLeft="4dp"
android:fontFamily="sans-serif-condensed"
android:textAllCaps="true"
android:textSize="12sp"
android:maxLines="2"
android:ellipsize="end"/>
</LinearLayout>

View File

@ -32,21 +32,6 @@
android:orientation="vertical" android:orientation="vertical"
> >
<TextView
android:id="@id/drawer_button_go_pro"
android:layout_width="match_parent"
android:layout_height="72dp"
android:text="@string/donation_action"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:gravity="center_vertical"
android:textSize="12sp"
android:clickable="true"
android:background="?selectableItemBackground"
android:textColor="@color/indigo"/>
<android.support.v7.widget.SwitchCompat <android.support.v7.widget.SwitchCompat
android:gravity="center_vertical" android:gravity="center_vertical"
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@ -21,10 +21,22 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android" <menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"> xmlns:app="http://schemas.android.com/apk/res-auto">
<item <item
android:id="@id/im_save" android:id="@id/im_save"
app:showAsAction="ifRoom" app:showAsAction="ifRoom"
android:icon="@drawable/ic_action_save" android:icon="@drawable/ic_action_save"
android:title="@string/salva">
<menu>
<item
android:id="@id/im_save_normaly"
app:showAsAction="ifRoom"
android:title="@string/salva"/> android:title="@string/salva"/>
<item
android:id="@id/im_save_as"
app:showAsAction="ifRoom"
android:title="@string/save_as"/>
</menu>
</item>
<item <item
android:id="@id/im_undo" android:id="@id/im_undo"
app:showAsAction="ifRoom" app:showAsAction="ifRoom"
@ -63,9 +75,4 @@
app:showAsAction="never" app:showAsAction="never"
android:title="@string/info" android:title="@string/info"
/> />
<item
android:id="@id/im_donate"
app:showAsAction="never"
android:title="@string/donation_action"
/>
</menu> </menu>

View File

@ -49,6 +49,11 @@
app:showAsAction="always" app:showAsAction="always"
android:title="@string/replace"> android:title="@string/replace">
</item> </item>
<item
android:id="@id/im_replace_all"
app:showAsAction="always"
android:title="@string/replace_all">
</item>
<!--<item <!--<item
android:id="@id/im_cancel" android:id="@id/im_cancel"
android:icon="@drawable/ic_action_close" android:icon="@drawable/ic_action_close"

View File

@ -20,6 +20,21 @@
<changelog bulletedList="true"> <changelog bulletedList="true">
<changelogversion versionName="1.15" changeDate="Oct 30, 2014">
<changelogtext>It is a "beta" release, feel free to send you feedback on github.com!</changelogtext>
<changelogtext>Added Save As! (and rename option)</changelogtext>
<changelogtext>Added Replace All!</changelogtext>
<changelogtext>Initial support to cloud files</changelogtext>
<changelogtext>The default encoding now is UTF-16</changelogtext>
<changelogtext>Removed donations items, if you want to donate please buy the pro version!</changelogtext>
<changelogtext>Minor bug fixes</changelogtext>
</changelogversion>
<changelogversion versionName="1.14" changeDate="Oct 30, 2014">
<changelogtext>Removed the ads because HAPPY NEW YEAR!!!</changelogtext>
<changelogtext>Minor bug fixes</changelogtext>
</changelogversion>
<changelogversion versionName="1.13.1" changeDate="Oct 30, 2014"> <changelogversion versionName="1.13.1" changeDate="Oct 30, 2014">
<changelogtext>Manly bug fixes</changelogtext> <changelogtext>Manly bug fixes</changelogtext>
</changelogversion> </changelogversion>

View File

@ -25,12 +25,12 @@
<string name="font_size">Schriftgröße</string> <string name="font_size">Schriftgröße</string>
<string name="connection_name">Verbindungsname</string> <string name="connection_name">Verbindungsname</string>
<string name="line_numbers">Zeilennummern</string> <string name="line_numbers">Zeilennummern</string>
<string name="wrap_content">Inhalts Umbruch</string> <string name="wrap_content">Zeilenumbruch</string>
<string name="view_it_on_the_web">Im Web anschauen</string> <string name="view_it_on_the_web">Im Web anschauen</string>
<string name="file">Datei</string> <string name="file">Datei</string>
<string name="folder">Ordner</string> <string name="folder">Ordner</string>
<string name="light_theme">Helles Design</string> <string name="light_theme">Helles Design</string>
<string name="goto_line">Gehe zu Linie</string> <string name="goto_line">Gehe zu Zeile&#8230;</string>
<string name="goto_page">Gehe zu Seite&#8230;</string> <string name="goto_page">Gehe zu Seite&#8230;</string>
<string name="find">Suchen</string> <string name="find">Suchen</string>
<string name="replace">Ersetzen</string> <string name="replace">Ersetzen</string>

View File

@ -22,13 +22,13 @@
<string name="close">Schließen</string> <string name="close">Schließen</string>
<string name="about_action">Über</string> <string name="about_action">Über</string>
<string name="about_message"><![CDATA[ <string name="about_message"><![CDATA[
Turbo Editor is a free and <a href="http://github.com/vmihalachi/turbo-editor">open source</a> app. Turbo Editor ist eine freie und <a href="http://github.com/vmihalachi/turbo-editor">quelloffene</a> Anwendung.
Copyright 2013-2014 <a href="https://plus.google.com/+VladMihalachi">Vlad Mihalachi</a>. All Rights Reserved.<br/> Copyright 2013-2014 <a href="https://plus.google.com/+VladMihalachi">Vlad Mihalachi</a>. All Rights Reserved.<br/>
<br/> <br/>
Many thanks to all who Vielen dank an alle Personen,
<a href="http://crowdin.net/project/turbo-client">helped with translations</a> or <a href="http://crowdin.net/project/turbo-client">die bei der Übersetzung geholfen</a> oder
donated to me.<br/> gespendet haben.<br/>
<br/> <br/>
If you want to send feedback here is the <a href="http://forum.xda-developers.com/android/apps-games/app-turbo-editor-text-editor-t2832016">XDA thread</a> Wenn Sie ein Feedback geben möchten, hier der <a href="http://forum.xda-developers.com/android/apps-games/app-turbo-editor-text-editor-t2832016">XDA Beitrag</a>
]]></string> ]]></string>
</resources> </resources>

View File

@ -20,18 +20,18 @@
--> -->
<resources> <resources>
<string name="donation_action">Spenden</string> <string name="donation_action">Spenden</string>
<string name="donation_title">Donate to developer</string> <string name="donation_title">An den Entwickler spenden</string>
<string name="donation_info"><![CDATA[ <string name="donation_info"><![CDATA[
Turbo Editor is a free and <a href="http://github.com/vmihalachi/turbo-editor/">open source</a> app. Turbo Editor ist eine freie und <a href="http://github.com/vmihalachi/turbo-editor/">quelloffene</a> Anwendung.
You can show your appreciation and support development by donating: Du kannst deine Anerkennung zeigen, in dem du die Entwicklung mit Spenden unterstützt:
]]></string> ]]></string>
<string name="donation_item_bought">You\'ve donated for this item already.</string> <string name="donation_item_bought">Du hast bereits gespendet.</string>
<string name="donation_2">An ice cream</string> <string name="donation_2">Eine Kugel Eis</string>
<string name="donation_4">Cup of coffee</string> <string name="donation_4">Tasse Kaffee</string>
<string name="donation_10">Electricity bills</string> <string name="donation_10">Stromrechnung</string>
<string name="donation_20">The right pillow</string> <string name="donation_20">Das richtige Kissen</string>
<string name="donation_50">Solid-state drive</string> <string name="donation_50">SSD Festplatte</string>
<string name="donation_99">Sound system</string> <string name="donation_99">Sound-System</string>
<string name="donation_error_iab_setup">Failed to setup in-app-billing service!</string> <string name="donation_error_iab_setup">Fehler beim Einrichten des In-App-Bezahlservices!</string>
<string name="donation_no_responsibility">Notice that Google is not responsible for that payments method.</string> <string name="donation_no_responsibility">Beachten Sie, dass Google für diese Zahlungsmethode nicht verantwortlich ist.</string>
</resources> </resources>

View File

@ -28,7 +28,7 @@
<string name="wrap_content">Ajuste de línea</string> <string name="wrap_content">Ajuste de línea</string>
<string name="view_it_on_the_web">Ver en la web</string> <string name="view_it_on_the_web">Ver en la web</string>
<string name="file">Archivo</string> <string name="file">Archivo</string>
<string name="folder">archivo</string> <string name="folder">Carpeta</string>
<string name="light_theme">Tema claro</string> <string name="light_theme">Tema claro</string>
<string name="goto_line">Ir a línea</string> <string name="goto_line">Ir a línea</string>
<string name="goto_page">Ir a página&#8230;</string> <string name="goto_page">Ir a página&#8230;</string>

View File

@ -20,7 +20,7 @@
--> -->
<resources> <resources>
<string name="donation_action">Donar</string> <string name="donation_action">Donar</string>
<string name="donation_title">Donate to developer</string> <string name="donation_title">Donar al desarrollador</string>
<string name="donation_info"><![CDATA[ <string name="donation_info"><![CDATA[
Turbo Editor is a free and <a href="http://github.com/vmihalachi/turbo-editor/">open source</a> app. Turbo Editor is a free and <a href="http://github.com/vmihalachi/turbo-editor/">open source</a> app.
You can show your appreciation and support development by donating: You can show your appreciation and support development by donating:

View File

@ -30,7 +30,7 @@
<string name="file">Tiedosto</string> <string name="file">Tiedosto</string>
<string name="folder">Kansio</string> <string name="folder">Kansio</string>
<string name="light_theme">Vaalea teema</string> <string name="light_theme">Vaalea teema</string>
<string name="goto_line">Siirry riville</string> <string name="goto_line">Siirry riville&#8230;</string>
<string name="goto_page">Siirry sivulle&#8230;</string> <string name="goto_page">Siirry sivulle&#8230;</string>
<string name="find">Löydä</string> <string name="find">Löydä</string>
<string name="replace">Korvaa</string> <string name="replace">Korvaa</string>
@ -51,7 +51,7 @@
<string name="translate_the_app">Auta kääntämisessä</string> <string name="translate_the_app">Auta kääntämisessä</string>
<string name="changelog">Muutosloki</string> <string name="changelog">Muutosloki</string>
<string name="match_case">Sama kirjainkoko</string> <string name="match_case">Sama kirjainkoko</string>
<string name="long_click_for_more_options">Saat lisää vaihtoehtoja napsauttamalla</string> <string name="long_click_for_more_options">Saat lisää vaihtoehtoja pitkällä painalluksella</string>
<string name="auto_save">Automaattinen tallennus</string> <string name="auto_save">Automaattinen tallennus</string>
<string name="read_only">Vain luku</string> <string name="read_only">Vain luku</string>
<string name="send_error_reports">Lähetä virheraportit</string> <string name="send_error_reports">Lähetä virheraportit</string>

View File

@ -22,12 +22,12 @@
<string name="close">Sulje</string> <string name="close">Sulje</string>
<string name="about_action">Tietoja</string> <string name="about_action">Tietoja</string>
<string name="about_message"><![CDATA[ <string name="about_message"><![CDATA[
Turbo Editor on ilmainen ja <a href="http://github.com/vmihalachi/turbo-editor">avoimen lähdekoodin</a> sovellus. Turbo Editor on ilmainen ja <a href="http://github.com/vmihalachi/turbo-editor">avoimen lähdekoodin</a> sovellus.
Tekijänoikeudet 2013-2014 <a href="https://plus.google.com/+VladMihalachi">Vlad Mihalachi</a>. Kaikki oikeudet pidätetään.<br/> Tekijänoikeudet 2013-2014 <a href="https://plus.google.com/+VladMihalachi">Vlad Mihalachi</a>. Kaikki oikeudet pidätetään.<br/>
<br/> <br/>
Suuret kiitokset kaikille, jotka Suuret kiitokset kaikille, jotka
<a href="http://crowdin.net/project/turbo-client">auttoivat käännöksien parissa</a> tai <a href="http://crowdin.net/project/turbo-client">auttoivat käännöksien parissa</a> tai
lahjoittivat minulle</a>.<br/> lahjoittivat minulle.<br/>
<br/> <br/>
Jos haluat lähettää palautetta, kerro se siitä <a href="http://forum.xda-developers.com/android/apps-games/app-turbo-editor-text-editor-t2832016">XDA-ketjussa</a> Jos haluat lähettää palautetta, kerro se siitä <a href="http://forum.xda-developers.com/android/apps-games/app-turbo-editor-text-editor-t2832016">XDA-ketjussa</a>
]]></string> ]]></string>

View File

@ -28,7 +28,7 @@
<string name="donation_item_bought">Olet lahjoittanut tälle kohteelle jo.</string> <string name="donation_item_bought">Olet lahjoittanut tälle kohteelle jo.</string>
<string name="donation_2">Jäätelöä</string> <string name="donation_2">Jäätelöä</string>
<string name="donation_4">Kuppi kahvia</string> <string name="donation_4">Kuppi kahvia</string>
<string name="donation_10">Sähkölasku</string> <string name="donation_10">Sähkölaskut</string>
<string name="donation_20">Oikea tyyny</string> <string name="donation_20">Oikea tyyny</string>
<string name="donation_50">SSD-levy</string> <string name="donation_50">SSD-levy</string>
<string name="donation_99">Äänijärjestelmä</string> <string name="donation_99">Äänijärjestelmä</string>

View File

@ -20,13 +20,13 @@
--> -->
<!--Generated by crowdin.net--> <!--Generated by crowdin.net-->
<resources> <resources>
<string name="use_monospace">Use monospace</string> <string name="use_monospace">Monospace को उपयोग करें</string>
<string name="recent_files">Recent files</string> <string name="recent_files">हाल ही की दस्तावेज</string>
<string name="font_size">Font size</string> <string name="font_size">Font size</string>
<string name="connection_name">Connection Name</string> <string name="connection_name">Connection Name</string>
<string name="line_numbers">Line Numbers</string> <string name="line_numbers">पंक्ति क्रमांक</string>
<string name="wrap_content">Wrap content</string> <string name="wrap_content">सामग्री लपेटें</string>
<string name="view_it_on_the_web">View it on the web</string> <string name="view_it_on_the_web">यह वेब पर देखें</string>
<string name="file">File</string> <string name="file">File</string>
<string name="folder">Folder</string> <string name="folder">Folder</string>
<string name="light_theme">Light Theme</string> <string name="light_theme">Light Theme</string>

View File

@ -31,7 +31,7 @@
<string name="folder">Mappa</string> <string name="folder">Mappa</string>
<string name="light_theme">Világos téma</string> <string name="light_theme">Világos téma</string>
<string name="goto_line">Sorhoz ugrás</string> <string name="goto_line">Sorhoz ugrás</string>
<string name="goto_page">Go to Page&#8230;</string> <string name="goto_page">Ugrás oldalra&#8230;</string>
<string name="find">Keresés</string> <string name="find">Keresés</string>
<string name="replace">Csere</string> <string name="replace">Csere</string>
<string name="share">Megosztás</string> <string name="share">Megosztás</string>
@ -54,11 +54,11 @@
<string name="long_click_for_more_options">Hosszú-kattintás a további beállításokhoz</string> <string name="long_click_for_more_options">Hosszú-kattintás a további beállításokhoz</string>
<string name="auto_save">Automatikus mentés</string> <string name="auto_save">Automatikus mentés</string>
<string name="read_only">Csak olvasható</string> <string name="read_only">Csak olvasható</string>
<string name="send_error_reports">Send error reports</string> <string name="send_error_reports">Hibajelentés küldése</string>
<string name="extra_options">Extra options</string> <string name="extra_options">Extra beállítások</string>
<string name="split_text_if_too_long">Split the text if too long</string> <string name="split_text_if_too_long">A szöveg részekre bontása ha túl hosszú</string>
<string name="ignore_back_button">Ignore back button</string> <string name="ignore_back_button">Vissza-gomb figyelmen kívül hagyása</string>
<string name="donate">Donate</string> <string name="donate">Támogatás</string>
<string name="codifica">Kódolás</string> <string name="codifica">Kódolás</string>
<string name="condividi">Megosztás</string> <string name="condividi">Megosztás</string>
<string name="info">Információ</string> <string name="info">Információ</string>
@ -71,6 +71,6 @@
<string name="open">Megnyit</string> <string name="open">Megnyit</string>
<string name="file_saved_with_success">A(z) %1$s fájl sikeresen mentve!</string> <string name="file_saved_with_success">A(z) %1$s fájl sikeresen mentve!</string>
<string name="open_a_file">Fájl megnyitása</string> <string name="open_a_file">Fájl megnyitása</string>
<string name="no">No</string> <string name="no">Nem</string>
<string name="new_file">New file</string> <string name="new_file">Új fájl</string>
</resources> </resources>

View File

@ -19,16 +19,16 @@
~ along with this program. If not, see <http://www.gnu.org/licenses/>. ~ along with this program. If not, see <http://www.gnu.org/licenses/>.
--> -->
<resources> <resources>
<string name="close">Close</string> <string name="close">Bezárás</string>
<string name="about_action">About</string> <string name="about_action">Névjegy</string>
<string name="about_message"><![CDATA[ <string name="about_message"><![CDATA[
Turbo Editor is a free and <a href="http://github.com/vmihalachi/turbo-editor">open source</a> app. A Turbo Editor szabad és <a href="http://github.com/vmihalachi/turbo-editor">nyílt forráskódú</a> alkalmazás.
Copyright 2013-2014 <a href="https://plus.google.com/+VladMihalachi">Vlad Mihalachi</a>. All Rights Reserved.<br/> Copyright 2013-2014 <a href="https://plus.google.com/+VladMihalachi">Vlad Mihalachi</a>. All Rights Reserved.<br/>
<br/> <br/>
Many thanks to all who Köszönet mindazoknak akik
<a href="http://crowdin.net/project/turbo-client">helped with translations</a> or <a href="http://crowdin.net/project/turbo-client">segítettek a fordításban</a> vagy
donated to me.<br/> támogatást adtak.<br/>
<br/> <br/>
If you want to send feedback here is the <a href="http://forum.xda-developers.com/android/apps-games/app-turbo-editor-text-editor-t2832016">XDA thread</a> Visszajelzéseket az <a href="http://forum.xda-developers.com/android/apps-games/app-turbo-editor-text-editor-t2832016">XDA fórumon</a> lehet küldeni
]]></string> ]]></string>
</resources> </resources>

View File

@ -19,19 +19,19 @@
~ along with this program. If not, see <http://www.gnu.org/licenses/>. ~ along with this program. If not, see <http://www.gnu.org/licenses/>.
--> -->
<resources> <resources>
<string name="donation_action">Donate</string> <string name="donation_action">Támogatás</string>
<string name="donation_title">Donate to developer</string> <string name="donation_title">Támogatás a fejlesztőnek</string>
<string name="donation_info"><![CDATA[ <string name="donation_info"><![CDATA[
Turbo Editor is a free and <a href="http://github.com/vmihalachi/turbo-editor/">open source</a> app. A Turbo Editor egy szabad és <a href="http://github.com/vmihalachi/turbo-editor/">nyílt forrású</a> alkalmazás.
You can show your appreciation and support development by donating: Mutassa meg mennyire értékeli és támogathassa a fejlesztést:
]]></string> ]]></string>
<string name="donation_item_bought">You\'ve donated for this item already.</string> <string name="donation_item_bought">Ön már támogatta ezt.</string>
<string name="donation_2">An ice cream</string> <string name="donation_2">Egy jégkrém</string>
<string name="donation_4">Cup of coffee</string> <string name="donation_4">Egy csésze kávé</string>
<string name="donation_10">Electricity bills</string> <string name="donation_10">Villany számla</string>
<string name="donation_20">The right pillow</string> <string name="donation_20">A jobb oldali párna</string>
<string name="donation_50">Solid-state drive</string> <string name="donation_50">Szilárdtest-meghajtó</string>
<string name="donation_99">Sound system</string> <string name="donation_99">Hang-rendszer</string>
<string name="donation_error_iab_setup">Failed to setup in-app-billing service!</string> <string name="donation_error_iab_setup">Nem sikerült beállítani az alkalmazáson belüli fizetést!</string>
<string name="donation_no_responsibility">Notice that Google is not responsible for that payments method.</string> <string name="donation_no_responsibility">Ne felejtse el, hogy a Google nem felel a fizetési módszerekért.</string>
</resources> </resources>

View File

@ -25,52 +25,52 @@
<string name="font_size">Ukuran font</string> <string name="font_size">Ukuran font</string>
<string name="connection_name">Nama Sambungan</string> <string name="connection_name">Nama Sambungan</string>
<string name="line_numbers">Nomor Baris</string> <string name="line_numbers">Nomor Baris</string>
<string name="wrap_content">Wrap Konten</string> <string name="wrap_content">Rapatkan Konten</string>
<string name="view_it_on_the_web">Lihat di web</string> <string name="view_it_on_the_web">Lihat di web</string>
<string name="file">File</string> <string name="file">File</string>
<string name="folder">Folder</string> <string name="folder">Folder</string>
<string name="light_theme">Tema Terang</string> <string name="light_theme">Tema Terang</string>
<string name="goto_line">Pergi ke Baris</string> <string name="goto_line">Pergi ke Baris</string>
<string name="goto_page">Go to Page&#8230;</string> <string name="goto_page">Pergi ke halaman...</string>
<string name="find">Cari</string> <string name="find">Temukan</string>
<string name="replace">Replace</string> <string name="replace">Ganti</string>
<string name="share">Bagikan</string> <string name="share">Bagikan</string>
<string name="keyboard_suggestions_and_swipe">Keyboard suggestions and Swipe</string> <string name="keyboard_suggestions_and_swipe">Saran keyboard dan usapan</string>
<string name="enable_autoencoding">Pengkodean-Otomatis</string> <string name="enable_autoencoding">Pengkodean-Otomatis</string>
<string name="set_as_working_folder">Set as the working folder</string> <string name="set_as_working_folder">Jadikan sebagai folder kerja</string>
<string name="is_the_working_folder">This is the working folder</string> <string name="is_the_working_folder">Ini adalah folder kerja</string>
<string name="save_changes">Do you want to save the changes to the file %s?</string> <string name="save_changes">Apakah Anda ingin menyimpan perubahan pada file ini %s?</string>
<string name="regular_expression">Regular Expression</string> <string name="regular_expression">Ekspresi Reguler</string>
<string name="text_to_find">Text to find</string> <string name="text_to_find">Ketik untuk mencari</string>
<string name="text_to_replace">Text to replace</string> <string name="text_to_replace">Ketik untuk mengganti</string>
<string name="next">Next</string> <string name="next">Lanjut</string>
<string name="previous">Previous</string> <string name="previous">Sebelum</string>
<string name="please_wait">Please wait&#8230;</string> <string name="please_wait">Harap tunggu...</string>
<string name="occurrences_found">%s occurrences was found</string> <string name="occurrences_found">%s kejadian ditemukan</string>
<string name="app_version_new">v%s</string> <string name="app_version_new">v%s</string>
<string name="translate_the_app">Translate</string> <string name="translate_the_app">Terjemahkan</string>
<string name="changelog">Changelog</string> <string name="changelog">Daftar perubahan</string>
<string name="match_case">Match case</string> <string name="match_case">Penyesuaian</string>
<string name="long_click_for_more_options">Long click for more options</string> <string name="long_click_for_more_options">Klik tahan untuk opsi lanjut</string>
<string name="auto_save">Auto save</string> <string name="auto_save">Simpan otomatis</string>
<string name="read_only">Read only</string> <string name="read_only">Hanya baca</string>
<string name="send_error_reports">Send error reports</string> <string name="send_error_reports">Kirim laporan kesalahan</string>
<string name="extra_options">Extra options</string> <string name="extra_options">Opsi ekstra</string>
<string name="split_text_if_too_long">Split the text if too long</string> <string name="split_text_if_too_long">Membagi teks jika terlalu panjang</string>
<string name="ignore_back_button">Ignore back button</string> <string name="ignore_back_button">Abaikan tombol kembali</string>
<string name="donate">Donate</string> <string name="donate">Donasi</string>
<string name="codifica">Pengkodean</string> <string name="codifica">Pengkodean</string>
<string name="condividi">Bagikan</string> <string name="condividi">Bagikan</string>
<string name="info">Info</string> <string name="info">Info</string>
<string name="nome_app_turbo_editor">Editor Turbo</string> <string name="nome_app_turbo_editor">Turbo Editor</string>
<string name="preferenze">Preferensi</string> <string name="preferenze">Preferensi</string>
<string name="salva">Simpan</string> <string name="salva">Simpan</string>
<string name="menu_syntax_highlight">Highlight syntax</string> <string name="menu_syntax_highlight">Sorot sintaks</string>
<string name="testo_indietro">Batal</string> <string name="testo_indietro">Batalkan</string>
<string name="testo_rifai">Ulangi</string> <string name="testo_rifai">Ulangi</string>
<string name="open">Buka</string> <string name="open">Buka</string>
<string name="file_saved_with_success">File %1$s berhasil disimpan!</string> <string name="file_saved_with_success">File %1$s berhasil disimpan!</string>
<string name="open_a_file">Buka file</string> <string name="open_a_file">Buka file</string>
<string name="no">No</string> <string name="no">Tidak</string>
<string name="new_file">New file</string> <string name="new_file">File baru</string>
</resources> </resources>

View File

@ -19,16 +19,15 @@
~ along with this program. If not, see <http://www.gnu.org/licenses/>. ~ along with this program. If not, see <http://www.gnu.org/licenses/>.
--> -->
<resources> <resources>
<string name="close">Close</string> <string name="close">Tutup</string>
<string name="about_action">About</string> <string name="about_action">Tentang</string>
<string name="about_message"><![CDATA[ <string name="about_message"><![CDATA[
Turbo Editor is a free and <a href="http://github.com/vmihalachi/turbo-editor">open source</a> app. Turbo Editor adalah sebuah aplikasi gratis dan <a href="http://github.com/vmihalachi/turbo-editor">open source</a> app.
Copyright 2013-2014 <a href="https://plus.google.com/+VladMihalachi">Vlad Mihalachi</a>. All Rights Reserved.<br/> Copyright 2013-2014 <a href="https://plus.google.com/+VladMihalachi">Vlad Mihalachi</a>. All Rights Reserved.<br/>
<br/> <br/>
Many thanks to all who Banyak terima kasih saya ucapkan kepada
<a href="http://crowdin.net/project/turbo-client">helped with translations</a> or <a href="http://crowdin.net/project/turbo-client">yang telah membantu menerjemahkan aplikasi ini</a> or
donated to me.<br/> donasi kepada saya.<br/>
<br/> <br/>
If you want to send feedback here is the <a href="http://forum.xda-developers.com/android/apps-games/app-turbo-editor-text-editor-t2832016">XDA thread</a> Jika Anda ingin mengirim saran atau kritik <a href="http://forum.xda-developers.com/android/apps-games/app-turbo-editor-text-editor-t2832016">Artikel di XDA</a> ]]></string>
]]></string>
</resources> </resources>

View File

@ -19,19 +19,18 @@
~ along with this program. If not, see <http://www.gnu.org/licenses/>. ~ along with this program. If not, see <http://www.gnu.org/licenses/>.
--> -->
<resources> <resources>
<string name="donation_action">Donate</string> <string name="donation_action">Donasi</string>
<string name="donation_title">Donate to developer</string> <string name="donation_title">Donasi untuk pengembang</string>
<string name="donation_info"><![CDATA[ <string name="donation_info"><![CDATA[
Turbo Editor is a free and <a href="http://github.com/vmihalachi/turbo-editor/">open source</a> app. Turbo Editor adalah sebuah aplikasi gratis dani <a href="http://github.com/vmihalachi/turbo-editor/">open source</a> app.
You can show your appreciation and support development by donating: Anda dapat melihat apresiasi Anda dan dukungan pada pengembang dengan memberikan donasi: ]]></string>
]]></string> <string name="donation_item_bought">Anda telah mendonasikan untuk item ini.</string>
<string name="donation_item_bought">You\'ve donated for this item already.</string> <string name="donation_2">Sebuah es krim</string>
<string name="donation_2">An ice cream</string> <string name="donation_4">Secangkir kopi</string>
<string name="donation_4">Cup of coffee</string> <string name="donation_10">Tagihan listrik</string>
<string name="donation_10">Electricity bills</string> <string name="donation_20">Bantal yang tepat</string>
<string name="donation_20">The right pillow</string> <string name="donation_50">Solid-state drive (SSD)</string>
<string name="donation_50">Solid-state drive</string> <string name="donation_99">Sistem suara</string>
<string name="donation_99">Sound system</string> <string name="donation_error_iab_setup">Gagal dalam menyeting layanan pembelian dalam aplikasi!</string>
<string name="donation_error_iab_setup">Failed to setup in-app-billing service!</string> <string name="donation_no_responsibility">Perhatikan bahwa Google tidak bertanggung jawab untuk metode pembayaran.</string>
<string name="donation_no_responsibility">Notice that Google is not responsible for that payments method.</string>
</resources> </resources>

View File

@ -31,7 +31,7 @@
<string name="folder">Folder</string> <string name="folder">Folder</string>
<string name="light_theme">Jasny motyw</string> <string name="light_theme">Jasny motyw</string>
<string name="goto_line">Idź do linii</string> <string name="goto_line">Idź do linii</string>
<string name="goto_page">Go to Page&#8230;</string> <string name="goto_page">Idź do strony&#8230;</string>
<string name="find">Znajdź</string> <string name="find">Znajdź</string>
<string name="replace">Zastąp</string> <string name="replace">Zastąp</string>
<string name="share">Udostępnij</string> <string name="share">Udostępnij</string>
@ -47,18 +47,18 @@
<string name="previous">Poprzedni</string> <string name="previous">Poprzedni</string>
<string name="please_wait">Proszę czekać&#8230;</string> <string name="please_wait">Proszę czekać&#8230;</string>
<string name="occurrences_found">Znaleziono %s wystąpień</string> <string name="occurrences_found">Znaleziono %s wystąpień</string>
<string name="app_version_new">v%s</string> <string name="app_version_new">wersja %s</string>
<string name="translate_the_app">Tłumacz</string> <string name="translate_the_app">Tłumacz</string>
<string name="changelog">Lista zmian</string> <string name="changelog">Lista zmian</string>
<string name="match_case">Uwzględnij wielkość liter</string> <string name="match_case">Uwzględnij wielkość liter</string>
<string name="long_click_for_more_options">Przytrzymaj dłużej aby zobaczyć więcej opcji</string> <string name="long_click_for_more_options">Przytrzymaj dłużej aby zobaczyć więcej opcji</string>
<string name="auto_save">Automatyczny zapis</string> <string name="auto_save">Automatyczny zapis</string>
<string name="read_only">Tylko do odczytu</string> <string name="read_only">Tylko do odczytu</string>
<string name="send_error_reports">Send error reports</string> <string name="send_error_reports">Wyślij raport o błędach</string>
<string name="extra_options">Extra options</string> <string name="extra_options">Dodatkowe opcje</string>
<string name="split_text_if_too_long">Split the text if too long</string> <string name="split_text_if_too_long">Podziel tekst, jeśli jest zbyt długi</string>
<string name="ignore_back_button">Ignore back button</string> <string name="ignore_back_button">Ignoruj przycisk \"Wstecz\"</string>
<string name="donate">Donate</string> <string name="donate">Wesprzyj mnie</string>
<string name="codifica">Kodowanie</string> <string name="codifica">Kodowanie</string>
<string name="condividi">Udostępnij</string> <string name="condividi">Udostępnij</string>
<string name="info">Informacje</string> <string name="info">Informacje</string>
@ -71,6 +71,6 @@
<string name="open">Otwórz</string> <string name="open">Otwórz</string>
<string name="file_saved_with_success">Plik %1$s został pomyślnie zapisany!</string> <string name="file_saved_with_success">Plik %1$s został pomyślnie zapisany!</string>
<string name="open_a_file">Otwórz plik</string> <string name="open_a_file">Otwórz plik</string>
<string name="no">No</string> <string name="no">Nie</string>
<string name="new_file">New file</string> <string name="new_file">Nowy plik</string>
</resources> </resources>

View File

@ -19,8 +19,8 @@
~ along with this program. If not, see <http://www.gnu.org/licenses/>. ~ along with this program. If not, see <http://www.gnu.org/licenses/>.
--> -->
<resources> <resources>
<string name="close">Close</string> <string name="close">Zamknij</string>
<string name="about_action">About</string> <string name="about_action">O aplikacji i autorach</string>
<string name="about_message"><![CDATA[ <string name="about_message"><![CDATA[
Turbo Editor is a free and <a href="http://github.com/vmihalachi/turbo-editor">open source</a> app. Turbo Editor is a free and <a href="http://github.com/vmihalachi/turbo-editor">open source</a> app.
Copyright 2013-2014 <a href="https://plus.google.com/+VladMihalachi">Vlad Mihalachi</a>. All Rights Reserved.<br/> Copyright 2013-2014 <a href="https://plus.google.com/+VladMihalachi">Vlad Mihalachi</a>. All Rights Reserved.<br/>

View File

@ -19,8 +19,8 @@
~ along with this program. If not, see <http://www.gnu.org/licenses/>. ~ along with this program. If not, see <http://www.gnu.org/licenses/>.
--> -->
<resources> <resources>
<string name="donation_action">Donate</string> <string name="donation_action">Wesprzyj mnie</string>
<string name="donation_title">Donate to developer</string> <string name="donation_title">Wspomóż twórcę</string>
<string name="donation_info"><![CDATA[ <string name="donation_info"><![CDATA[
Turbo Editor is a free and <a href="http://github.com/vmihalachi/turbo-editor/">open source</a> app. Turbo Editor is a free and <a href="http://github.com/vmihalachi/turbo-editor/">open source</a> app.
You can show your appreciation and support development by donating: You can show your appreciation and support development by donating:

View File

@ -71,6 +71,6 @@
<string name="open">Abrir</string> <string name="open">Abrir</string>
<string name="file_saved_with_success">O arquivo %1$s foi salvo com sucesso!</string> <string name="file_saved_with_success">O arquivo %1$s foi salvo com sucesso!</string>
<string name="open_a_file">Abrir um arquivo</string> <string name="open_a_file">Abrir um arquivo</string>
<string name="no">No</string> <string name="no">Não</string>
<string name="new_file">New file</string> <string name="new_file">Novo arquivo</string>
</resources> </resources>

View File

@ -30,13 +30,13 @@
<string name="file">Файл</string> <string name="file">Файл</string>
<string name="folder">Каталог</string> <string name="folder">Каталог</string>
<string name="light_theme">Светлая тема</string> <string name="light_theme">Светлая тема</string>
<string name="goto_line">Перейти к строке</string> <string name="goto_line">Перейти к строке&#8230;</string>
<string name="goto_page">Перейти на страницу&#8230;</string> <string name="goto_page">Перейти на страницу&#8230;</string>
<string name="find">Поиск</string> <string name="find">Поиск</string>
<string name="replace">Заменить</string> <string name="replace">Заменить</string>
<string name="share">Поделиться</string> <string name="share">Поделиться</string>
<string name="keyboard_suggestions_and_swipe">Car</string> <string name="keyboard_suggestions_and_swipe">Показывать варианты исправлений</string>
<string name="enable_autoencoding">Copy</string> <string name="enable_autoencoding">Автоопределение кодировки</string>
<string name="set_as_working_folder">Установить в качестве рабочего каталога</string> <string name="set_as_working_folder">Установить в качестве рабочего каталога</string>
<string name="is_the_working_folder">Это рабочий каталог</string> <string name="is_the_working_folder">Это рабочий каталог</string>
<string name="save_changes">Сохранить изменения в файле %s?</string> <string name="save_changes">Сохранить изменения в файле %s?</string>
@ -54,7 +54,7 @@
<string name="long_click_for_more_options">Долгое нажатие для дополнительных опций</string> <string name="long_click_for_more_options">Долгое нажатие для дополнительных опций</string>
<string name="auto_save">Автосохранение</string> <string name="auto_save">Автосохранение</string>
<string name="read_only">Только для чтения</string> <string name="read_only">Только для чтения</string>
<string name="send_error_reports">Отправить отчёт об ошибке</string> <string name="send_error_reports">Отправлять отчёты об ошибках</string>
<string name="extra_options">Дополнительные опции</string> <string name="extra_options">Дополнительные опции</string>
<string name="split_text_if_too_long">Разбивать длинный текст</string> <string name="split_text_if_too_long">Разбивать длинный текст</string>
<string name="ignore_back_button">Игнорировать кнопку Назад</string> <string name="ignore_back_button">Игнорировать кнопку Назад</string>

View File

@ -20,18 +20,18 @@
--> -->
<resources> <resources>
<string name="donation_action">Поддержать</string> <string name="donation_action">Поддержать</string>
<string name="donation_title">Donate to developer</string> <string name="donation_title">Пожертвовать разработчику</string>
<string name="donation_info"><![CDATA[ <string name="donation_info"><![CDATA[
Turbo Editor is a free and <a href="http://github.com/vmihalachi/turbo-editor/">open source</a> app. Turbo Editor является бесплатной и <a href="http://github.com/vmihalachi/turbo-editor/">open source</a> программой.
You can show your appreciation and support development by donating: Вы можете выразить свою признательность и поддержку, пожертвовав:
]]></string> ]]></string>
<string name="donation_item_bought">You\'ve donated for this item already.</string> <string name="donation_item_bought">Вы уже пожертвовали.</string>
<string name="donation_2">An ice cream</string> <string name="donation_2">Мороженое</string>
<string name="donation_4">Cup of coffee</string> <string name="donation_4">Чашка кофе</string>
<string name="donation_10">Electricity bills</string> <string name="donation_10">Счета за электричество</string>
<string name="donation_20">The right pillow</string> <string name="donation_20">Отличная подушка</string>
<string name="donation_50">Solid-state drive</string> <string name="donation_50">Твердотельный накопитель</string>
<string name="donation_99">Sound system</string> <string name="donation_99">Звуковая система</string>
<string name="donation_error_iab_setup">Failed to setup in-app-billing service!</string> <string name="donation_error_iab_setup">Не удалось запустить внутреннюю службу биллинга!</string>
<string name="donation_no_responsibility">Notice that Google is not responsible for that payments method.</string> <string name="donation_no_responsibility">Имейте в виду, что Google не несет ответственности за данный способ оплаты.</string>
</resources> </resources>

View File

@ -1,4 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<!-- <!--
~ Copyright (C) 2014 Vlad Mihalachi ~ Copyright (C) 2014 Vlad Mihalachi
~ ~
@ -17,137 +18,59 @@
~ You should have received a copy of the GNU General Public License ~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <http://www.gnu.org/licenses/>. ~ along with this program. If not, see <http://www.gnu.org/licenses/>.
--> -->
<!--Generated by crowdin.com-->
<!--Generated by crowdin.net--> <!--Generated by crowdin.net-->
<resources> <resources>
<string name="aggiungi_account">Nový účet</string> <string name="use_monospace">Použiť neproporcionálne</string>
<string name="attiva">Aktívne</string> <string name="recent_files">Nedávne súbory</string>
<string name="cancella">Vymazať</string> <string name="font_size">Veľkosť písma</string>
<string name="cancellazione">Mažem súbory&#8230;</string> <string name="connection_name">Názov pripojenia</string>
<string name="caricamento">Načítavanie&#8230;</string> <string name="line_numbers">Čísla riadkov</string>
<string name="cartella_locale_corrente">Aktuálna miestna zložka</string> <string name="wrap_content">Zalomiť obsah</string>
<string name="chiave_privata">Súkromný kľúč</string> <string name="view_it_on_the_web">Zobraziť na webe</string>
<string name="chiaro">Svetlá</string> <string name="file">Súbor</string>
<string name="folder">Adresár</string>
<string name="light_theme">Svetlá téma</string>
<string name="goto_line">Prejsť na riadok&#8230;</string>
<string name="goto_page">Prejsť na stránku&#8230;</string>
<string name="find">Nájsť</string>
<string name="replace">Nahradiť</string>
<string name="share">Zdieľať</string>
<string name="keyboard_suggestions_and_swipe">Návrhy opráv a písanie gestami</string>
<string name="enable_autoencoding">Automatické kódovanie</string>
<string name="set_as_working_folder">Nastaviť ako pracovný adresár</string>
<string name="is_the_working_folder">Toto je pracovný adresár</string>
<string name="save_changes">Chcete uložiť zmeny v súbore %s?</string>
<string name="regular_expression">Presný výraz</string>
<string name="text_to_find">Text, ktorý chcete nájsť</string>
<string name="text_to_replace">Text, ktorý chcete nahradiť</string>
<string name="next">Ďalšie</string>
<string name="previous">Predchádzajúce</string>
<string name="please_wait">Prosím, počkajte&#8230;</string>
<string name="occurrences_found">%s výskytov bolo nájdených</string>
<string name="app_version_new">v%s</string>
<string name="translate_the_app">Preložiť</string>
<string name="changelog">Zoznam zmien</string>
<string name="match_case">Rozlišovať malé a veľké písmená</string>
<string name="long_click_for_more_options">Podržte dlhšie pre viac možností</string>
<string name="auto_save">Automatické ukladanie</string>
<string name="read_only">Iba na čítanie</string>
<string name="send_error_reports">Odoslať správy o chybách</string>
<string name="extra_options">Ďalšie voľby</string>
<string name="split_text_if_too_long">Rozdeliť text, ak je príliš dlhý</string>
<string name="ignore_back_button">Ignorovať tlačidlo späť</string>
<string name="donate">Prispieť</string>
<string name="codifica">Kódovanie</string> <string name="codifica">Kódovanie</string>
<string name="condividi">Zdieľať</string> <string name="condividi">Zdieľať</string>
<string name="crea_cartella_locale">Nový lokálny súbor</string> <string name="info">Informácie</string>
<string name="crea_cartella_remota">Nový vzdialený priečinok</string>
<string name="crea_file_remoto">New remote file</string>
<string name="new_local_file">New local file</string>
<string name="disconneti">Odpojiť sa</string>
<string name="default_local_folder">Predvol. miestna zložka</string>
<string name="dove_scaricare">Kde oi chcete stiahnuť?</string>
<string name="download">Stiahnuť</string>
<string name="download_completato">Sťahovanie dokončené</string>
<string name="duplicate">Duplikát</string>
<string name="fatto">Hotovo</string>
<string name="home">Domov</string>
<string name="host">Hosť</string>
<string name="info">Info</string>
<string name="locale">Lokálny</string>
<string name="log_in">Prihlasujem sa&#8230;</string>
<string name="modifica">Upraviť</string>
<string name="muovi">Presunúť</string>
<string name="nascondi">Schovať</string>
<string name="nome_app">Turbo Klient</string>
<string name="nome_app_turbo_editor">Turbo Editor</string> <string name="nome_app_turbo_editor">Turbo Editor</string>
<string name="nome_utente">Užív. meno</string>
<string name="passiva">Pasívny</string>
<string name="passphrase">Heslo</string>
<string name="password">Heslo</string>
<string name="password_summary">Ponechajte prázdne, pre výzvu pri každej relácii</string>
<string name="porta">Port</string>
<string name="preferenze">Predvoľby</string> <string name="preferenze">Predvoľby</string>
<string name="remoto">vzdialený</string>
<string name="riavva_per_tema">Pre zmenu témy, reštartujte aplikáciu</string>
<string name="rinomina">Premenovať</string>
<string name="root">Root</string>
<string name="salva">Uložiť</string> <string name="salva">Uložiť</string>
<string name="scuro">Tmavá</string> <string name="menu_syntax_highlight">Zvýrazniť syntax</string>
<string name="seleziona">Vybrať</string> <string name="testo_indietro">Späť</string>
<string name="seleziona_account">Vyberte účet</string> <string name="testo_rifai">Znova</string>
<string name="sicuro">Ste si istý?</string> <string name="open">Otvoriť</string>
<string name="something_failed">Niečo zlyhalo</string> <string name="file_saved_with_success">Súbor %1$s bol úspešne uložený!</string>
<string name="skip_same_file">Nepresúvajte rovnaký súbor</string> <string name="open_a_file">Otvoriť súbor</string>
<string name="tema_app">Téma</string> <string name="no">Nie</string>
<string name="tipo_connessione">Typ pripojenia</string> <string name="new_file">Nový súbor</string>
<string name="tipo_protocollo">Typ protokolu</string>
<string name="un_altra_cartella">Ďalšia zložka</string>
<string name="use_passphrase">Napíš heslo</string>
<string name="upload">Nahrať</string>
<string name="upload_completato">Nahrávanie dokončené</string>
<string name="what_to_do">Čo chceš robiť?</string>
<string name="menu_syntax_highlight">Syntax highlight</string>
<string name="testo_indietro">Vrátiť späť</string>
<string name="testo_rifai">Prerobiť</string>
<string name="sync">Synchronizovať</string>
<string name="remote_folder_to_sync">Vzdial. zložka na synchronizáciu</string>
<string name="local_folder_to_sync">Miestna zložka na synchronizáciu</string>
<string name="vota">Ohodnotiť</string>
<string name="inapp_unavailable">Nemožno kontaktovať Google Play</string>
<string name="inapp_description">Podpor rozvoj ďalších skvelých funkcií.</string>
<string name="upgrade_premium">Vylepšiť na Premium</string>
<string name="upgrade_premium_summary">Vylepši na Premium a podpor tým vývoj Turbo klienta!</string>
<string name="download_unlocked_version">Stiahnuť odomknutú verziu</string>
<string name="inapp_second_description">Čo pre teba Turbo klient znamená? Stanov si vlastnú cenu! </string>
<string name="inapp_first_description">Vylepši na Premium, pre odomknutie týchto funkcií:</string>
<string name="inapp_item_openandeditfiles">Power to open and modify any type of file.</string>
<string name="inapp_item_backup_service">Backup service to backup and restore your data safely. </string>
<string name="inapp_unlock_features">Unlock the Premium features</string>
<string name="inapp_seconditem_description">I really like this app!</string>
<string name="inapp_thirditem_description">I love this app!</string>
<string name="backup_accounts">Backup the accounts</string>
<string name="restore_accounts">Restore the accounts</string>
<string name="share_accounts">Backup and share the accounts</string>
<string name="importing_accounts">Importing the accounts&#8230;</string>
<string name="exporting_accounts">Exporting the accounts...</string>
<string name="backup_not_found">No backups found</string>
<string name="err_cant_open_the_file">Cannot open the file</string>
<string name="err_temp_folder_doesnt_exist">Temporary folder does not exist</string>
<string name="err_occured">An error occurred</string>
<string name="ui_ux">Ui</string>
<string name="remove">Remove</string>
<string name="modification_date">Modification date</string>
<string name="name">Name</string>
<string name="size">Size</string>
<string name="sort">Sort</string>
<string name="open">Open</string>
<string name="file_modified">The file %1$s was modified, do you want to upload it?</string>
<string name="file_saved_with_success">The file %1$s was saved with success!</string>
<string name="create_new_account">Create a new account</string>
<string name="create_new_account_to_start">Create a new account to start.</string>
<string name="type">Type</string>
<string name="send_feedback">Send feedback</string>
<string name="copy_url">Copy URL</string>
<string name="cut">Cut</string>
<string name="paste">paste</string>
<string name="advanced">Advanced</string>
<string name="auto">Auto</string>
<string name="bytes">Bytes</string>
<string name="unit_measurement_for_file_size">Unit of measurement for file size</string>
<string name="open_source_license">Open Source licenses</string>
<string name="open_source_license_summary">Show open source licenses</string>
<string name="open_a_file">Open a file</string>
<string name="open_this_time_only">Open this time only</string>
<string name="change_list_type">Change the list type</string>
<string name="use_monospace">Use monospace</string>
<string name="recent_files">Recent files</string>
<string name="font_size">Font size</string>
<string name="connection_name">Connection Name</string>
<string name="line_numbers">Line Numbers</string>
<string name="wrap_content">Wrap content</string>
<string name="view_it_on_the_web">View it on the web</string>
<string name="file_size_is_too_big">The file size is too big</string>
<string name="search">Search</string>
<string name="add">Add</string>
<string name="file">File</string>
<string name="folder">Folder</string>
<string name="light_theme">Light Theme</string>
<string name="goto_line">Goto Line</string>
<string name="find">Find</string>
<string name="find_and_replace">Find and Replace</string>
<string name="root_permission">Root Permission</string>
<string name="share">Zdieľať</string>
<string name="text_suggestions">Text Suggestions</string>
</resources> </resources>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<!-- <!--
~ Copyright (C) 2014 Vlad Mihalachi ~ Copyright (C) 2014 Vlad Mihalachi
~ ~
@ -19,5 +19,16 @@
~ along with this program. If not, see <http://www.gnu.org/licenses/>. ~ along with this program. If not, see <http://www.gnu.org/licenses/>.
--> -->
<resources> <resources>
<integer name="editor_max_file_size">4194304</integer> <string name="close">Zatvoriť</string>
<string name="about_action">O aplikácii</string>
<string name="about_message"><![CDATA[
Turbo Editor je zadarmo a <a href="http://github.com/vmihalachi/turbo-editor">zdrojový kód je voľné dostupný</a>.
Copyright 2013-2014 <a href="https://plus.google.com/+VladMihalachi">Vlad Mihalachi</a>. Všetky práva vyhradené.<br/>
<br/>
Veľká vďaka všetkým
<a href="http://crowdin.net/project/turbo-client">prekladateľom</a> aj tým,
ktorí mi poslali dar.<br/>
<br/>
Svoj názor na aplikáciu môžete vyjadriť v <a href="http://forum.xda-developers.com/android/apps-games/app-turbo-editor-text-editor-t2832016">téme na XDA</a>
]]></string>
</resources> </resources>

View File

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<!--
~ 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/>.
-->
<resources>
<string name="donation_action">Prispieť</string>
<string name="donation_title">Podporiť vývojára</string>
<string name="donation_info"><![CDATA[
Turbo Editor je zadarmo a <a href="http://github.com/vmihalachi/turbo-editor">zdrojový kód je voľné dostupný</a>.
Môžete ukázať svoje uznanie a podporiť rozvoj tým, že pošlete dar:
]]></string>
<string name="donation_item_bought">Už ste pre túto položku poslali dar.</string>
<string name="donation_2">Zmrzlina</string>
<string name="donation_4">Šálka kávy</string>
<string name="donation_10">Účet za elektrinu</string>
<string name="donation_20">Správny vankúš</string>
<string name="donation_50">SSD disk</string>
<string name="donation_99">Domáce kino</string>
<string name="donation_error_iab_setup">Zlyhalo nastavenie služby nákupu v aplikácii!</string>
<string name="donation_no_responsibility">Prosím, berte na vedomie, že Google nie je zodpovedný za túto metódu platby.</string>
</resources>

View File

@ -21,56 +21,56 @@
<!--Generated by crowdin.net--> <!--Generated by crowdin.net-->
<resources> <resources>
<string name="use_monospace">Använd monospace</string> <string name="use_monospace">Använd monospace</string>
<string name="recent_files">Senaste filer</string> <string name="recent_files">Senaste filerna</string>
<string name="font_size">Storlek för typsnitt</string> <string name="font_size">Storlek för typsnitt</string>
<string name="connection_name">Benämning för anslutningen</string> <string name="connection_name">Benämning för anslutningen</string>
<string name="line_numbers">Radnummer</string> <string name="line_numbers">Radnummer</string>
<string name="wrap_content">Wrap content</string> <string name="wrap_content">Linda in innehåll</string>
<string name="view_it_on_the_web">View it on the web</string> <string name="view_it_on_the_web">Kolla på det i webbläsaren</string>
<string name="file">File</string> <string name="file">Fil</string>
<string name="folder">Folder</string> <string name="folder">Mapp</string>
<string name="light_theme">Light Theme</string> <string name="light_theme">Ljust Tema</string>
<string name="goto_line">Go to Line&#8230;</string> <string name="goto_line">Gå Till Linje&#8230;</string>
<string name="goto_page">Go to Page&#8230;</string> <string name="goto_page">Gå Till Sida&#8230;</string>
<string name="find">Find</string> <string name="find">Hitta</string>
<string name="replace">Replace</string> <string name="replace">Byt Ut</string>
<string name="share">Share</string> <string name="share">Dela</string>
<string name="keyboard_suggestions_and_swipe">Keyboard suggestions and Swipe</string> <string name="keyboard_suggestions_and_swipe">Tangentbordsförslag och Swipe</string>
<string name="enable_autoencoding">Auto-Encoding</string> <string name="enable_autoencoding">Auto-Kodning</string>
<string name="set_as_working_folder">Set as the working folder</string> <string name="set_as_working_folder">Sätt som nuvarande mapp</string>
<string name="is_the_working_folder">This is the working folder</string> <string name="is_the_working_folder">Det här är den nuvarande mappen</string>
<string name="save_changes">Do you want to save the changes to the file %s?</string> <string name="save_changes">Vill du spara ändringarna till filen %s?</string>
<string name="regular_expression">Regular Expression</string> <string name="regular_expression">Reguljära uttryck</string>
<string name="text_to_find">Text to find</string> <string name="text_to_find">Text att hitta</string>
<string name="text_to_replace">Text to replace</string> <string name="text_to_replace">Text som ska ersätta</string>
<string name="next">Next</string> <string name="next">Nästa</string>
<string name="previous">Previous</string> <string name="previous">Förra</string>
<string name="please_wait">Please wait&#8230;</string> <string name="please_wait">Var god vänta&#8230;</string>
<string name="occurrences_found">%s occurrences was found</string> <string name="occurrences_found">%s träffar hittade</string>
<string name="app_version_new">v%s</string> <string name="app_version_new">v%s</string>
<string name="translate_the_app">Translate</string> <string name="translate_the_app">Översätt</string>
<string name="changelog">Changelog</string> <string name="changelog">Ändringar</string>
<string name="match_case">Match case</string> <string name="match_case">Matcha stor/liten bokstav</string>
<string name="long_click_for_more_options">Long click for more options</string> <string name="long_click_for_more_options">Långtryck för fler inställningar</string>
<string name="auto_save">Auto save</string> <string name="auto_save">Autospara</string>
<string name="read_only">Read only</string> <string name="read_only">Läs endast läge</string>
<string name="send_error_reports">Send error reports</string> <string name="send_error_reports">Skicka felrapport</string>
<string name="extra_options">Extra options</string> <string name="extra_options">Extra inställningar</string>
<string name="split_text_if_too_long">Split the text if too long</string> <string name="split_text_if_too_long">Dela upp texten om den är för lång</string>
<string name="ignore_back_button">Ignore back button</string> <string name="ignore_back_button">Ignorera Tillbakaknappen</string>
<string name="donate">Donate</string> <string name="donate">Donera</string>
<string name="codifica">Encoding</string> <string name="codifica">Encoding</string>
<string name="condividi">Share</string> <string name="condividi">Dela</string>
<string name="info">Info</string> <string name="info">Info</string>
<string name="nome_app_turbo_editor">Turbo Editor</string> <string name="nome_app_turbo_editor">Turbo Editor</string>
<string name="preferenze">Preferences</string> <string name="preferenze">Inställningar</string>
<string name="salva">Save</string> <string name="salva">Spara</string>
<string name="menu_syntax_highlight">Syntax highlight</string> <string name="menu_syntax_highlight">Syntax Markering</string>
<string name="testo_indietro">Undo</string> <string name="testo_indietro">Ångra</string>
<string name="testo_rifai">Redo</string> <string name="testo_rifai">Återställ</string>
<string name="open">Open</string> <string name="open">Öppna</string>
<string name="file_saved_with_success">The file %1$s was saved with success!</string> <string name="file_saved_with_success">Filen %1$s sparades!</string>
<string name="open_a_file">Open a file</string> <string name="open_a_file">Öppna en fil</string>
<string name="no">No</string> <string name="no">Nej</string>
<string name="new_file">New file</string> <string name="new_file">Ny fil</string>
</resources> </resources>

View File

@ -19,16 +19,16 @@
~ along with this program. If not, see <http://www.gnu.org/licenses/>. ~ along with this program. If not, see <http://www.gnu.org/licenses/>.
--> -->
<resources> <resources>
<string name="close">Close</string> <string name="close">Stäng</string>
<string name="about_action">About</string> <string name="about_action">Om</string>
<string name="about_message"><![CDATA[ <string name="about_message"><![CDATA[
Turbo Editor is a free and <a href="http://github.com/vmihalachi/turbo-editor">open source</a> app. Turbo Editor är en gratis och <a href="http://github.com/vmihalachi/turbo-editor">öppen källkod</a> app.
Copyright 2013-2014 <a href="https://plus.google.com/+VladMihalachi">Vlad Mihalachi</a>. All Rights Reserved.<br/> Copyright 2013-2014 <a href="https://plus.google.com/+VladMihalachi">Vlad Mihalachi</a>. All Rights Reserved.<br/>
<br/> <br/>
Many thanks to all who Många tack till alla som
<a href="http://crowdin.net/project/turbo-client">helped with translations</a> or <a href="http://crowdin.net/project/turbo-client">hjälpt med översättningar </a> eller
donated to me.<br/> donerat.<br/>
<br/> <br/>
If you want to send feedback here is the <a href="http://forum.xda-developers.com/android/apps-games/app-turbo-editor-text-editor-t2832016">XDA thread</a> Om du vill skicka feedback är detta <a href="http://forum.xda-developers.com/android/apps-games/app-turbo-editor-text-editor-t2832016">XDA Tråden</a>
]]></string> ]]></string>
</resources> </resources>

View File

@ -1,37 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<!--
~ 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/>.
-->
<resources>
<string name="donation_action">Donate</string>
<string name="donation_title">Donate to developer</string>
<string name="donation_info"><![CDATA[
Turbo Editor is a free and <a href="http://github.com/vmihalachi/turbo-editor/">open source</a> app.
You can show your appreciation and support development by donating:
]]></string>
<string name="donation_item_bought">You\'ve donated for this item already.</string>
<string name="donation_2">An ice cream</string>
<string name="donation_4">Cup of coffee</string>
<string name="donation_10">Electricity bills</string>
<string name="donation_20">The right pillow</string>
<string name="donation_50">Solid-state drive</string>
<string name="donation_99">Sound system</string>
<string name="donation_error_iab_setup">Failed to setup in-app-billing service!</string>
<string name="donation_no_responsibility">Notice that Google is not responsible for that payments method.</string>
</resources>

View File

@ -21,13 +21,10 @@
<resources> <resources>
<string name="close">Kapat</string> <string name="close">Kapat</string>
<string name="about_action">Hakkında</string> <string name="about_action">Hakkında</string>
<string name="about_message"><![CDATA[ <string name="about_message"><![CDATA[ Turbo Editör ücretsiz ve <a href="http://github.com/vmihalachi/turbo-editor">açık kaynak</a> bir uygulamadır.
Turbo Editör ücretsiz ve <a href="http://github.com/vmihalachi/turbo-editor">açık kaynak</a> bir uygulamadır.
Telif hakkı 2013-2014 <a href="https://plus.google.com/+VladMihalachi">Vlad Mihalachi</a>. Tüm Hakları Saklıdır.<br/> Telif hakkı 2013-2014 <a href="https://plus.google.com/+VladMihalachi">Vlad Mihalachi</a>. Tüm Hakları Saklıdır.<br/>
<br/> <br/>
Tüm çevirileriyle <a href="http://crowdin.net/project/turbo-client">Tüm çevirileriyle</a> veya bağışlarıyla yardımcı olanlara çok teşekkürler</a>.<br/>
<a href="http://crowdin.net/project/turbo-client">veya bağışlarıyla yardımcı</a> olanlara çok teşekkürler</a>.<br/>
<br/> <br/>
Geri bildirim göndermek istiyorsanız XDA konusunu <a href="http://forum.xda-developers.com/android/apps-games/app-turbo-editor-text-editor-t2832016">kullanabilirsiniz</a> Geri bildirim göndermek istiyorsanız <a href="http://forum.xda-developers.com/android/apps-games/app-turbo-editor-text-editor-t2832016">XDA konusunu</a> kullanabilirsiniz]]></string>
<a href="https://plus.google.com/+VladMihalachi">]]></string>
</resources> </resources>

View File

@ -26,8 +26,8 @@
Bağış yaparak gelişimini destekleyebilir ve beğeninizi gösterebilirsiniz: Bağış yaparak gelişimini destekleyebilir ve beğeninizi gösterebilirsiniz:
]]></string> ]]></string>
<string name="donation_item_bought">Zaten bu öğe için bağış yaptınız.</string> <string name="donation_item_bought">Zaten bu öğe için bağış yaptınız.</string>
<string name="donation_2">Bir dondurma</string> <string name="donation_2">Dondurma</string>
<string name="donation_4">Bir fincan kahve</string> <string name="donation_4">Kahve</string>
<string name="donation_10">Elektrik faturaları</string> <string name="donation_10">Elektrik faturaları</string>
<string name="donation_20">Ortopedik yastık</string> <string name="donation_20">Ortopedik yastık</string>
<string name="donation_50">Solid-state sürücü</string> <string name="donation_50">Solid-state sürücü</string>

View File

@ -20,57 +20,57 @@
--> -->
<!--Generated by crowdin.net--> <!--Generated by crowdin.net-->
<resources> <resources>
<string name="use_monospace">Use monospace</string> <string name="use_monospace">Моноширний шрифт</string>
<string name="recent_files">Recent files</string> <string name="recent_files">Нещодавні файли</string>
<string name="font_size">Font size</string> <string name="font_size">Розмір шрифту</string>
<string name="connection_name">Connection Name</string> <string name="connection_name">Назва з\'єднання</string>
<string name="line_numbers">Line Numbers</string> <string name="line_numbers">Нумерація рядків</string>
<string name="wrap_content">Wrap content</string> <string name="wrap_content">Перенесення рядків</string>
<string name="view_it_on_the_web">View it on the web</string> <string name="view_it_on_the_web">Переглянути в броузері</string>
<string name="file">File</string> <string name="file">Файл</string>
<string name="folder">Folder</string> <string name="folder">Папка</string>
<string name="light_theme">Light Theme</string> <string name="light_theme">Світла тема</string>
<string name="goto_line">Go to Line&#8230;</string> <string name="goto_line">Перейти на рядок&#8230;</string>
<string name="goto_page">Go to Page&#8230;</string> <string name="goto_page">Перейти на сторінку&#8230;</string>
<string name="find">Find</string> <string name="find">Пошук</string>
<string name="replace">Replace</string> <string name="replace">Замінити</string>
<string name="share">Share</string> <string name="share">Поділитись</string>
<string name="keyboard_suggestions_and_swipe">Keyboard suggestions and Swipe</string> <string name="keyboard_suggestions_and_swipe">Клавіатурні підказки і свайп</string>
<string name="enable_autoencoding">Auto-Encoding</string> <string name="enable_autoencoding">Автоматичне кодування</string>
<string name="set_as_working_folder">Set as the working folder</string> <string name="set_as_working_folder">Встановити як робочу папку</string>
<string name="is_the_working_folder">This is the working folder</string> <string name="is_the_working_folder">Це робоча папка</string>
<string name="save_changes">Do you want to save the changes to the file %s?</string> <string name="save_changes">Зберегти зміни у файлі %s?</string>
<string name="regular_expression">Regular Expression</string> <string name="regular_expression">Регулярний вираз</string>
<string name="text_to_find">Text to find</string> <string name="text_to_find">Текст для пошуку</string>
<string name="text_to_replace">Text to replace</string> <string name="text_to_replace">Текст для заміни</string>
<string name="next">Next</string> <string name="next">Далі</string>
<string name="previous">Previous</string> <string name="previous">Назад</string>
<string name="please_wait">Please wait&#8230;</string> <string name="please_wait">Будь ласка, зачекайте&#8230;</string>
<string name="occurrences_found">%s occurrences was found</string> <string name="occurrences_found">Знайдено %s</string>
<string name="app_version_new">v%s</string> <string name="app_version_new">v%s</string>
<string name="translate_the_app">Translate</string> <string name="translate_the_app">Перекласти</string>
<string name="changelog">Changelog</string> <string name="changelog">Історія змін</string>
<string name="match_case">Match case</string> <string name="match_case">Враховувати регістр</string>
<string name="long_click_for_more_options">Long click for more options</string> <string name="long_click_for_more_options">Утримуйте для додаткових опцій</string>
<string name="auto_save">Auto save</string> <string name="auto_save">Автоматичне збереження</string>
<string name="read_only">Read only</string> <string name="read_only">Тільки для читання</string>
<string name="send_error_reports">Send error reports</string> <string name="send_error_reports">Відправляти звіти про помилки</string>
<string name="extra_options">Extra options</string> <string name="extra_options">Додаткові опції</string>
<string name="split_text_if_too_long">Split the text if too long</string> <string name="split_text_if_too_long">Розділення тексту, якщо занадто довгий</string>
<string name="ignore_back_button">Ignore back button</string> <string name="ignore_back_button">Ігнорувати кнопку Назад</string>
<string name="donate">Donate</string> <string name="donate">Пожертвувати</string>
<string name="codifica">Encoding</string> <string name="codifica">Кодування</string>
<string name="condividi">Share</string> <string name="condividi">Поділитись</string>
<string name="info">Info</string> <string name="info">Інформація</string>
<string name="nome_app_turbo_editor">Turbo Editor</string> <string name="nome_app_turbo_editor">Turbo Editor</string>
<string name="preferenze">Preferences</string> <string name="preferenze">Налаштування</string>
<string name="salva">Save</string> <string name="salva">Зберегти</string>
<string name="menu_syntax_highlight">Syntax highlight</string> <string name="menu_syntax_highlight">Підсвітка синтаксису</string>
<string name="testo_indietro">Undo</string> <string name="testo_indietro">Скасувати</string>
<string name="testo_rifai">Redo</string> <string name="testo_rifai">Повторити</string>
<string name="open">Open</string> <string name="open">Відкрити</string>
<string name="file_saved_with_success">The file %1$s was saved with success!</string> <string name="file_saved_with_success">Файл %1$s було успішно збережено!</string>
<string name="open_a_file">Open a file</string> <string name="open_a_file">Відкрити файл</string>
<string name="no">No</string> <string name="no">Ні</string>
<string name="new_file">New file</string> <string name="new_file">Новий файл</string>
</resources> </resources>

View File

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<!-- <!--
~ Copyright (C) 2014 Vlad Mihalachi ~ Copyright (C) 2014 Vlad Mihalachi
~ ~
@ -18,17 +17,20 @@
~ You should have received a copy of the GNU General Public License ~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <http://www.gnu.org/licenses/>. ~ along with this program. If not, see <http://www.gnu.org/licenses/>.
--> -->
<!--Generated by crowdin.com-->
<resources> <resources>
<string name="close">Close</string> <string name="close">Закрити</string>
<string name="about_action">About</string> <string name="about_action">Про програму</string>
<string name="about_message"><![CDATA[ <string name="about_message"><![CDATA[
Turbo Editor is a free and <a href="http://github.com/vmihalachi/turbo-editor">open source</a> app. Turbo Editor це безкоштовна програма з <a href="http://github.com/vmihalachi/turbo-editor">відкритим вихідним кодом</a>.
Copyright 2013-2014 <a href="https://plus.google.com/+VladMihalachi">Vlad Mihalachi</a>. All Rights Reserved.<br/> Copyright 2013-2014 <a href="https://plus.google.com/+VladMihalachi">Vlad Mihalachi</a>. All Rights Reserved.<br/>
<br/> <br/>
Many thanks to all who Велике спасибі всім хто
<a href="http://crowdin.net/project/turbo-client">helped with translations</a> or <a href="http://crowdin.net/project/turbo-client">допомагає з перекладами</a> або
donated to me.<br/> підтримує мене<br/>
<br/> <br/>
If you want to send feedback here is the <a href="http://forum.xda-developers.com/android/apps-games/app-turbo-editor-text-editor-t2832016">XDA thread</a> Зворотній зв\'язок <a href="http://forum.xda-developers.com/android/apps-games/app-turbo-editor-text-editor-t2832016">тема на XDA</a>
]]></string> ]]></string>
</resources> </resources>

View File

@ -19,19 +19,19 @@
~ along with this program. If not, see <http://www.gnu.org/licenses/>. ~ along with this program. If not, see <http://www.gnu.org/licenses/>.
--> -->
<resources> <resources>
<string name="donation_action">Donate</string> <string name="donation_action">Пожертвувати</string>
<string name="donation_title">Donate to developer</string> <string name="donation_title">Пожертва розробнику</string>
<string name="donation_info"><![CDATA[ <string name="donation_info"><![CDATA[
Turbo Editor is a free and <a href="http://github.com/vmihalachi/turbo-editor/">open source</a> app. Turbo Editor це безкоштовна програма з <a href="http://github.com/vmihalachi/turbo-editor/ ">відкритим вихідним кодом</a>.
You can show your appreciation and support development by donating: Ви можете показати вашу вдячність і підтримати проект пожертвами:
]]></string> ]]></string>
<string name="donation_item_bought">You\'ve donated for this item already.</string> <string name="donation_item_bought">Ви вже пожертвували.</string>
<string name="donation_2">An ice cream</string> <string name="donation_2">Морозиво</string>
<string name="donation_4">Cup of coffee</string> <string name="donation_4">Чашка кави</string>
<string name="donation_10">Electricity bills</string> <string name="donation_10">Рахунки за електрику</string>
<string name="donation_20">The right pillow</string> <string name="donation_20">Хорошу подушку</string>
<string name="donation_50">Solid-state drive</string> <string name="donation_50">SSD диск</string>
<string name="donation_99">Sound system</string> <string name="donation_99">Аудіо систему</string>
<string name="donation_error_iab_setup">Failed to setup in-app-billing service!</string> <string name="donation_error_iab_setup">Не вдалося виконати in-app-billing сервіс!</string>
<string name="donation_no_responsibility">Notice that Google is not responsible for that payments method.</string> <string name="donation_no_responsibility">Зверніть увагу, що Google не відповідає за цей метод платежу.</string>
</resources> </resources>

View File

@ -28,6 +28,8 @@
<item type="id" name="im_info"/> <item type="id" name="im_info"/>
<item type="id" name="im_button"/> <item type="id" name="im_button"/>
<item type="id" name="im_save"/> <item type="id" name="im_save"/>
<item type="id" name="im_save_normaly"/>
<item type="id" name="im_save_as"/>
<item type="id" name="im_share"/> <item type="id" name="im_share"/>
<item type="id" name="im_editor_encoding"/> <item type="id" name="im_editor_encoding"/>
<item type="id" name="im_line_numbers"/> <item type="id" name="im_line_numbers"/>
@ -46,6 +48,7 @@
<item type="id" name="im_is_working_folder"/> <item type="id" name="im_is_working_folder"/>
<item type="id" name="im_set_as_working_folder"/> <item type="id" name="im_set_as_working_folder"/>
<item type="id" name="im_replace"/> <item type="id" name="im_replace"/>
<item type="id" name="im_replace_all"/>
<item type="id" name="im_next_page"/> <item type="id" name="im_next_page"/>
<item type="id" name="im_prev_page"/> <item type="id" name="im_prev_page"/>
<item type="id" name="im_donate"/> <item type="id" name="im_donate"/>
@ -62,6 +65,7 @@
<item type="id" name="text_editor"/> <item type="id" name="text_editor"/>
<item type="id" name="no_file_opened_messagge"/> <item type="id" name="no_file_opened_messagge"/>
<item type="id" name="delete_current_file"/>
<item type="id" name="regex_check"/> <item type="id" name="regex_check"/>
<item type="id" name="replace_check"/> <item type="id" name="replace_check"/>
<item type="id" name="match_case_check"/> <item type="id" name="match_case_check"/>

View File

@ -64,6 +64,7 @@
<string name="nome_app_turbo_editor">Turbo Editor</string> <string name="nome_app_turbo_editor">Turbo Editor</string>
<string name="preferenze">Preferences</string> <string name="preferenze">Preferences</string>
<string name="salva">Save</string> <string name="salva">Save</string>
<string name="save_as">Save as</string>
<string name="menu_syntax_highlight">Syntax highlight</string> <string name="menu_syntax_highlight">Syntax highlight</string>
<string name="testo_indietro">Undo</string> <string name="testo_indietro">Undo</string>
<string name="testo_rifai">Redo</string> <string name="testo_rifai">Redo</string>
@ -72,4 +73,6 @@
<string name="open_a_file">Open a file</string> <string name="open_a_file">Open a file</string>
<string name="no">No</string> <string name="no">No</string>
<string name="new_file">New file</string> <string name="new_file">New file</string>
<string name="delete_current_file">Delete current file</string>
<string name="replace_all">Replace all</string>
</resources> </resources>