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'
android {
compileSdkVersion 21
buildToolsVersion '21.1.2'
compileSdkVersion 22
buildToolsVersion '22'
defaultConfig {
applicationId "com.maskyn.fileeditorpro"
minSdkVersion 11
targetSdkVersion 21
versionCode 35
versionName "1.13.2"
targetSdkVersion 22
versionCode 39
versionName "1.15.1"
}
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 {
compileSdkVersion 21
buildToolsVersion '21.1.2'
compileSdkVersion 22
buildToolsVersion '22'
defaultConfig {
applicationId "com.maskyn.fileeditor"
minSdkVersion 11
targetSdkVersion 21
versionCode 35
versionName "1.13.2"
targetSdkVersion 22
versionCode 39
versionName "1.15.1"
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
@ -71,7 +71,7 @@ android {
dependencies {
compile fileTree(dir: 'libs', include: '*.jar')
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') {
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" >
<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"
revision="21.0.2"
sha1="1609e6d42d0480b0f4188e2c29f75388fa12a8f0">
<dex dex="C:\Users\Vlad\Documents\AndroidStudioProjects\turbo-editor\app-pro\build\intermediates\pre-dexed\debug\internal_impl-21.0.0-b15535acecaec42d04239e17e0a03ab072a43104.jar" />
revision="22.0.0"
sha1="66cee5a65742fef58c1dcdc0b892042f7bb1530b">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app-pro/build/intermediates/pre-dexed/debug/classes-041d055cf4bc0ac183d528da81f21df261f58a2c.jar" />
</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"
revision="21.0.2"
sha1="d0b9fcf5ff71e9443e787fdeef87e6833f82498d">
<dex dex="C:\Users\Vlad\Documents\AndroidStudioProjects\turbo-editor\app-pro\build\intermediates\pre-dexed\debug\classes-82d5b6cab7f16bad663de7c7008673037efb0e1b.jar" />
revision="22.0.0"
sha1="2c91c949a45a21cdecf26e03951e46c7beec9ad8">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/pre-dexed/release/classes-e010b6ec2ae97c8d5cf66327f984fb7645e2eacb.jar" />
</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"
revision="21.0.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"
revision="21.1.2"
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
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"
revision="21.0.2"
sha1="905075e6c80f206bbe6cf1e809d2caa69f420c76">
<dex dex="C:\Users\Vlad\Documents\AndroidStudioProjects\turbo-editor\app-pro\build\intermediates\pre-dexed\debug\commons-lang3-3.1-84728078c80f2c8637e0c3fe426ad61433c75bb6.jar" />
revision="21.1.2"
sha1="2c91c949a45a21cdecf26e03951e46c7beec9ad8">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/pre-dexed/debug/classes-e010b6ec2ae97c8d5cf66327f984fb7645e2eacb.jar" />
</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"
revision="21.0.2"
sha1="fe94ead11c648222804d49f12bbe257ed8d09c4d">
<dex dex="C:\Users\Vlad\Documents\AndroidStudioProjects\turbo-editor\app-pro\build\intermediates\pre-dexed\debug\classes-bcfe21eb1248db73c27c811996e28274cf39b024.jar" />
revision="22.0.0"
sha1="158555fbeff80e5a85464a818eadda8a448a1051">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/pre-dexed/release/classes-f91276bcf60cec32a04f3aa34394e11eb3ba3ad5.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-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"
revision="21.0.2"
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"
revision="22.0.0"
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
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"
revision="21.0.2"
sha1="f1cd6d34046095cac347407908d0d42858db410a">
<dex dex="C:\Users\Vlad\Documents\AndroidStudioProjects\turbo-editor\app-pro\build\intermediates\pre-dexed\debug\classes-30cc9565ecef1e8ae8577530d7ddd41993d192d7.jar" />
revision="21.1.2"
sha1="0bb0df3bf333801406f32bdfba678bcbd38cb9ff">
<dex dex="/Users/mac/AndroidStudioProjects/turbo-editor/app/build/intermediates/pre-dexed/debug/classes-dda140fb3d64731d445f409c3466c69c68a4c02e.jar" />
</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"
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">
<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
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"
revision="21.0.2"
sha1="1a578b9607b36266c63d43a4fa0ab5664dbe911e">
<dex dex="C:\Users\Vlad\Documents\AndroidStudioProjects\turbo-editor\app-pro\build\intermediates\pre-dexed\debug\support-annotations-21.0.0-7b7e20ddbdfce40d4a29c1e68c2dbbc5bb512ab5.jar" />
revision="22.0.0"
sha1="0a4af6a85230b990eb8690b696d2db9247338611">
<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>
</items>

Binary file not shown.

View File

@ -1,11 +1,11 @@
apply plugin: 'com.android.library'
android {
compileSdkVersion 21
buildToolsVersion '21.1.2'
compileSdkVersion 22
buildToolsVersion '22'
defaultConfig {
minSdkVersion 7
targetSdkVersion 21
targetSdkVersion 22
versionName "1.0"
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
android:minSdkVersion="7"
android:targetSdkVersion="21" />
android:targetSdkVersion="22" />
<application android:allowBackup="true" >
</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
android:minSdkVersion="7"
android:targetSdkVersion="21" />
android:targetSdkVersion="22" />
<application android:allowBackup="true" >
</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 {
compileSdkVersion 21
buildToolsVersion '21.1.2'
compileSdkVersion 22
buildToolsVersion '22'
defaultConfig {
minSdkVersion 7
targetSdkVersion 21
targetSdkVersion 22
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7

View File

@ -26,12 +26,12 @@ android {
disable 'MissingTranslation', 'ExtraTranslation'
}
compileSdkVersion 21
buildToolsVersion '21.1.2'
compileSdkVersion 22
buildToolsVersion '22'
defaultConfig {
minSdkVersion 11
targetSdkVersion 21
targetSdkVersion 22
versionCode 1
versionName "1.0"
}
@ -61,9 +61,6 @@ dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile project(':libraries:RootCommands')
compile project(':libraries:FloatingActionButton')
//compile('de.greenrobot:eventbus:2.2.1') {
// exclude module: 'support-v4'
// }
// compile 'com.googlecode.juniversalchardet:juniversalchardet:1.0.3'
compile 'org.apache.commons:commons-lang3:3.1'
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.MenuItem;
import android.view.View;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.EditText;
@ -74,8 +73,10 @@ import org.sufficientlysecure.rootcommands.Toolbox;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -87,6 +88,7 @@ import sharedcode.turboeditor.dialogfragment.FindTextDialog;
import sharedcode.turboeditor.dialogfragment.NewFileDetailsDialog;
import sharedcode.turboeditor.dialogfragment.NumberPickerDialog;
import sharedcode.turboeditor.dialogfragment.SaveFileDialog;
import sharedcode.turboeditor.preferences.PreferenceChangeType;
import sharedcode.turboeditor.preferences.PreferenceHelper;
import sharedcode.turboeditor.task.SaveFileTask;
import sharedcode.turboeditor.texteditor.EditTextPadding;
@ -99,7 +101,6 @@ import sharedcode.turboeditor.texteditor.SearchResult;
import sharedcode.turboeditor.util.AccessStorageApi;
import sharedcode.turboeditor.util.AnimationUtils;
import sharedcode.turboeditor.util.AppInfoHelper;
import sharedcode.turboeditor.util.EventBusEvents;
import sharedcode.turboeditor.util.IHomeActivity;
import sharedcode.turboeditor.util.MimeTypes;
import sharedcode.turboeditor.util.ProCheckUtils;
@ -108,29 +109,19 @@ import sharedcode.turboeditor.views.CustomDrawerLayout;
import sharedcode.turboeditor.views.DialogHelper;
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
.SearchDialogInterface, GoodScrollView.ScrollInterface, PageSystem.PageSystemInterface,
PageSystemButtons.PageButtonsInterface, NumberPickerDialog.INumberPickerDialog, SaveFileDialog.ISaveDialog,
AdapterView.OnItemClickListener, AdapterDrawer.Callbacks{
//region VARIABLES
private static final int READ_REQUEST_CODE = 42;
private static final int
ID_SELECT_ALL = android.R.id.selectAll;
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_PASTE = android.R.id.paste;
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_LONG = 1500;
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 Editor mEditor;
private static HorizontalScrollView horizontalScroll;
private boolean searchingText;
private static SearchResult searchResult;
private static PageSystem pageSystem;
private static PageSystemButtons pageSystemButtons;
private static String currentEncoding = "UTF-8";
private static String currentEncoding = "UTF-16";
private static Toolbar toolbar;
/*
@ -236,7 +226,7 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
super.onPause();
if (PreferenceHelper.getAutoSave(getBaseContext()) && mEditor.canSaveFile()) {
saveTheFile();
saveTheFile(false);
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
getSupportActionBar().setTitle(getString(R.string.nome_app_turbo_editor));
onEvent(new EventBusEvents.ClosedAFile());
closedTheFile();
mDrawerLayout.openDrawer(Gravity.START);
mDrawerLayout.closeDrawer(Gravity.END);
@ -335,15 +325,15 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
path = AccessStorageApi.getPath(getBaseContext(), data.getData());
}
if (requestCode == KITKAT_OPEN_REQUEST_CODE) {
if (requestCode == READ_REQUEST_CODE) {
path = AccessStorageApi.getPath(getBaseContext(), data.getData());
}
if (!TextUtils.isEmpty(path)) {
File file = new File(path);
if (file.isFile() && file.exists()) {
onEvent(new EventBusEvents.NewFileToOpen(new File
(path)));
newFileToOpen(new File
(path), "");
}
}
@ -355,7 +345,7 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
// Path of the file selected
String filePath = files.get(position).getAbsolutePath();
// Send the event that a file was selected
onEvent(new EventBusEvents.NewFileToOpen(new File(filePath)));
newFileToOpen(new File(filePath), "");
}
//endregion
@ -364,7 +354,7 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
@Override
public boolean onCreateOptionsMenu(Menu menu) {
if (fileOpened && searchingText)
if (fileOpened && searchResult != null)
getMenuInflater().inflate(R.menu.fragment_editor_search, menu);
else if (fileOpened)
getMenuInflater().inflate(R.menu.fragment_editor, menu);
@ -374,14 +364,18 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
if (fileOpened && searchingText) {
if (fileOpened && searchResult != null) {
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 imNext = menu.findItem(R.id.im_next_item);
if (imReplace != null)
imReplace.setVisible(searchResult.canReplaceSomething());
if (imReplaceAll != null)
imReplaceAll.setVisible(searchResult.canReplaceSomething());
if (imPrev != null)
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();
mDrawerLayout.closeDrawer(Gravity.END);
return true;
} else if (i == R.id.im_save) {
saveTheFile();
} else if (i == R.id.im_save_normaly) {
saveTheFile(false);
} else if (i == R.id.im_save_as) {
saveTheFile(true);
} else if (i == R.id.im_undo) {
mEditor.onTextContextMenuItem(ID_UNDO);
@ -445,11 +442,14 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
FindTextDialog.newInstance(mEditor.getText().toString()).show(getFragmentManager()
.beginTransaction(), "dialog");
} else if (i == R.id.im_cancel) {
searchingText = false;
searchResult = null;
invalidateOptionsMenu();
} 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) {
nextResult();
@ -475,16 +475,18 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
} else if (i == R.id.im_info) {
FileInfoDialog.newInstance(sFilePath).show(getFragmentManager().beginTransaction(), "dialog");
}
else if (i == R.id.im_donate) {
DialogHelper.showDonateDialog(this);
}
return super.onOptionsItemSelected(item);
}
//endregion
// region OTHER THINGS
void replaceText() {
void replaceText(boolean all) {
if (all) {
mEditor.setText(mEditor.getText().toString().replaceAll(searchResult.whatToSearch, searchResult.textToReplace));
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));
@ -497,6 +499,7 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
else if (searchResult.hasPrevious())
previousResult();
}
}
void nextResult() {
if (searchResult.index == mEditor.getLineCount() - 1) // last result of page
@ -561,14 +564,18 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
invalidateOptionsMenu();
}
private void saveTheFile() {
private void saveTheFile(boolean saveAs) {
File file = new File(sFilePath);
if (!file.getName().isEmpty())
if (!file.getName().isEmpty() && !saveAs)
new SaveFileTask(this, sFilePath, pageSystem.getAllText(mEditor.getText()
.toString()), currentEncoding).execute();
else {
NewFileDetailsDialog.newInstance
(pageSystem.getAllText(mEditor.getText().toString()), currentEncoding).show(getFragmentManager().beginTransaction(), "dialog");
NewFileDetailsDialog.newInstance(
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);
}
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);
pageSystem = new PageSystem(this, this, "", null);
@ -655,7 +656,6 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
mEditor.resetVariables();
searchResult = null;
searchingText = false;
invalidateOptionsMenu();
@ -692,11 +692,11 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
|| Intent.ACTION_PICK.equals(action)
&& type != null) {
// Post event
onEvent(new EventBusEvents.NewFileToOpen(new File(intent
.getData().getPath())));
newFileToOpen(new File(intent
.getData().getPath()), "");
} else if (Intent.ACTION_SEND.equals(action) && type != null) {
if ("text/plain".equals(type)) {
onEvent(new EventBusEvents.NewFileToOpen(intent.getStringExtra(Intent.EXTRA_TEXT)));
newFileToOpen(null, intent.getStringExtra(Intent.EXTRA_TEXT));
}
}
}
@ -784,11 +784,11 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
//endregion
//region EVENTBUS
void onEvent(final EventBusEvents.NewFileToOpen event) {
public void newFileToOpen(final File newFile, final String newFileText) {
if (fileOpened && mEditor.canSaveFile()) {
SaveFileDialog.newInstance(sFilePath, pageSystem.getAllText(mEditor
.getText().toString()), currentEncoding, true, event.getFile().getAbsolutePath()).show(getFragmentManager(),
.getText().toString()), currentEncoding, true, newFile.getAbsolutePath()).show(getFragmentManager(),
"dialog");
return;
}
@ -814,10 +814,13 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
@Override
protected Void doInBackground(Void... params) {
file = event.getFile();
file = newFile;
if (file == null) {
file = new File("");
}
try {
if (!file.exists() || !file.isFile()) {
fileText = event.getFileText();
fileText = newFileText;
sFilePath = file.getAbsolutePath();
fileExtension = "txt";
return null;
@ -839,7 +842,7 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
File tempFile = new File(getFilesDir(), "temp.root.file");
if (!tempFile.exists())
tempFile.createNewFile();
tb.copyFile(event.getFile().getAbsolutePath(),
tb.copyFile(file.getAbsolutePath(),
tempFile.getAbsolutePath(), false, false);
file = new File(tempFile.getAbsolutePath());
}
@ -879,13 +882,13 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
if (!message.isEmpty()) {
Toast.makeText(MainActivity.this, message, Toast.LENGTH_LONG).show();
onEvent(new EventBusEvents.CannotOpenAFile());
cannotOpenFile();
} else {
pageSystem = new PageSystem(MainActivity.this, MainActivity.this, fileText, new File(sFilePath));
currentEncoding = encoding;
onEvent(new EventBusEvents.AFileIsSelected(sFilePath));
aFileWasSelected(sFilePath);
showTextEditor();
@ -904,11 +907,13 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
}.execute();
}
public void onEvent(EventBusEvents.SavedAFile event) {
public void savedAFile(String filePath) {
sFilePath = event.getPath();
sFilePath = filePath;
fileExtension = FilenameUtils.getExtension(sFilePath).toLowerCase();
toolbar.setTitle(FilenameUtils.getName(sFilePath));
mEditor.clearHistory();
mEditor.fileSaved();
invalidateOptionsMenu();
@ -919,10 +924,8 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
e.printStackTrace();
}
refreshList(event.getPath(), true, false);
arrayAdapter.selectView(event.getPath());
showInterstitial();
refreshList(filePath, true, false);
arrayAdapter.selectView(filePath);
}
/**
@ -931,7 +934,7 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
*
* @param event The event called
*/
void onEvent(EventBusEvents.CannotOpenAFile event) {
public void cannotOpenFile() {
//
mDrawerLayout.openDrawer(Gravity.LEFT);
//
@ -942,13 +945,17 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
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);
}
if (event.hasType(WRAP_CONTENT)) {
if (types.contains(PreferenceChangeType.WRAP_CONTENT)) {
if (PreferenceHelper.getWrapContent(this)) {
horizontalScroll.removeView(mEditor);
verticalScroll.removeView(horizontalScroll);
@ -958,41 +965,42 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
verticalScroll.addView(horizontalScroll);
horizontalScroll.addView(mEditor);
}
} else if (event.hasType(LINE_NUMERS)) {
} else if (types.contains(PreferenceChangeType.LINE_NUMERS)) {
mEditor.disableTextChangedListener();
mEditor.replaceTextKeepCursor(null, true);
mEditor.enableTextChangedListener();
if (PreferenceHelper.getLineNumbers(this)) {
mEditor.setPadding(EditTextPadding.getPaddingWithLineNumbers(this,
PreferenceHelper.getFontSize(this)),
EditTextPadding.getPaddingTop(this), 0, 0);
mEditor.setPadding(
EditTextPadding.getPaddingWithLineNumbers(this, PreferenceHelper.getFontSize(this)),
EditTextPadding.getPaddingTop(this),
EditTextPadding.getPaddingTop(this),
0);
} else {
mEditor.setPadding(EditTextPadding.getPaddingWithoutLineNumbers(this)
, EditTextPadding.getPaddingTop(this), 0, 0);
mEditor.setPadding(
EditTextPadding.getPaddingWithoutLineNumbers(this),
EditTextPadding.getPaddingTop(this),
EditTextPadding.getPaddingTop(this),
0);
}
} else if (event.hasType(SYNTAX)) {
} else if (types.contains(PreferenceChangeType.SYNTAX)) {
mEditor.disableTextChangedListener();
mEditor.replaceTextKeepCursor(null, true);
mEditor.enableTextChangedListener();
} else if (event.hasType(MONOSPACE)) {
} else if (types.contains(PreferenceChangeType.MONOSPACE)) {
if (PreferenceHelper.getUseMonospace(this))
mEditor.setTypeface(Typeface.MONOSPACE);
else
mEditor.setTypeface(Typeface.DEFAULT);
} else if (event.hasType(THEME_CHANGE)) {
} else if (types.contains(PreferenceChangeType.THEME_CHANGE)) {
if (PreferenceHelper.getLightTheme(this)) {
mEditor.setTextColor(getResources().getColor(R.color.textColorInverted));
} else {
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)) {
getWindow().setSoftInputMode(WindowManager.LayoutParams
.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
mEditor.setReadOnly(true);
} else {
getWindow().setSoftInputMode(WindowManager.LayoutParams
.SOFT_INPUT_STATE_UNSPECIFIED);
mEditor.setReadOnly(false);
if (PreferenceHelper.getSuggestionActive(this)) {
mEditor.setInputType(InputType.TYPE_CLASS_TEXT | InputType
@ -1009,17 +1017,22 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
mEditor.setTypeface(Typeface.MONOSPACE);
else
mEditor.setTypeface(Typeface.DEFAULT);
} else if (event.hasType(FONT_SIZE)) {
} else if (types.contains(PreferenceChangeType.FONT_SIZE)) {
if (PreferenceHelper.getLineNumbers(this)) {
mEditor.setPadding(EditTextPadding.getPaddingWithLineNumbers(this,
PreferenceHelper.getFontSize(this)),
EditTextPadding.getPaddingTop(this), 0, 0);
mEditor.setPadding(
EditTextPadding.getPaddingWithLineNumbers(this, PreferenceHelper.getFontSize(this)),
EditTextPadding.getPaddingTop(this),
EditTextPadding.getPaddingTop(this),
0);
} else {
mEditor.setPadding(EditTextPadding.getPaddingWithoutLineNumbers(this)
, EditTextPadding.getPaddingTop(this), 0, 0);
mEditor.setPadding(
EditTextPadding.getPaddingWithoutLineNumbers(this),
EditTextPadding.getPaddingTop(this),
EditTextPadding.getPaddingTop(this),
0);
}
mEditor.setTextSize(PreferenceHelper.getFontSize(this));
} else if (event.hasType(ENCODING)) {
} else if (types.contains(PreferenceChangeType.ENCODING)) {
String oldEncoding, newEncoding;
oldEncoding = currentEncoding;
newEncoding = PreferenceHelper.getEncoding(this);
@ -1033,7 +1046,7 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
try {
final byte[] oldText = mEditor.getText().toString().getBytes(oldEncoding);
mEditor.disableTextChangedListener();
mEditor.replaceTextKeepCursor(new String(oldText, "UTF-8"), true);
mEditor.replaceTextKeepCursor(new String(oldText, "UTF-16"), true);
mEditor.enableTextChangedListener();
} catch (UnsupportedEncodingException ignored2) {
}
@ -1041,24 +1054,43 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
}
}
void onEvent(EventBusEvents.AFileIsSelected event) {
arrayAdapter.selectView(event.getPath());
public void aFileWasSelected(String filePath) {
arrayAdapter.selectView(filePath);
}
void onEvent(EventBusEvents.ClosedAFile event) {
public void closedTheFile() {
arrayAdapter.selectView("");
}
//endregion
//region Calls from the layout
public void OpenFile(View view) {
// if (Device.hasKitKatApi()) {
// // 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) {
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) {
@ -1137,7 +1169,6 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
@Override
public void onSearchDone(SearchResult searchResult) {
MainActivity.searchResult = searchResult;
searchingText = true;
invalidateOptionsMenu();
final int line = LineUtils.getLineFromIndex(searchResult.foundIndex.getFirst
@ -1165,7 +1196,7 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
@Override
public void onPageChanged(int page) {
pageSystemButtons.updateVisibility(false);
searchingText = false;
searchResult = null;
mEditor.clearHistory();
invalidateOptionsMenu();
}
@ -1175,7 +1206,7 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
pageSystemButtons.updateVisibility(Math.abs(t) > 10);
if (!PreferenceHelper.getSyntaxHighlight(this) || (mEditor.hasSelection() &&
!searchingText) || updateHandler == null || colorRunnable_duringScroll == null)
searchResult == null) || updateHandler == null || colorRunnable_duringScroll == null)
return;
updateHandler.removeCallbacks(colorRunnable_duringEditing);
@ -1219,16 +1250,16 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
public void userDoesntWantToSave(boolean openNewFile, String pathOfNewFile) {
Editor.canSaveFile = false;
if(openNewFile)
onEvent(new EventBusEvents.NewFileToOpen(new File(pathOfNewFile)));
newFileToOpen(new File(pathOfNewFile), "");
else
onEvent(new EventBusEvents.CannotOpenAFile());
cannotOpenFile();
}
@Override
public void CancelItem(int position, boolean andCloseOpenedFile) {
refreshList(files.get(position).getAbsolutePath(), false, true);
if (andCloseOpenedFile)
onEvent(new EventBusEvents.CannotOpenAFile());
cannotOpenFile();
}
//endregion
@ -1271,11 +1302,11 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
private static int firstVisibleIndex, firstColoredIndex;
private static int deviceHeight;
private static int editorHeight;
private static boolean[] hasNewLineArray;
private static boolean[] isGoodLineArray;
private static int[] realLines;
private static boolean wrapContent;
private static int lastLine;
private static int firstLine;
//private static int lastLine;
//private static int firstLine;
private static CharSequence textToHighlight;
private static int lastVisibleIndex;
private static int i;
@ -1306,12 +1337,17 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
setTextColor(getResources().getColor(R.color.textColor));
}
if (PreferenceHelper.getLineNumbers(getContext())) {
setPadding(EditTextPadding.getPaddingWithLineNumbers(getContext(),
PreferenceHelper.getFontSize(getContext())),
EditTextPadding.getPaddingTop(getContext()), 0, 0);
setPadding(
EditTextPadding.getPaddingWithLineNumbers(getContext(), PreferenceHelper.getFontSize(getContext())),
EditTextPadding.getPaddingTop(getContext()),
EditTextPadding.getPaddingTop(getContext()),
0);
} else {
setPadding(EditTextPadding.getPaddingWithoutLineNumbers(getContext()),
EditTextPadding.getPaddingTop(getContext()), 0, 0);
setPadding(
EditTextPadding.getPaddingWithoutLineNumbers(getContext()),
EditTextPadding.getPaddingTop(getContext()),
EditTextPadding.getPaddingTop(getContext()),
0);
}
if (PreferenceHelper.getReadOnly(getContext())) {
@ -1397,24 +1433,20 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
lineUtils.updateHasNewLineArray(pageSystem
.getStartingLine(), lineCount, getLayout(), getText().toString());
hasNewLineArray = lineUtils.getToCountLinesArray();
isGoodLineArray = lineUtils.getGoodLines();
realLines = lineUtils.getRealLines();
}
editorHeight = getHeight();
firstLine = lineUtils.getFirstVisibleLine(verticalScroll, editorHeight, lineCount);
lastLine = lineUtils.getLastVisibleLine(verticalScroll, editorHeight, lineCount, deviceHeight);
//editorHeight = getHeight();
if (PreferenceHelper.getLineNumbers(getContext())) {
wrapContent = PreferenceHelper.getWrapContent(getContext());
i = firstLine;
while (i < lastLine) {
for (i = 0; i < lineCount; i++) {
// if last line we count it anyway
if (!wrapContent
|| hasNewLineArray[i]
|| i == lastLine - 1) {
|| isGoodLineArray[i]) {
realLine = realLines[i];
canvas.drawText(String.valueOf(realLine),
@ -1422,7 +1454,6 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
paddingTop + lineHeight * (i + 1),
mPaintNumbers);
}
i++;
}
}
@ -1456,7 +1487,7 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
return onTextContextMenuItem(ID_REDO);
}
case KeyEvent.KEYCODE_S:
((MainActivity) getContext()).saveTheFile();
((MainActivity) getContext()).saveTheFile(false);
return true;
default:
return super.onKeyDown(keyCode, event);
@ -1638,20 +1669,23 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
cursorPos = getSelectionStart();
cursorPosEnd = getSelectionEnd();
}
disableTextChangedListener();
if (PreferenceHelper.getSyntaxHighlight(getContext()))
if (PreferenceHelper.getSyntaxHighlight(getContext())) {
setText(highlight(textToUpdate == null ? getEditableText() : Editable.Factory
.getInstance().newEditable(textToUpdate), textToUpdate != null));
else
setText(textToUpdate == null ? getText().toString() : textToUpdate);
}
else {
setText(textToUpdate == null ? getEditableText() : textToUpdate);
}
enableTextChangedListener();
if (mantainCursorPos)
firstVisibleIndex = cursorPos;
if (firstVisibleIndex > -1) {
if (firstVisibleIndex > -1 && firstVisibleIndex < length()) {
if (cursorPosEnd != cursorPos)
setSelection(cursorPos, cursorPosEnd);
else
@ -1667,7 +1701,7 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
removeTextChangedListener(mChangeListener);
}
public CharSequence highlight(Editable editable, boolean newText) {
public Editable highlight(Editable editable, boolean newText) {
editable.clearSpans();
if (editable.length() == 0) {
@ -1677,10 +1711,8 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
editorHeight = getHeight();
if (!newText && editorHeight > 0) {
firstLine = lineUtils.getFirstVisibleLine(verticalScroll, editorHeight, lineCount);
lastLine = lineUtils.getLastVisibleLine(verticalScroll, editorHeight, lineCount, deviceHeight);
firstVisibleIndex = getLayout().getLineStart(firstLine);
lastVisibleIndex = getLayout().getLineStart(lastLine);
firstVisibleIndex = getLayout().getLineStart(lineUtils.getFirstVisibleLine(verticalScroll, editorHeight, lineCount));
lastVisibleIndex = getLayout().getLineStart(lineUtils.getLastVisibleLine(verticalScroll, editorHeight, lineCount, deviceHeight));
} else {
firstVisibleIndex = 0;
lastVisibleIndex = CHARS_TO_COLOR;
@ -1701,8 +1733,7 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
if (fileExtension.contains("htm")
|| fileExtension.contains("xml")) {
color(Patterns.HTML_OPEN_TAGS, editable, textToHighlight, firstColoredIndex);
color(Patterns.HTML_CLOSE_TAGS, editable, textToHighlight, firstColoredIndex);
color(Patterns.HTML_TAGS, editable, textToHighlight, firstColoredIndex);
color(Patterns.HTML_ATTRS, editable, textToHighlight, firstColoredIndex);
color(Patterns.GENERAL_STRINGS, editable, textToHighlight, firstColoredIndex);
color(Patterns.XML_COMMENTS, editable, textToHighlight, firstColoredIndex);
@ -1768,8 +1799,7 @@ public abstract class MainActivity extends ActionBarActivity implements IHomeAct
CharSequence textToHighlight,
int start) {
int color = 0;
if (pattern.equals(Patterns.HTML_OPEN_TAGS)
|| pattern.equals(Patterns.HTML_CLOSE_TAGS)
if (pattern.equals(Patterns.HTML_TAGS)
|| pattern.equals(Patterns.GENERAL_KEYWORDS)
|| pattern.equals(Patterns.SQL_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_32LE,
Constants.CHARSET_UTF_8,
"UTF-16",
Constants.CHARSET_WINDOWS_1251,
Constants.CHARSET_WINDOWS_1252,
Constants.CHARSET_WINDOWS_1253,

View File

@ -193,7 +193,7 @@ public class FindTextDialog extends DialogFragment {
return;
// else we return positions and other things
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);
}
} else {

View File

@ -24,16 +24,21 @@ import android.app.Dialog;
import android.app.DialogFragment;
import android.content.DialogInterface;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.view.WindowManager;
import android.widget.CheckBox;
import android.widget.EditText;
import org.apache.commons.io.FileUtils;
import java.io.File;
import sharedcode.turboeditor.R;
import sharedcode.turboeditor.activity.MainActivity;
import sharedcode.turboeditor.preferences.PreferenceHelper;
import sharedcode.turboeditor.task.SaveFileTask;
import sharedcode.turboeditor.util.ViewUtils;
import sharedcode.turboeditor.views.DialogHelper;
// ...
@ -41,10 +46,13 @@ public class NewFileDetailsDialog extends DialogFragment {
private EditText mName;
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 Bundle args = new Bundle();
args.putString("path", currentPath);
args.putString("name", currentName);
args.putString("fileText", fileText);
args.putString("fileEncoding", fileEncoding);
f.setArguments(args);
@ -55,15 +63,29 @@ public class NewFileDetailsDialog extends DialogFragment {
public Dialog onCreateDialog(Bundle savedInstanceState) {
View view = new DialogHelper.Builder(getActivity())
.setTitle(R.string.file)
.setTitle(R.string.save_as)
.setView(R.layout.dialog_fragment_new_file_details)
.createSkeletonView();
this.mName = (EditText) view.findViewById(android.R.id.text1);
this.mFolder = (EditText) view.findViewById(android.R.id.text2);
boolean noName = TextUtils.isEmpty(getArguments().getString("name"));
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
this.mName.requestFocus();
@ -76,6 +98,11 @@ public class NewFileDetailsDialog extends DialogFragment {
new DialogInterface.OnClickListener() {
@Override
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()) {
File file = new File(mFolder.getText().toString(), mName.getText().toString());
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();
else {
NewFileDetailsDialog dialogFrag =
NewFileDetailsDialog.newInstance(text,
NewFileDetailsDialog.newInstance("","",text,
encoding);
dialogFrag.show(getFragmentManager().beginTransaction(),
"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/>.
*/
package sharedcode.turboeditor.iab.utils;
package sharedcode.turboeditor.preferences;
/**
* Exception thrown when encountering an invalid Base64 input character.
*
* @author nelson
*/
public class Base64DecoderException extends Exception {
private static final long serialVersionUID = 1L;
public Base64DecoderException() {
super();
public enum PreferenceChangeType {
FONT_SIZE, ENCODING, SYNTAX, WRAP_CONTENT, MONOSPACE, LINE_NUMERS, THEME_CHANGE, TEXT_SUGGESTIONS, READ_ONLY,
}
public Base64DecoderException(String s) {
super(s);
}
}

View File

@ -74,7 +74,7 @@ public final class PreferenceHelper {
}
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) {

View File

@ -32,20 +32,7 @@ import sharedcode.turboeditor.R;
import sharedcode.turboeditor.activity.MainActivity;
import sharedcode.turboeditor.dialogfragment.EncodingDialog;
import sharedcode.turboeditor.dialogfragment.NumberPickerDialog;
import sharedcode.turboeditor.util.ProCheckUtils;
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 {
@ -118,16 +105,12 @@ public class SettingsFragment extends Fragment implements NumberPickerDialog.INu
fontSizeView = (TextView) rootView.findViewById(R.id.drawer_button_font_size);
encodingView = (TextView) rootView.findViewById(R.id.drawer_button_encoding);
extraOptionsView = (TextView) rootView.findViewById(R.id.drawer_button_extra_options);
donateView = (TextView) rootView.findViewById(R.id.drawer_button_go_pro);
if(ProCheckUtils.isPro(getActivity(), false))
ViewUtils.setVisible(donateView, false);
swLineNumbers.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean 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) {
sColorSyntax = 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
public void onCheckedChanged(CompoundButton buttonView, boolean 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) {
sUseMonospace = 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
public void onCheckedChanged(CompoundButton buttonView, boolean 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() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean 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
public void onCheckedChanged(CompoundButton buttonView, boolean 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
public void onNumberPickerDialogDismissed(NumberPickerDialog.Actions action, int value) {
PreferenceHelper.setFontSize(getActivity(), value);
((MainActivity) getActivity()).onEvent(new APreferenceValueWasChanged(FONT_SIZE));
((MainActivity) getActivity()).aPreferenceValueWasChanged(PreferenceChangeType.FONT_SIZE);
}
@Override
public void onEncodingSelected(String 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.activity.MainActivity;
import sharedcode.turboeditor.root.RootUtils;
import sharedcode.turboeditor.util.EventBusEvents;
public class SaveFileTask extends AsyncTask<Void, Void, Void> {
@ -101,6 +100,6 @@ public class SaveFileTask extends AsyncTask<Void, Void, Void> {
super.onPostExecute(aVoid);
Toast.makeText(activity, message, Toast.LENGTH_LONG).show();
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 int[] realLines;
public boolean[] getToCountLinesArray() {
public boolean[] getGoodLines() {
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
for (i = 0; i < toCountLinesArray.length; i++) {

View File

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

View File

@ -28,11 +28,14 @@ public class SearchResult {
public boolean isReplace;
public String textToReplace;
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.textLength = textLength;
this.isReplace = isReplace;
this.whatToSearch = whatToSearch;
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 sharedcode.turboeditor.preferences.PreferenceHelper;
public class ProCheckUtils {
public static boolean isPro(Context context, boolean includeDonations) {
String packageName = context.getPackageName();
// happy new year
return true;
/*
if (Build.FOR_AMAZON)
return true;
else if (packageName.equals("com.maskyn.fileeditorpro"))
else if (context.getPackageName().equals("com.maskyn.fileeditorpro"))
return true;
else if (includeDonations && PreferenceHelper.hasDonated(context))
return true;
else
return false;
return false;*/
}
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.dialogfragment.AboutDialog;
import sharedcode.turboeditor.iab.DonationFragment;
/**
* 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_HELP = "dialog_help";
public static final String TAG_FRAGMENT_DONATION = "dialog_donate";
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) {
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
~ 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
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
@ -43,6 +38,14 @@
android:textColor="@android:color/secondary_text_dark"
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
android:layout_width="match_parent"
android:layout_height="match_parent"
@ -102,7 +105,7 @@
android:visibility="invisible"/>
</FrameLayout>
</LinearLayout>
<RelativeLayout
@ -141,7 +144,7 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="192dp"
android:layout_height="216dp"
android:id="@id/drawer_buttons"
android:layout_alignParentBottom="true"
android:orientation="vertical">
@ -153,7 +156,7 @@
<TextView
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_height="54dp"
android:text="@string/new_file"
android:gravity="center_vertical"
android:paddingStart="20dp"
@ -168,7 +171,7 @@
<TextView
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_height="54dp"
android:text="@string/open_a_file"
android:gravity="center_vertical"
android:paddingStart="20dp"
@ -183,7 +186,7 @@
<TextView
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_height="54dp"
android:text="@string/preferenze"
android:gravity="center_vertical"
android:paddingStart="20dp"
@ -349,5 +352,3 @@
</sharedcode.turboeditor.views.CustomDrawerLayout>
</LinearLayout>

View File

@ -58,4 +58,14 @@
android:hint="@string/folder"
android:padding="5dp"
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>

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"
>
<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:gravity="center_vertical"
android:layout_width="match_parent"

View File

@ -24,7 +24,19 @@
android:id="@id/im_save"
app:showAsAction="ifRoom"
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"/>
<item
android:id="@id/im_save_as"
app:showAsAction="ifRoom"
android:title="@string/save_as"/>
</menu>
</item>
<item
android:id="@id/im_undo"
app:showAsAction="ifRoom"
@ -63,9 +75,4 @@
app:showAsAction="never"
android:title="@string/info"
/>
<item
android:id="@id/im_donate"
app:showAsAction="never"
android:title="@string/donation_action"
/>
</menu>

View File

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

View File

@ -20,6 +20,21 @@
<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">
<changelogtext>Manly bug fixes</changelogtext>
</changelogversion>

View File

@ -25,12 +25,12 @@
<string name="font_size">Schriftgröße</string>
<string name="connection_name">Verbindungsname</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="file">Datei</string>
<string name="folder">Ordner</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="find">Suchen</string>
<string name="replace">Ersetzen</string>

View File

@ -22,13 +22,13 @@
<string name="close">Schließen</string>
<string name="about_action">Über</string>
<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/>
<br/>
Many thanks to all who
<a href="http://crowdin.net/project/turbo-client">helped with translations</a> or
donated to me.<br/>
Vielen dank an alle Personen,
<a href="http://crowdin.net/project/turbo-client">die bei der Übersetzung geholfen</a> oder
gespendet haben.<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>
</resources>

View File

@ -20,18 +20,18 @@
-->
<resources>
<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[
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:
Turbo Editor ist eine freie und <a href="http://github.com/vmihalachi/turbo-editor/">quelloffene</a> Anwendung.
Du kannst deine Anerkennung zeigen, in dem du die Entwicklung mit Spenden unterstützt:
]]></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>
<string name="donation_item_bought">Du hast bereits gespendet.</string>
<string name="donation_2">Eine Kugel Eis</string>
<string name="donation_4">Tasse Kaffee</string>
<string name="donation_10">Stromrechnung</string>
<string name="donation_20">Das richtige Kissen</string>
<string name="donation_50">SSD Festplatte</string>
<string name="donation_99">Sound-System</string>
<string name="donation_error_iab_setup">Fehler beim Einrichten des In-App-Bezahlservices!</string>
<string name="donation_no_responsibility">Beachten Sie, dass Google für diese Zahlungsmethode nicht verantwortlich ist.</string>
</resources>

View File

@ -28,7 +28,7 @@
<string name="wrap_content">Ajuste de línea</string>
<string name="view_it_on_the_web">Ver en la web</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="goto_line">Ir a línea</string>
<string name="goto_page">Ir a página&#8230;</string>

View File

@ -20,7 +20,7 @@
-->
<resources>
<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[
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:

View File

@ -30,7 +30,7 @@
<string name="file">Tiedosto</string>
<string name="folder">Kansio</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="find">Löydä</string>
<string name="replace">Korvaa</string>
@ -51,7 +51,7 @@
<string name="translate_the_app">Auta kääntämisessä</string>
<string name="changelog">Muutosloki</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="read_only">Vain luku</string>
<string name="send_error_reports">Lähetä virheraportit</string>

View File

@ -27,7 +27,7 @@
<br/>
Suuret kiitokset kaikille, jotka
<a href="http://crowdin.net/project/turbo-client">auttoivat käännöksien parissa</a> tai
lahjoittivat minulle</a>.<br/>
lahjoittivat minulle.<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>
]]></string>

View File

@ -28,7 +28,7 @@
<string name="donation_item_bought">Olet lahjoittanut tälle kohteelle jo.</string>
<string name="donation_2">Jäätelöä</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_50">SSD-levy</string>
<string name="donation_99">Äänijärjestelmä</string>

View File

@ -20,13 +20,13 @@
-->
<!--Generated by crowdin.net-->
<resources>
<string name="use_monospace">Use monospace</string>
<string name="recent_files">Recent files</string>
<string name="use_monospace">Monospace को उपयोग करें</string>
<string name="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="line_numbers">पंक्ति क्रमांक</string>
<string name="wrap_content">सामग्री लपेटें</string>
<string name="view_it_on_the_web">यह वेब पर देखें</string>
<string name="file">File</string>
<string name="folder">Folder</string>
<string name="light_theme">Light Theme</string>

View File

@ -31,7 +31,7 @@
<string name="folder">Mappa</string>
<string name="light_theme">Világos téma</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="replace">Csere</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="auto_save">Automatikus mentés</string>
<string name="read_only">Csak olvasható</string>
<string name="send_error_reports">Send error reports</string>
<string name="extra_options">Extra options</string>
<string name="split_text_if_too_long">Split the text if too long</string>
<string name="ignore_back_button">Ignore back button</string>
<string name="donate">Donate</string>
<string name="send_error_reports">Hibajelentés küldése</string>
<string name="extra_options">Extra beállítások</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">Vissza-gomb figyelmen kívül hagyása</string>
<string name="donate">Támogatás</string>
<string name="codifica">Kódolás</string>
<string name="condividi">Megosztás</string>
<string name="info">Információ</string>
@ -71,6 +71,6 @@
<string name="open">Megnyit</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="no">No</string>
<string name="new_file">New file</string>
<string name="no">Nem</string>
<string name="new_file">Új fájl</string>
</resources>

View File

@ -19,16 +19,16 @@
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<resources>
<string name="close">Close</string>
<string name="about_action">About</string>
<string name="close">Bezárás</string>
<string name="about_action">Névjegy</string>
<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/>
<br/>
Many thanks to all who
<a href="http://crowdin.net/project/turbo-client">helped with translations</a> or
donated to me.<br/>
Köszönet mindazoknak akik
<a href="http://crowdin.net/project/turbo-client">segítettek a fordításban</a> vagy
támogatást adtak.<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>
</resources>

View File

@ -19,19 +19,19 @@
~ 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_action">Támogatás</string>
<string name="donation_title">Támogatás a fejlesztőnek</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:
A Turbo Editor egy szabad és <a href="http://github.com/vmihalachi/turbo-editor/">nyílt forrású</a> alkalmazás.
Mutassa meg mennyire értékeli és támogathassa a fejlesztést:
]]></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>
<string name="donation_item_bought">Ön már támogatta ezt.</string>
<string name="donation_2">Egy jégkrém</string>
<string name="donation_4">Egy csésze kávé</string>
<string name="donation_10">Villany számla</string>
<string name="donation_20">A jobb oldali párna</string>
<string name="donation_50">Szilárdtest-meghajtó</string>
<string name="donation_99">Hang-rendszer</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">Ne felejtse el, hogy a Google nem felel a fizetési módszerekért.</string>
</resources>

View File

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

View File

@ -19,16 +19,15 @@
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<resources>
<string name="close">Close</string>
<string name="about_action">About</string>
<string name="close">Tutup</string>
<string name="about_action">Tentang</string>
<string name="about_message"><![CDATA[
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/>
<br/>
Many thanks to all who
<a href="http://crowdin.net/project/turbo-client">helped with translations</a> or
donated to me.<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>
]]></string>
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/>
<br/>
Banyak terima kasih saya ucapkan kepada
<a href="http://crowdin.net/project/turbo-client">yang telah membantu menerjemahkan aplikasi ini</a> or
donasi kepada saya.<br/>
<br/>
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>
</resources>

View File

@ -19,19 +19,18 @@
~ 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_action">Donasi</string>
<string name="donation_title">Donasi untuk pengembang</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>
Turbo Editor adalah sebuah aplikasi gratis dani <a href="http://github.com/vmihalachi/turbo-editor/">open source</a> app.
Anda dapat melihat apresiasi Anda dan dukungan pada pengembang dengan memberikan donasi: ]]></string>
<string name="donation_item_bought">Anda telah mendonasikan untuk item ini.</string>
<string name="donation_2">Sebuah es krim</string>
<string name="donation_4">Secangkir kopi</string>
<string name="donation_10">Tagihan listrik</string>
<string name="donation_20">Bantal yang tepat</string>
<string name="donation_50">Solid-state drive (SSD)</string>
<string name="donation_99">Sistem suara</string>
<string name="donation_error_iab_setup">Gagal dalam menyeting layanan pembelian dalam aplikasi!</string>
<string name="donation_no_responsibility">Perhatikan bahwa Google tidak bertanggung jawab untuk metode pembayaran.</string>
</resources>

View File

@ -31,7 +31,7 @@
<string name="folder">Folder</string>
<string name="light_theme">Jasny motyw</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="replace">Zastąp</string>
<string name="share">Udostępnij</string>
@ -47,18 +47,18 @@
<string name="previous">Poprzedni</string>
<string name="please_wait">Proszę czekać&#8230;</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="changelog">Lista zmian</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="auto_save">Automatyczny zapis</string>
<string name="read_only">Tylko do odczytu</string>
<string name="send_error_reports">Send error reports</string>
<string name="extra_options">Extra options</string>
<string name="split_text_if_too_long">Split the text if too long</string>
<string name="ignore_back_button">Ignore back button</string>
<string name="donate">Donate</string>
<string name="send_error_reports">Wyślij raport o błędach</string>
<string name="extra_options">Dodatkowe opcje</string>
<string name="split_text_if_too_long">Podziel tekst, jeśli jest zbyt długi</string>
<string name="ignore_back_button">Ignoruj przycisk \"Wstecz\"</string>
<string name="donate">Wesprzyj mnie</string>
<string name="codifica">Kodowanie</string>
<string name="condividi">Udostępnij</string>
<string name="info">Informacje</string>
@ -71,6 +71,6 @@
<string name="open">Otwórz</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="no">No</string>
<string name="new_file">New file</string>
<string name="no">Nie</string>
<string name="new_file">Nowy plik</string>
</resources>

View File

@ -19,8 +19,8 @@
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<resources>
<string name="close">Close</string>
<string name="about_action">About</string>
<string name="close">Zamknij</string>
<string name="about_action">O aplikacji i autorach</string>
<string name="about_message"><![CDATA[
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/>

View File

@ -19,8 +19,8 @@
~ 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_action">Wesprzyj mnie</string>
<string name="donation_title">Wspomóż twórcę</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:

View File

@ -71,6 +71,6 @@
<string name="open">Abrir</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="no">No</string>
<string name="new_file">New file</string>
<string name="no">Não</string>
<string name="new_file">Novo arquivo</string>
</resources>

View File

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

View File

@ -20,18 +20,18 @@
-->
<resources>
<string name="donation_action">Поддержать</string>
<string name="donation_title">Donate to developer</string>
<string name="donation_title">Пожертвовать разработчику</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:
Turbo Editor является бесплатной и <a href="http://github.com/vmihalachi/turbo-editor/">open source</a> программой.
Вы можете выразить свою признательность и поддержку, пожертвовав:
]]></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>
<string name="donation_item_bought">Вы уже пожертвовали.</string>
<string name="donation_2">Мороженое</string>
<string name="donation_4">Чашка кофе</string>
<string name="donation_10">Счета за электричество</string>
<string name="donation_20">Отличная подушка</string>
<string name="donation_50">Твердотельный накопитель</string>
<string name="donation_99">Звуковая система</string>
<string name="donation_error_iab_setup">Не удалось запустить внутреннюю службу биллинга!</string>
<string name="donation_no_responsibility">Имейте в виду, что Google не несет ответственности за данный способ оплаты.</string>
</resources>

View File

@ -1,4 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<!--
~ Copyright (C) 2014 Vlad Mihalachi
~
@ -17,137 +18,59 @@
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<!--Generated by crowdin.com-->
<!--Generated by crowdin.net-->
<resources>
<string name="aggiungi_account">Nový účet</string>
<string name="attiva">Aktívne</string>
<string name="cancella">Vymazať</string>
<string name="cancellazione">Mažem súbory&#8230;</string>
<string name="caricamento">Načítavanie&#8230;</string>
<string name="cartella_locale_corrente">Aktuálna miestna zložka</string>
<string name="chiave_privata">Súkromný kľúč</string>
<string name="chiaro">Svetlá</string>
<string name="use_monospace">Použiť neproporcionálne</string>
<string name="recent_files">Nedávne súbory</string>
<string name="font_size">Veľkosť písma</string>
<string name="connection_name">Názov pripojenia</string>
<string name="line_numbers">Čísla riadkov</string>
<string name="wrap_content">Zalomiť obsah</string>
<string name="view_it_on_the_web">Zobraziť na webe</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="condividi">Zdieľať</string>
<string name="crea_cartella_locale">Nový lokálny súbor</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="info">Informácie</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="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="scuro">Tmavá</string>
<string name="seleziona">Vybrať</string>
<string name="seleziona_account">Vyberte účet</string>
<string name="sicuro">Ste si istý?</string>
<string name="something_failed">Niečo zlyhalo</string>
<string name="skip_same_file">Nepresúvajte rovnaký súbor</string>
<string name="tema_app">Téma</string>
<string name="tipo_connessione">Typ pripojenia</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>
<string name="menu_syntax_highlight">Zvýrazniť syntax</string>
<string name="testo_indietro">Späť</string>
<string name="testo_rifai">Znova</string>
<string name="open">Otvoriť</string>
<string name="file_saved_with_success">Súbor %1$s bol úspešne uložený!</string>
<string name="open_a_file">Otvoriť súbor</string>
<string name="no">Nie</string>
<string name="new_file">Nový súbor</string>
</resources>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<!--
~ Copyright (C) 2014 Vlad Mihalachi
~
@ -19,5 +19,16 @@
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<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>

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

View File

@ -19,16 +19,16 @@
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<resources>
<string name="close">Close</string>
<string name="about_action">About</string>
<string name="close">Stäng</string>
<string name="about_action">Om</string>
<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/>
<br/>
Many thanks to all who
<a href="http://crowdin.net/project/turbo-client">helped with translations</a> or
donated to me.<br/>
Många tack till alla som
<a href="http://crowdin.net/project/turbo-client">hjälpt med översättningar </a> eller
donerat.<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>
</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>
<string name="close">Kapat</string>
<string name="about_action">Hakkında</string>
<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.
<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.
Telif hakkı 2013-2014 <a href="https://plus.google.com/+VladMihalachi">Vlad Mihalachi</a>. Tüm Hakları Saklıdır.<br/>
<br/>
Tüm çevirileriyle
<a href="http://crowdin.net/project/turbo-client">veya bağışlarıyla yardımcı</a> olanlara çok teşekkürler</a>.<br/>
<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/>
<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>
<a href="https://plus.google.com/+VladMihalachi">]]></string>
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>
</resources>

View File

@ -26,8 +26,8 @@
Bağış yaparak gelişimini destekleyebilir ve beğeninizi gösterebilirsiniz:
]]></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_4">Bir fincan kahve</string>
<string name="donation_2">Dondurma</string>
<string name="donation_4">Kahve</string>
<string name="donation_10">Elektrik faturaları</string>
<string name="donation_20">Ortopedik yastık</string>
<string name="donation_50">Solid-state sürücü</string>

View File

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

View File

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<!--
~ Copyright (C) 2014 Vlad Mihalachi
~
@ -18,17 +17,20 @@
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<!--Generated by crowdin.com-->
<resources>
<string name="close">Close</string>
<string name="about_action">About</string>
<string name="close">Закрити</string>
<string name="about_action">Про програму</string>
<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/>
<br/>
Many thanks to all who
<a href="http://crowdin.net/project/turbo-client">helped with translations</a> or
donated to me.<br/>
Велике спасибі всім хто
<a href="http://crowdin.net/project/turbo-client">допомагає з перекладами</a> або
підтримує мене<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>
</resources>

View File

@ -19,19 +19,19 @@
~ 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_action">Пожертвувати</string>
<string name="donation_title">Пожертва розробнику</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:
Turbo Editor це безкоштовна програма з <a href="http://github.com/vmihalachi/turbo-editor/ ">відкритим вихідним кодом</a>.
Ви можете показати вашу вдячність і підтримати проект пожертвами:
]]></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>
<string name="donation_item_bought">Ви вже пожертвували.</string>
<string name="donation_2">Морозиво</string>
<string name="donation_4">Чашка кави</string>
<string name="donation_10">Рахунки за електрику</string>
<string name="donation_20">Хорошу подушку</string>
<string name="donation_50">SSD диск</string>
<string name="donation_99">Аудіо систему</string>
<string name="donation_error_iab_setup">Не вдалося виконати in-app-billing сервіс!</string>
<string name="donation_no_responsibility">Зверніть увагу, що Google не відповідає за цей метод платежу.</string>
</resources>

View File

@ -28,6 +28,8 @@
<item type="id" name="im_info"/>
<item type="id" name="im_button"/>
<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_editor_encoding"/>
<item type="id" name="im_line_numbers"/>
@ -46,6 +48,7 @@
<item type="id" name="im_is_working_folder"/>
<item type="id" name="im_set_as_working_folder"/>
<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_prev_page"/>
<item type="id" name="im_donate"/>
@ -62,6 +65,7 @@
<item type="id" name="text_editor"/>
<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="replace_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="preferenze">Preferences</string>
<string name="salva">Save</string>
<string name="save_as">Save as</string>
<string name="menu_syntax_highlight">Syntax highlight</string>
<string name="testo_indietro">Undo</string>
<string name="testo_rifai">Redo</string>
@ -72,4 +73,6 @@
<string name="open_a_file">Open a file</string>
<string name="no">No</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>